added frontend and script examples

This commit is contained in:
CaffeineFueled 2025-04-15 23:33:44 +02:00
parent 368c4de6fe
commit 61b10a2bc2
6 changed files with 385 additions and 0 deletions

33
frontend/README.md Normal file
View file

@ -0,0 +1,33 @@
# Static2API Frontend
This is a simple frontend that displays data from the Static2API application. It's designed to work with the API without requiring any changes to the container or backend.
## Usage
1. Start the Static2API application either directly or via container:
```
python main.py
```
or
```
./run_container.sh
```
2. Open the `index.html` file in your browser:
- You can use any static file server
- Or simply open the file directly in your browser
3. The frontend will fetch data from the following endpoints:
- `/` - Root endpoint
- `/api/users` - Users data
- `/api/contacts` - Contacts data
## CORS Support
The FastAPI application has been updated with CORS middleware to allow cross-origin requests from this frontend. This means you can:
1. Open the HTML file directly in your browser
2. Access the API endpoints without CORS restrictions
3. Serve the frontend from any static file server
No additional configuration is needed for CORS support.

110
frontend/index.html Normal file
View file

@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Static2API Frontend</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.container {
max-width: 1000px;
margin: 0 auto;
background-color: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
padding: 20px;
}
h1 {
color: #333;
text-align: center;
margin-bottom: 30px;
}
.endpoints {
display: flex;
gap: 20px;
flex-wrap: wrap;
}
.endpoint {
flex: 1;
min-width: 300px;
border: 1px solid #ddd;
border-radius: 6px;
padding: 15px;
}
.endpoint h2 {
margin-top: 0;
color: #2c3e50;
border-bottom: 1px solid #eee;
padding-bottom: 10px;
}
pre {
background-color: #f8f9fa;
padding: 12px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
}
.loading {
text-align: center;
color: #666;
font-style: italic;
}
.example {
margin-top: 40px;
padding: 20px;
background-color: #f0f8ff;
border-radius: 6px;
border-left: 4px solid #4a90e2;
}
.example h2 {
margin-top: 0;
color: #2c3e50;
}
.location-list {
list-style-type: none;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.location-item {
background-color: #e8f4fd;
padding: 8px 15px;
border-radius: 20px;
border: 1px solid #c8e1fb;
font-size: 14px;
}
</style>
</head>
<body>
<div class="container">
<h1>Static2API Frontend</h1>
<div class="endpoints">
<div class="endpoint">
<h2>Root Endpoint</h2>
<div id="root-data" class="loading">Loading...</div>
</div>
<div class="endpoint">
<h2>Users API</h2>
<div id="users-data" class="loading">Loading...</div>
</div>
<div class="endpoint">
<h2>Contacts API</h2>
<div id="contacts-data" class="loading">Loading...</div>
</div>
</div>
<div class="example">
<h2>Example: Locations from Contacts</h2>
<p>This example extracts and displays all unique locations from the contacts data:</p>
<div id="locations-example" class="loading">Loading locations...</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

88
frontend/script.js Normal file
View file

@ -0,0 +1,88 @@
document.addEventListener('DOMContentLoaded', () => {
// Set the base URL for the API
// When running locally without the container, you would use:
const API_BASE_URL = 'http://localhost:8000';
// When accessing the API running in a container, you would use:
// const API_BASE_URL = 'http://localhost:8000';
// Adjust the port if needed according to your container setup
// Function to fetch data from the API and update the UI
async function fetchEndpoint(endpoint, elementId) {
const dataElement = document.getElementById(elementId);
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
// Create a formatted JSON string with syntax highlighting
const formattedJson = JSON.stringify(data, null, 2);
// Update the UI with the fetched data
dataElement.innerHTML = `<pre>${formattedJson}</pre>`;
return data; // Return the data for potential further processing
} catch (error) {
dataElement.innerHTML = `<div class="error">Error: ${error.message}</div>`;
console.error(`Failed to fetch ${endpoint}:`, error);
return null;
}
}
// Fetch data from all endpoints
fetchEndpoint('/', 'root-data');
fetchEndpoint('/api/users', 'users-data');
// Fetch contacts data and then process it to display locations
fetchEndpoint('/api/contacts', 'contacts-data')
.then(contactsData => {
if (contactsData) {
// Process the contacts data to extract unique locations
displayLocationsExample(contactsData);
}
});
// Function to display the locations example
function displayLocationsExample(contactsData) {
const locationsElement = document.getElementById('locations-example');
try {
// Extract all unique locations from the contacts data
const locations = [...new Set(contactsData.map(contact => contact.location))];
if (locations.length === 0) {
locationsElement.innerHTML = '<p>No locations found in the contacts data.</p>';
return;
}
// Create HTML for the locations list
const locationsHTML = `
<p>Found ${locations.length} unique location(s):</p>
<ul class="location-list">
${locations.map(location => `
<li class="location-item">${location}</li>
`).join('')}
</ul>
<p>Code example:</p>
<pre>
// JavaScript to extract unique locations
const locations = [...new Set(
contactsData.map(contact => contact.location)
)];
console.log(locations); // ${JSON.stringify(locations)}
</pre>
`;
locationsElement.innerHTML = locationsHTML;
} catch (error) {
locationsElement.innerHTML = `<div class="error">Error processing locations: ${error.message}</div>`;
console.error('Error processing locations:', error);
}
}
});