mirror of
https://github.com/donpat1to/Schichtenplaner.git
synced 2025-12-01 06:55:45 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f5aa376e31 | |||
| e82e584f76 | |||
| e177c3d2a6 | |||
| de23ea00ee | |||
| d78ba474d8 |
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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 = () => {
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user