Compare commits

...

5 Commits

7 changed files with 61 additions and 21 deletions

View File

@@ -3,6 +3,7 @@ import express from 'express';
import path from 'path'; import path from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { initializeDatabase } from './scripts/initializeDatabase.js'; import { initializeDatabase } from './scripts/initializeDatabase.js';
import fs from 'fs';
// Route imports // Route imports
import authRoutes from './routes/auth.js'; import authRoutes from './routes/auth.js';
@@ -39,11 +40,50 @@ app.get('/api/health', (req: any, res: any) => {
}); });
// 🆕 STATIC FILE SERVING FÜR FRONTEND // 🆕 STATIC FILE SERVING FÜR FRONTEND
app.use(express.static(path.join(__dirname, '../../frontend-build'))); const frontendBuildPath = path.join(__dirname, '../frontend-build');
console.log('📁 Frontend build path:', frontendBuildPath);
// Überprüfe ob das Verzeichnis existiert
if (fs.existsSync(frontendBuildPath)) {
console.log('✅ Frontend build directory exists');
const files = fs.readdirSync(frontendBuildPath);
console.log('📄 Files in frontend-build:', files);
// Serviere statische Dateien
app.use(express.static(frontendBuildPath));
console.log('✅ Static file serving configured');
} else {
console.log('❌ Frontend build directory NOT FOUND:', frontendBuildPath);
}
app.get('/', (req, res) => {
const indexPath = path.join(frontendBuildPath, 'index.html');
console.log('📄 Serving index.html from:', indexPath);
if (fs.existsSync(indexPath)) {
res.sendFile(indexPath);
} else {
console.error('❌ index.html not found at:', indexPath);
res.status(404).send('Frontend not found - index.html missing');
}
});
// 🆕 FALLBACK FÜR CLIENT-SIDE ROUTING
app.get('*', (req, res) => { app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../../frontend-build/index.html')); // Ignoriere API Routes
if (req.path.startsWith('/api/')) {
return res.status(404).json({ error: 'API endpoint not found' });
}
const indexPath = path.join(frontendBuildPath, 'index.html');
console.log('🔄 Client-side routing for:', req.path, '-> index.html');
if (fs.existsSync(indexPath)) {
res.sendFile(indexPath);
} else {
console.error('❌ index.html not found for client-side routing');
res.status(404).json({ error: 'Frontend application not found' });
}
}); });
// Error handling middleware // Error handling middleware

View File

