feat: add fullstack TypeScript template with Docker support
- Created package.json for managing workspaces (frontend and backend) - Added scripts for development, build, testing, and Docker operations - Implemented kill-dev-processes.sh script to terminate development processes gracefully
This commit is contained in:
98
frontend/src/App.tsx
Normal file
98
frontend/src/App.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import './App.css';
|
||||
|
||||
interface Photo {
|
||||
id: number;
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface HealthStatus {
|
||||
status: string;
|
||||
message: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
function App() {
|
||||
const [photos, setPhotos] = useState<Photo[]>([]);
|
||||
const [health, setHealth] = useState<HealthStatus | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:3001';
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// Health Check
|
||||
const healthResponse = await fetch(`${API_BASE_URL}/api/health`);
|
||||
const healthData = await healthResponse.json();
|
||||
setHealth(healthData);
|
||||
|
||||
// Photos
|
||||
const photosResponse = await fetch(`${API_BASE_URL}/api/photos`);
|
||||
const photosData = await photosResponse.json();
|
||||
setPhotos(photosData.photos);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden der Daten:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, [API_BASE_URL]);
|
||||
|
||||
const handlePrint = async (photoId: number) => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/print`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ photoId, copies: 1 }),
|
||||
});
|
||||
const data = await response.json();
|
||||
alert(`Druckauftrag erstellt: ${data.message}`);
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Drucken:', error);
|
||||
alert('Fehler beim Erstellen des Druckauftrags');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<h1>📸 Fotodrucker</h1>
|
||||
|
||||
{health && (
|
||||
<div className="health-status">
|
||||
<p>Backend Status: <span className="status-ok">{health.status}</span></p>
|
||||
<small>Letzte Aktualisierung: {new Date(health.timestamp).toLocaleString()}</small>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{loading ? (
|
||||
<p>Lade Fotos...</p>
|
||||
) : (
|
||||
<div className="photos-grid">
|
||||
<h2>Verfügbare Fotos</h2>
|
||||
{photos.map((photo) => (
|
||||
<div key={photo.id} className="photo-card">
|
||||
<h3>{photo.name}</h3>
|
||||
<p>URL: {photo.url}</p>
|
||||
<button
|
||||
className="print-button"
|
||||
onClick={() => handlePrint(photo.id)}
|
||||
>
|
||||
🖨️ Drucken
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
Reference in New Issue
Block a user