diff --git a/backend/package.json b/backend/package.json index 2509e07..3b64a3e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -3,18 +3,18 @@ "version": "1.0.0", "type": "commonjs", "scripts": { - "dev": "ts-node src/server.ts", + "dev": "node -r ts-node/register src/server.ts", + "simple": "node src/server.ts", "build": "tsc", - "start": "node dist/server.js", - "test": "echo \"Error: no test specified\" && exit 1" + "start": "node dist/server.js" }, "dependencies": { "express": "^4.18.2", "cors": "^2.8.5", "sqlite3": "^5.1.6", - "uuid": "^9.0.0", "jsonwebtoken": "^9.0.2", - "bcryptjs": "^2.4.3" + "bcryptjs": "^2.4.3", + "uuid": "^9.0.0" }, "devDependencies": { "@types/express": "^4.17.17", diff --git a/backend/src/server.ts b/backend/src/server.ts index de1ef38..34753bb 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -1,44 +1,74 @@ -// backend/src/server.ts -import express from 'express'; -import cors from 'cors'; -import { db } from './services/databaseService.js'; -import { seedData } from './scripts/seedData.js'; -import authRoutes from './routes/auth.js'; -import shiftTemplateRoutes from './routes/shiftTemplates.js'; -import shiftPlanRoutes from './routes/shiftPlans.js'; +const express = require('express'); +const cors = require('cors'); +const sqlite3 = require('sqlite3').verbose(); +const path = require('path'); const app = express(); -const PORT = process.env.PORT || 3001; +const PORT = process.env.PORT || 3002; // Middleware app.use(cors()); app.use(express.json()); -// Routes -app.use('/api/auth', authRoutes); -app.use('/api/shift-templates', shiftTemplateRoutes); -app.use('/api/shift-plans', shiftPlanRoutes); - -// Health check -app.get('/api/health', (req, res) => { - res.json({ status: 'OK', timestamp: new Date().toISOString() }); +// Health route +app.get('/api/health', (req: any, res: any) => { + console.log('βœ… Health check called'); + res.json({ + status: 'OK', + message: 'Backend lΓ€uft!', + timestamp: new Date().toISOString() + }); }); -// Error handling -app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => { - console.error('Unhandled error:', err); - res.status(500).json({ error: 'Internal server error' }); +// Simple login without bcrypt +app.post('/api/auth/login', (req: any, res: any) => { + console.log('πŸ” Login attempt:', req.body.email); + + // Einfache Hardcoded Auth (OHNE Passwort-Hashing fΓΌr Test) + if (req.body.email === 'admin@schichtplan.de' && req.body.password === 'admin123') { + console.log('βœ… Login successful'); + res.json({ + user: { + id: '1', + email: 'admin@schichtplan.de', + name: 'Admin User', + role: 'admin', + createdAt: new Date().toISOString() + }, + token: 'simple-jwt-token-' + Date.now(), + expiresIn: '7d' + }); + } else { + console.log('❌ Login failed'); + res.status(401).json({ error: 'Invalid credentials' }); + } +}); + +// Get shift templates +app.get('/api/shift-templates', (req: any, res: any) => { + console.log('πŸ“‹ Fetching shift templates'); + res.json([ + { + id: '1', + name: 'Standard Woche', + description: 'Standard Schichtplan', + isDefault: true, + createdBy: '1', + createdAt: new Date().toISOString(), + shifts: [ + { id: '1', dayOfWeek: 1, name: 'Vormittag', startTime: '08:00', endTime: '12:00', requiredEmployees: 2 }, + { id: '2', dayOfWeek: 1, name: 'Nachmittag', startTime: '11:30', endTime: '15:30', requiredEmployees: 2 } + ] + } + ]); }); // Start server -app.listen(PORT, async () => { - console.log(`Server running on port ${PORT}`); - await seedData(); +app.listen(PORT, () => { + console.log('πŸŽ‰ BACKEND STARTED SUCCESSFULLY!'); + console.log(`πŸ“ Port: ${PORT}`); + console.log(`πŸ“ Health: http://localhost:${PORT}/api/health`); + console.log(`πŸ“ Ready for login!`); }); -// Graceful shutdown -process.on('SIGINT', async () => { - console.log('Shutting down gracefully...'); - await db.close(); - process.exit(0); -}); \ No newline at end of file +console.log('πŸš€ Server starting...'); \ No newline at end of file diff --git a/frontend/src/contexts/AuthContext.tsx b/frontend/src/contexts/AuthContext.tsx index 54737fe..858ec2c 100644 --- a/frontend/src/contexts/AuthContext.tsx +++ b/frontend/src/contexts/AuthContext.tsx @@ -18,19 +18,25 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children const [loading, setLoading] = useState(true); useEffect(() => { - // Beim Start User aus localStorage laden - const savedUser = authService.getCurrentUser(); - if (savedUser) { - setUser(savedUser); - } - setLoading(false); + // User aus localStorage laden beim Start + const initAuth = async () => { + const savedUser = authService.getCurrentUser(); + if (savedUser) { + setUser(savedUser); + } + setLoading(false); + }; + + initAuth(); }, []); const login = async (credentials: LoginRequest) => { try { const response = await authService.login(credentials); - setUser(response.user); + setUser(response.user); // ← WICHTIG: User State updaten! + console.log('AuthContext: User nach Login gesetzt', response.user); } catch (error) { + console.error('AuthContext: Login fehlgeschlagen', error); throw error; } }; @@ -39,7 +45,9 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children try { const response = await authService.register(userData); setUser(response.user); + console.log('AuthContext: User nach Registrierung gesetzt', response.user); } catch (error) { + console.error('AuthContext: Registrierung fehlgeschlagen', error); throw error; } }; @@ -47,14 +55,24 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children const logout = () => { authService.logout(); setUser(null); + console.log('AuthContext: User nach Logout entfernt'); }; const hasRole = (roles: string[]) => { return user ? roles.includes(user.role) : false; }; + const value = { + user, + login, + register, + logout, + hasRole, + loading + }; + return ( - + {children} ); diff --git a/frontend/src/pages/Auth/Login.tsx b/frontend/src/pages/Auth/Login.tsx index f6e7ef9..5611023 100644 --- a/frontend/src/pages/Auth/Login.tsx +++ b/frontend/src/pages/Auth/Login.tsx @@ -1,16 +1,16 @@ // frontend/src/pages/Auth/Login.tsx import React, { useState } from 'react'; import { useAuth } from '../../contexts/AuthContext'; -import { useNavigate } from 'react-router-dom'; const Login: React.FC = () => { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); + const [email, setEmail] = useState('admin@schichtplan.de'); + const [password, setPassword] = useState('admin123'); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); - const { login, user } = useAuth(); - const navigate = useNavigate(); + const { login } = useAuth(); + + console.log('Login Komponente - State:', { email, password, error, loading }); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -18,11 +18,11 @@ const Login: React.FC = () => { setLoading(true); try { - console.log('Versuche Login...'); + console.log('Login startet mit:', { email }); await login({ email, password }); - console.log('Login erfolgreich!', 'User:', user); - console.log('Navigiere zu /'); - navigate('/', { replace: true }); + console.log('Login erfolgreich abgeschlossen'); + // Force refresh als Fallback + window.location.reload(); } catch (err: any) { console.error('Login Fehler:', err); setError(err.message || 'Login fehlgeschlagen'); @@ -37,9 +37,10 @@ const Login: React.FC = () => { margin: '100px auto', padding: '20px', border: '1px solid #ddd', - borderRadius: '8px' + borderRadius: '8px', + backgroundColor: '#f9f9f9' }}> -

Anmelden

+

Anmelden

{error && (
{ backgroundColor: '#ffe6e6', padding: '10px', borderRadius: '4px', - marginBottom: '15px' + marginBottom: '15px', + border: '1px solid #ffcccc' }}> - {error} + Fehler: {error}
)}
-
-
-