@@ -20,7 +20,7 @@ interface AuthContextType {
} }
const AuthContext = createContext<AuthContextType | undefined>(undefined); const AuthContext = createContext<AuthContextType | undefined>(undefined);
const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || 'http://localhost:3002/api'; const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || '/api';
interface AuthProviderProps { interface AuthProviderProps {
children: ReactNode; children: ReactNode;

View File

@@ -2,6 +2,8 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useAuth } from '../../contexts/AuthContext'; import { useAuth } from '../../contexts/AuthContext';
const API_BASE_URL = '/api';
const Setup: React.FC = () => { const Setup: React.FC = () => {
const [step, setStep] = useState(1); const [step, setStep] = useState(1);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
@@ -73,7 +75,7 @@ const Setup: React.FC = () => {
console.log('🚀 Sending setup request...', payload); console.log('🚀 Sending setup request...', payload);
const response = await fetch('http://localhost:3002/api/setup/admin', { const response = await fetch(`${API_BASE_URL}/setup/admin`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',

View File

@@ -1,6 +1,6 @@
// frontend/src/services/authService.ts // frontend/src/services/authService.ts
import { Employee } from '../models/Employee'; import { Employee } from '../models/Employee';
const API_BASE = process.env.REACT_APP_API_BASE_URL || 'http://localhost:3002/api'; const API_BASE = process.env.REACT_APP_API_BASE_URL || '/api';
export interface LoginRequest { export interface LoginRequest {
email: string; email: string;

View File

@@ -1,7 +1,7 @@
// frontend/src/services/employeeService.ts // frontend/src/services/employeeService.ts
import { Employee, CreateEmployeeRequest, UpdateEmployeeRequest, EmployeeAvailability } from '../models/Employee'; import { Employee, CreateEmployeeRequest, UpdateEmployeeRequest, EmployeeAvailability } from '../models/Employee';
const API_BASE_URL = 'http://localhost:3002/api'; const API_BASE_URL = '/api';
const getAuthHeaders = () => { const getAuthHeaders = () => {
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');

View File

@@ -4,9 +4,7 @@ import { Employee, EmployeeAvailability } from '../models/Employee';
import { authService } from './authService'; import { authService } from './authService';
import { AssignmentResult, ScheduleRequest } from '../models/scheduling'; import { AssignmentResult, ScheduleRequest } from '../models/scheduling';
const API_BASE_URL = 'http://localhost:3002/api'; const API_BASE_URL = '/api';
// Helper function to get auth headers // Helper function to get auth headers
const getAuthHeaders = () => { const getAuthHeaders = () => {

View File

@@ -3,7 +3,7 @@ import { authService } from './authService';
import { ShiftPlan, CreateShiftPlanRequest, ScheduledShift, CreateShiftFromTemplateRequest } from '../models/ShiftPlan'; import { ShiftPlan, CreateShiftPlanRequest, ScheduledShift, CreateShiftFromTemplateRequest } from '../models/ShiftPlan';
import { TEMPLATE_PRESETS } from '../models/defaults/shiftPlanDefaults'; import { TEMPLATE_PRESETS } from '../models/defaults/shiftPlanDefaults';
const API_BASE = 'http://localhost:3002/api/shift-plans'; const API_BASE_URL = '/api/shift-plans';
// Helper function to get auth headers // Helper function to get auth headers
const getAuthHeaders = () => { const getAuthHeaders = () => {
@@ -25,7 +25,7 @@ const handleResponse = async (response: Response) => {
export const shiftPlanService = { export const shiftPlanService = {
async getShiftPlans(): Promise<ShiftPlan[]> { async getShiftPlans(): Promise<ShiftPlan[]> {
const response = await fetch(API_BASE, { const response = await fetch(API_BASE_URL, {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...authService.getAuthHeaders() ...authService.getAuthHeaders()
@@ -50,7 +50,7 @@ export const shiftPlanService = {
}, },
async getShiftPlan(id: string): Promise<ShiftPlan> { async getShiftPlan(id: string): Promise<ShiftPlan> {
const response = await fetch(`${API_BASE}/${id}`, { const response = await fetch(`${API_BASE_URL}/${id}`, {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...authService.getAuthHeaders() ...authService.getAuthHeaders()
@@ -69,7 +69,7 @@ export const shiftPlanService = {
}, },
async createShiftPlan(plan: CreateShiftPlanRequest): Promise<ShiftPlan> { async createShiftPlan(plan: CreateShiftPlanRequest): Promise<ShiftPlan> {
const response = await fetch(API_BASE, { const response = await fetch(API_BASE_URL, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -90,7 +90,7 @@ export const shiftPlanService = {
}, },
async updateShiftPlan(id: string, plan: Partial<ShiftPlan>): Promise<ShiftPlan> { async updateShiftPlan(id: string, plan: Partial<ShiftPlan>): Promise<ShiftPlan> {
const response = await fetch(`${API_BASE}/${id}`, { const response = await fetch(`${API_BASE_URL}/${id}`, {
method: 'PUT', method: 'PUT',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -111,7 +111,7 @@ export const shiftPlanService = {
}, },
async deleteShiftPlan(id: string): Promise<void> { async deleteShiftPlan(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}`, { const response = await fetch(`${API_BASE_URL}/${id}`, {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -130,7 +130,7 @@ export const shiftPlanService = {
// Get specific template or plan // Get specific template or plan
getTemplate: async (id: string): Promise<ShiftPlan> => { getTemplate: async (id: string): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}/${id}`, { const response = await fetch(`${API_BASE_URL}/${id}`, {
headers: getAuthHeaders() headers: getAuthHeaders()
}); });
return handleResponse(response); return handleResponse(response);
@@ -142,7 +142,7 @@ export const shiftPlanService = {
console.log('🔄 Attempting to regenerate scheduled shifts...'); console.log('🔄 Attempting to regenerate scheduled shifts...');
// You'll need to add this API endpoint to your backend // You'll need to add this API endpoint to your backend
const response = await fetch(`${API_BASE}/${planId}/regenerate-shifts`, { const response = await fetch(`${API_BASE_URL}/${planId}/regenerate-shifts`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -162,7 +162,7 @@ export const shiftPlanService = {
// Create new plan // Create new plan
createPlan: async (data: CreateShiftPlanRequest): Promise<ShiftPlan> => { createPlan: async (data: CreateShiftPlanRequest): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}`, { const response = await fetch(`${API_BASE_URL}`, {
method: 'POST', method: 'POST',
headers: getAuthHeaders(), headers: getAuthHeaders(),
body: JSON.stringify(data), body: JSON.stringify(data),
@@ -177,7 +177,7 @@ export const shiftPlanService = {
endDate: string; endDate: string;
isTemplate?: boolean; isTemplate?: boolean;
}): Promise<ShiftPlan> => { }): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}/from-preset`, { const response = await fetch(`${API_BASE_URL}/from-preset`, {
method: 'POST', method: 'POST',
headers: getAuthHeaders(), headers: getAuthHeaders(),
body: JSON.stringify(data), body: JSON.stringify(data),
@@ -204,7 +204,7 @@ export const shiftPlanService = {
try { try {
console.log('🔄 Clearing assignments for plan:', planId); console.log('🔄 Clearing assignments for plan:', planId);
const response = await fetch(`${API_BASE}/${planId}/clear-assignments`, { const response = await fetch(`${API_BASE_URL}/${planId}/clear-assignments`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',