feat: Add API integration with Fetch & JSONPlaceholder on team page
This commit is contained in:
parent
69795a2912
commit
c4fb202935
2 changed files with 240 additions and 0 deletions
82
js/api-users.js
Normal file
82
js/api-users.js
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
// ====================== API INTEGRATION ======================
|
||||||
|
// Fetch & Display Users from JSONPlaceholder API
|
||||||
|
|
||||||
|
const API_URL = 'https://jsonplaceholder.typicode.com/users';
|
||||||
|
const apiContainer = document.getElementById('apiUsersContainer');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches users from JSONPlaceholder API
|
||||||
|
* Parses response as JSON and renders to DOM
|
||||||
|
* Includes error handling with catch()
|
||||||
|
*/
|
||||||
|
function fetchAndDisplayUsers() {
|
||||||
|
if (!apiContainer) {
|
||||||
|
console.log('API container not found on this page');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
apiContainer.innerHTML = '<p class="loading">Daten werden geladen...</p>';
|
||||||
|
|
||||||
|
fetch(API_URL)
|
||||||
|
.then(response => {
|
||||||
|
console.log('Response Status:', response.status);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Fetched Users Data:', data);
|
||||||
|
|
||||||
|
// Clear container
|
||||||
|
apiContainer.innerHTML = '';
|
||||||
|
|
||||||
|
// Create list of users using createElement
|
||||||
|
const userList = document.createElement('ul');
|
||||||
|
userList.className = 'api-users-list';
|
||||||
|
|
||||||
|
data.forEach(user => {
|
||||||
|
const listItem = document.createElement('li');
|
||||||
|
listItem.className = 'api-user-item';
|
||||||
|
|
||||||
|
// Create user card with detailed information
|
||||||
|
const userCard = document.createElement('div');
|
||||||
|
userCard.className = 'api-user-card';
|
||||||
|
|
||||||
|
userCard.innerHTML = `
|
||||||
|
<div class="api-user-header">
|
||||||
|
<h3 class="api-user-name">${user.name}</h3>
|
||||||
|
<span class="api-user-id">ID: ${user.id}</span>
|
||||||
|
</div>
|
||||||
|
<div class="api-user-details">
|
||||||
|
<p><strong>Username:</strong> ${user.username}</p>
|
||||||
|
<p><strong>Email:</strong> <a href="mailto:${user.email}">${user.email}</a></p>
|
||||||
|
<p><strong>Telefon:</strong> ${user.phone}</p>
|
||||||
|
<p><strong>Website:</strong> <a href="https://${user.website}" target="_blank">${user.website}</a></p>
|
||||||
|
<p><strong>Firma:</strong> ${user.company.name}</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
listItem.appendChild(userCard);
|
||||||
|
userList.appendChild(listItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
apiContainer.appendChild(userList);
|
||||||
|
console.log(`Successfully loaded and displayed ${data.length} users`);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching users:', error);
|
||||||
|
apiContainer.innerHTML = `
|
||||||
|
<div class="error-message">
|
||||||
|
<h3>⚠️ Fehler beim Laden der Daten</h3>
|
||||||
|
<p>${error.message}</p>
|
||||||
|
<p>Bitte versuchen Sie es später erneut oder kontaktieren Sie den Administrator.</p>
|
||||||
|
<button onclick="fetchAndDisplayUsers()" class="retry-btn">Erneut versuchen</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute on page load
|
||||||
|
document.addEventListener('DOMContentLoaded', fetchAndDisplayUsers);
|
||||||
158
team.html
158
team.html
|
|
@ -137,6 +137,153 @@
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* API Integration Styles */
|
||||||
|
.api-section {
|
||||||
|
background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
|
||||||
|
border-top: 2px solid rgba(102, 126, 234, 0.2);
|
||||||
|
border-bottom: 2px solid rgba(102, 126, 234, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-container {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-users-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-item {
|
||||||
|
animation: fadeIn 0.5s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border: 2px solid #e2e8f0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-card:hover {
|
||||||
|
border-color: #667eea;
|
||||||
|
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.15);
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 2px solid #f1f5f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-name {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1e293b;
|
||||||
|
margin: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-id {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 0.3rem 0.8rem;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-details {
|
||||||
|
color: #475569;
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-details p {
|
||||||
|
margin: 0.7rem 0;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-details strong {
|
||||||
|
color: #667eea;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-details a {
|
||||||
|
color: #667eea;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid #667eea;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api-user-details a:hover {
|
||||||
|
color: #764ba2;
|
||||||
|
border-bottom-color: #764ba2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 2rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #667eea;
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0.5; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
background: #fee2e2;
|
||||||
|
border: 2px solid #fca5a5;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
color: #991b1b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #dc2626;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn {
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 0.8rem 1.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retry-btn:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
@ -209,6 +356,16 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- API Integration Section -->
|
||||||
|
<section class="team-section api-section">
|
||||||
|
<h2 class="team-title">📡 API Integration Demo</h2>
|
||||||
|
<p class="team-intro">Hier demonstrieren wir die Integration einer öffentlichen API mit Fetch & JavaScript. Die Daten werden dynamisch von JSONPlaceholder geladen und im DOM gerendert.</p>
|
||||||
|
|
||||||
|
<div id="apiUsersContainer" class="api-container">
|
||||||
|
<!-- API data will be rendered here -->
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
|
@ -233,6 +390,7 @@
|
||||||
|
|
||||||
<script src="js/navbar.js"></script>
|
<script src="js/navbar.js"></script>
|
||||||
<script src="js/script.js"></script>
|
<script src="js/script.js"></script>
|
||||||
|
<script src="js/api-users.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue