Compare commits

..

4 Commits

7 changed files with 64 additions and 19 deletions

View File

@@ -3,6 +3,7 @@ import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import { initializeDatabase } from './scripts/initializeDatabase.js';
import fs from 'fs';
// Route imports
import authRoutes from './routes/auth.js';
@@ -39,7 +40,51 @@ app.get('/api/health', (req: any, res: any) => {
});
// 🆕 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');
}
});
app.get('*', (req, res) => {
// 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
app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {

View File

@@ -20,7 +20,7 @@ interface AuthContextType {
}
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 {
children: ReactNode;

View File

@@ -2,6 +2,8 @@
import React, { useState } from 'react';
import { useAuth } from '../../contexts/AuthContext';
const API_BASE_URL = '/api';
const Setup: React.FC = () => {
const [step, setStep] = useState(1);
const [formData, setFormData] = useState({
@@ -73,7 +75,7 @@ const Setup: React.FC = () => {
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',
headers: {
'Content-Type': 'application/json',

View File

@@ -1,6 +1,6 @@
// frontend/src/services/authService.ts
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 {
email: string;

View File

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

View File

@@ -4,9 +4,7 @@ import { Employee, EmployeeAvailability } from '../models/Employee';
import { authService } from './authService';
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
const getAuthHeaders = () => {

View File

@@ -3,7 +3,7 @@ import { authService } from './authService';
import { ShiftPlan, CreateShiftPlanRequest, ScheduledShift, CreateShiftFromTemplateRequest } from '../models/ShiftPlan';
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
const getAuthHeaders = () => {
@@ -25,7 +25,7 @@ const handleResponse = async (response: Response) => {
export const shiftPlanService = {
async getShiftPlans(): Promise<ShiftPlan[]> {
const response = await fetch(API_BASE, {
const response = await fetch(API_BASE_URL, {
headers: {
'Content-Type': 'application/json',
...authService.getAuthHeaders()
@@ -50,7 +50,7 @@ export const shiftPlanService = {
},
async getShiftPlan(id: string): Promise<ShiftPlan> {
const response = await fetch(`${API_BASE}/${id}`, {
const response = await fetch(`${API_BASE_URL}/${id}`, {
headers: {
'Content-Type': 'application/json',
...authService.getAuthHeaders()
@@ -69,7 +69,7 @@ export const shiftPlanService = {
},
async createShiftPlan(plan: CreateShiftPlanRequest): Promise<ShiftPlan> {
const response = await fetch(API_BASE, {
const response = await fetch(API_BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -90,7 +90,7 @@ export const shiftPlanService = {
},
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',
headers: {
'Content-Type': 'application/json',
@@ -111,7 +111,7 @@ export const shiftPlanService = {
},
async deleteShiftPlan(id: string): Promise<void> {
const response = await fetch(`${API_BASE}/${id}`, {
const response = await fetch(`${API_BASE_URL}/${id}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
@@ -130,7 +130,7 @@ export const shiftPlanService = {
// Get specific template or plan
getTemplate: async (id: string): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}/${id}`, {
const response = await fetch(`${API_BASE_URL}/${id}`, {
headers: getAuthHeaders()
});
return handleResponse(response);
@@ -142,7 +142,7 @@ export const shiftPlanService = {
console.log('🔄 Attempting to regenerate scheduled shifts...');
// 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',
headers: {
'Content-Type': 'application/json',
@@ -162,7 +162,7 @@ export const shiftPlanService = {
// Create new plan
createPlan: async (data: CreateShiftPlanRequest): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}`, {
const response = await fetch(`${API_BASE_URL}`, {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify(data),
@@ -177,7 +177,7 @@ export const shiftPlanService = {
endDate: string;
isTemplate?: boolean;
}): Promise<ShiftPlan> => {
const response = await fetch(`${API_BASE}/from-preset`, {
const response = await fetch(`${API_BASE_URL}/from-preset`, {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify(data),
@@ -204,7 +204,7 @@ export const shiftPlanService = {
try {
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',
headers: {
'Content-Type': 'application/json',