added frontend and script examples
This commit is contained in:
parent
368c4de6fe
commit
61b10a2bc2
6 changed files with 385 additions and 0 deletions
33
frontend/README.md
Normal file
33
frontend/README.md
Normal 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
110
frontend/index.html
Normal 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
88
frontend/script.js
Normal 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);
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue