mirror of
https://github.com/donpat1to/Schichtenplaner.git
synced 2025-11-30 22:45:46 +01:00
removed unnecessary comments
This commit is contained in:
@@ -64,7 +64,7 @@ export const login = async (req: Request, res: Response) => {
|
|||||||
return res.status(400).json({ error: 'E-Mail und Passwort sind erforderlich' });
|
return res.status(400).json({ error: 'E-Mail und Passwort sind erforderlich' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Get user from database with role from employee_roles table
|
// Get user from database with role from employee_roles table
|
||||||
const user = await db.get<any>(
|
const user = await db.get<any>(
|
||||||
`SELECT
|
`SELECT
|
||||||
e.id, e.email, e.password, e.firstname, e.lastname,
|
e.id, e.email, e.password, e.firstname, e.lastname,
|
||||||
@@ -155,7 +155,7 @@ export const getCurrentUser = async (req: Request, res: Response) => {
|
|||||||
return res.status(401).json({ error: 'Nicht authentifiziert' });
|
return res.status(401).json({ error: 'Nicht authentifiziert' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Get user with role from employee_roles table
|
// Get user with role from employee_roles table
|
||||||
const user = await db.get<any>(
|
const user = await db.get<any>(
|
||||||
`SELECT
|
`SELECT
|
||||||
e.id, e.email, e.firstname, e.lastname,
|
e.id, e.email, e.firstname, e.lastname,
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ export const requireRole = (roles: string[]) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add this function to your existing auth.ts
|
|
||||||
export const getClientIP = (req: Request): string => {
|
export const getClientIP = (req: Request): string => {
|
||||||
const trustedHeader = process.env.TRUSTED_PROXY_HEADER || 'x-forwarded-for';
|
const trustedHeader = process.env.TRUSTED_PROXY_HEADER || 'x-forwarded-for';
|
||||||
const forwarded = req.headers[trustedHeader];
|
const forwarded = req.headers[trustedHeader];
|
||||||
@@ -74,7 +73,6 @@ export const getClientIP = (req: Request): string => {
|
|||||||
return req.socket.remoteAddress || req.ip || 'unknown';
|
return req.socket.remoteAddress || req.ip || 'unknown';
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add IP-based security checks
|
|
||||||
export const ipSecurityCheck = (req: AuthRequest, res: Response, next: NextFunction): void => {
|
export const ipSecurityCheck = (req: AuthRequest, res: Response, next: NextFunction): void => {
|
||||||
const clientIP = getClientIP(req);
|
const clientIP = getClientIP(req);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function generateEmail(firstname: string, lastname: string): string {
|
|||||||
return `${cleanFirstname}.${cleanLastname}@sp.de`;
|
return `${cleanFirstname}.${cleanLastname}@sp.de`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Validation for new employee model with employee types
|
// Validation for new employee model with employee types
|
||||||
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
|
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export function generateEmployeeEmail(firstname: string, lastname: string): stri
|
|||||||
return generateEmail(firstname, lastname);
|
return generateEmail(firstname, lastname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Business logic helpers for new employee types
|
// Business logic helpers for new employee types
|
||||||
export const isManager = (employee: Employee): boolean =>
|
export const isManager = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'manager';
|
employee.employeeType === 'manager';
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ export const isInternal = (employee: Employee): boolean =>
|
|||||||
export const isExternal = (employee: Employee): boolean =>
|
export const isExternal = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'guest';
|
employee.employeeType === 'guest';
|
||||||
|
|
||||||
// UPDATED: Trainee logic - now based on isTrainee field for personell type
|
// Trainee logic - now based on isTrainee field for personell type
|
||||||
export const isTrainee = (employee: Employee): boolean =>
|
export const isTrainee = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'personell' && employee.isTrainee;
|
employee.employeeType === 'personell' && employee.isTrainee;
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ export const isMaintenance = (employee: Employee): boolean =>
|
|||||||
export const isUser = (employee: Employee): boolean =>
|
export const isUser = (employee: Employee): boolean =>
|
||||||
employee.roles?.includes('user') || false;
|
employee.roles?.includes('user') || false;
|
||||||
|
|
||||||
// UPDATED: Work alone permission - managers and experienced personell can work alone
|
// Work alone permission - managers and experienced personell can work alone
|
||||||
export const canEmployeeWorkAlone = (employee: Employee): boolean =>
|
export const canEmployeeWorkAlone = (employee: Employee): boolean =>
|
||||||
employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
|
employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ export function validateAvailabilityData(availability: Omit<EmployeeAvailability
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Helper to get employee type category
|
// Helper to get employee type category
|
||||||
export const getEmployeeCategory = (employee: Employee): 'internal' | 'external' => {
|
export const getEmployeeCategory = (employee: Employee): 'internal' | 'external' => {
|
||||||
return isInternal(employee) ? 'internal' : 'external';
|
return isInternal(employee) ? 'internal' : 'external';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export function calculateTotalRequiredEmployees(plan: ShiftPlan): number {
|
|||||||
return plan.shifts.reduce((total, shift) => total + shift.requiredEmployees, 0);
|
return plan.shifts.reduce((total, shift) => total + shift.requiredEmployees, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Get scheduled shift by date and time slot
|
// Get scheduled shift by date and time slot
|
||||||
export function getScheduledShiftByDateAndTime(
|
export function getScheduledShiftByDateAndTime(
|
||||||
plan: ShiftPlan,
|
plan: ShiftPlan,
|
||||||
date: string,
|
date: string,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Employee } from './Employee.js';
|
import { Employee } from './Employee.js';
|
||||||
import { ShiftPlan } from './ShiftPlan.js';
|
import { ShiftPlan } from './ShiftPlan.js';
|
||||||
|
|
||||||
// Updated Availability interface to match new schema
|
// Availability interface
|
||||||
export interface Availability {
|
export interface Availability {
|
||||||
id: string;
|
id: string;
|
||||||
employeeId: string;
|
employeeId: string;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ async function markMigrationAsApplied(migrationName: string) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Function to handle schema changes for the new employee type system
|
// Function to handle schema changes for the new employee type system
|
||||||
async function applySchemaUpdates() {
|
async function applySchemaUpdates() {
|
||||||
console.log('🔄 Applying schema updates for new employee type system...');
|
console.log('🔄 Applying schema updates for new employee type system...');
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ async function applySchemaUpdates() {
|
|||||||
PRAGMA table_info(employees)
|
PRAGMA table_info(employees)
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// FIXED: Check for employee_type column (not roles column)
|
// Check for employee_type column (not roles column)
|
||||||
const hasEmployeeType = employeesTableInfo.some((col: TableColumnInfo) => col.name === 'employee_type');
|
const hasEmployeeType = employeesTableInfo.some((col: TableColumnInfo) => col.name === 'employee_type');
|
||||||
const hasIsTrainee = employeesTableInfo.some((col: TableColumnInfo) => col.name === 'is_trainee');
|
const hasIsTrainee = employeesTableInfo.some((col: TableColumnInfo) => col.name === 'is_trainee');
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
|
|||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
const response = await fetch(`${API_BASE_URL}/setup/status`, {
|
const response = await fetch(`${API_BASE_URL}/setup/status`, {
|
||||||
signal: AbortSignal.timeout(5000) // 5 second timeout
|
signal: AbortSignal.timeout(5000)
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`✅ Setup status response received in ${Date.now() - startTime}ms`);
|
console.log(`✅ Setup status response received in ${Date.now() - startTime}ms`);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export const AVAILABILITY_PREFERENCES = {
|
|||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
// Default availability for new employees (all shifts unavailable as level 3)
|
// Default availability for new employees (all shifts unavailable as level 3)
|
||||||
// UPDATED: Now uses shiftId instead of timeSlotId + dayOfWeek
|
// Now uses shiftId instead of timeSlotId + dayOfWeek
|
||||||
export function createDefaultAvailabilities(employeeId: string, planId: string, shiftIds: string[]): Omit<EmployeeAvailability, 'id'>[] {
|
export function createDefaultAvailabilities(employeeId: string, planId: string, shiftIds: string[]): Omit<EmployeeAvailability, 'id'>[] {
|
||||||
const availabilities: Omit<EmployeeAvailability, 'id'>[] = [];
|
const availabilities: Omit<EmployeeAvailability, 'id'>[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function generateEmail(firstname: string, lastname: string): string {
|
|||||||
return `${cleanFirstname}.${cleanLastname}@sp.de`;
|
return `${cleanFirstname}.${cleanLastname}@sp.de`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Validation for new employee model with employee types
|
// Validation for new employee model with employee types
|
||||||
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
|
export function validateEmployeeData(employee: CreateEmployeeRequest): string[] {
|
||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ export function generateEmployeeEmail(firstname: string, lastname: string): stri
|
|||||||
return generateEmail(firstname, lastname);
|
return generateEmail(firstname, lastname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Business logic helpers for new employee types
|
// Business logic helpers for new employee types
|
||||||
export const isManager = (employee: Employee): boolean =>
|
export const isManager = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'manager';
|
employee.employeeType === 'manager';
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ export const isInternal = (employee: Employee): boolean =>
|
|||||||
export const isExternal = (employee: Employee): boolean =>
|
export const isExternal = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'guest';
|
employee.employeeType === 'guest';
|
||||||
|
|
||||||
// UPDATED: Trainee logic - now based on isTrainee field for personell type
|
// Trainee logic - now based on isTrainee field for personell type
|
||||||
export const isTrainee = (employee: Employee): boolean =>
|
export const isTrainee = (employee: Employee): boolean =>
|
||||||
employee.employeeType === 'personell' && employee.isTrainee;
|
employee.employeeType === 'personell' && employee.isTrainee;
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ export const isMaintenance = (employee: Employee): boolean =>
|
|||||||
export const isUser = (employee: Employee): boolean =>
|
export const isUser = (employee: Employee): boolean =>
|
||||||
employee.roles?.includes('user') || false;
|
employee.roles?.includes('user') || false;
|
||||||
|
|
||||||
// UPDATED: Work alone permission - managers and experienced personell can work alone
|
// Work alone permission - managers and experienced personell can work alone
|
||||||
export const canEmployeeWorkAlone = (employee: Employee): boolean =>
|
export const canEmployeeWorkAlone = (employee: Employee): boolean =>
|
||||||
employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
|
employee.canWorkAlone && (isManager(employee) || isExperienced(employee));
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ export function validateAvailabilityData(availability: Omit<EmployeeAvailability
|
|||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Helper to get employee type category
|
// Helper to get employee type category
|
||||||
export const getEmployeeCategory = (employee: Employee): 'internal' | 'external' => {
|
export const getEmployeeCategory = (employee: Employee): 'internal' | 'external' => {
|
||||||
return isInternal(employee) ? 'internal' : 'external';
|
return isInternal(employee) ? 'internal' : 'external';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export function calculateTotalRequiredEmployees(plan: ShiftPlan): number {
|
|||||||
return plan.shifts.reduce((total, shift) => total + shift.requiredEmployees, 0);
|
return plan.shifts.reduce((total, shift) => total + shift.requiredEmployees, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATED: Get scheduled shift by date and time slot
|
// Get scheduled shift by date and time slot
|
||||||
export function getScheduledShiftByDateAndTime(
|
export function getScheduledShiftByDateAndTime(
|
||||||
plan: ShiftPlan,
|
plan: ShiftPlan,
|
||||||
date: string,
|
date: string,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Employee } from './Employee.js';
|
import { Employee } from './Employee.js';
|
||||||
import { ShiftPlan } from './ShiftPlan.js';
|
import { ShiftPlan } from './ShiftPlan.js';
|
||||||
|
|
||||||
// Updated Availability interface to match new schema
|
// Availability interface to match
|
||||||
export interface Availability {
|
export interface Availability {
|
||||||
id: string;
|
id: string;
|
||||||
employeeId: string;
|
employeeId: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// frontend/src/pages/Auth/Login.tsx - UPDATED PASSWORD SECTION
|
// frontend/src/pages/Auth/Login.tsx
|
||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface EmployeeListProps {
|
|||||||
type SortField = 'name' | 'employeeType' | 'canWorkAlone' | 'role' | 'lastLogin';
|
type SortField = 'name' | 'employeeType' | 'canWorkAlone' | 'role' | 'lastLogin';
|
||||||
type SortDirection = 'asc' | 'desc';
|
type SortDirection = 'asc' | 'desc';
|
||||||
|
|
||||||
// FIXED: Use the actual employee types from the Employee interface
|
// Use the actual employee types from the Employee interface
|
||||||
type EmployeeType = 'manager' | 'personell' | 'apprentice' | 'guest';
|
type EmployeeType = 'manager' | 'personell' | 'apprentice' | 'guest';
|
||||||
|
|
||||||
const EmployeeList: React.FC<EmployeeListProps> = ({
|
const EmployeeList: React.FC<EmployeeListProps> = ({
|
||||||
@@ -130,7 +130,7 @@ const EmployeeList: React.FC<EmployeeListProps> = ({
|
|||||||
const getEmployeeTypeBadge = (type: EmployeeType, isTrainee: boolean = false) => {
|
const getEmployeeTypeBadge = (type: EmployeeType, isTrainee: boolean = false) => {
|
||||||
const config = EMPLOYEE_TYPE_CONFIG[type];
|
const config = EMPLOYEE_TYPE_CONFIG[type];
|
||||||
|
|
||||||
// FIXED: Updated color mapping for actual employee types
|
// Color mapping for actual employee types
|
||||||
const bgColor =
|
const bgColor =
|
||||||
type === 'manager'
|
type === 'manager'
|
||||||
? '#fadbd8' // light red
|
? '#fadbd8' // light red
|
||||||
@@ -326,7 +326,7 @@ const EmployeeList: React.FC<EmployeeListProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{sortedEmployees.map(employee => {
|
{sortedEmployees.map(employee => {
|
||||||
// FIXED: Type assertion to ensure type safety
|
// Type assertion to ensure type safety
|
||||||
const employeeType = getEmployeeTypeBadge(employee.employeeType as EmployeeType, employee.isTrainee);
|
const employeeType = getEmployeeTypeBadge(employee.employeeType as EmployeeType, employee.isTrainee);
|
||||||
const independence = getIndependenceBadge(employee.canWorkAlone);
|
const independence = getIndependenceBadge(employee.canWorkAlone);
|
||||||
const roleInfo = getRoleBadge(employee.roles);
|
const roleInfo = getRoleBadge(employee.roles);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// frontend/src/pages/ShiftPlans/ShiftPlanView.tsx - UPDATED
|
// frontend/src/pages/ShiftPlans/ShiftPlanView.tsx
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { useAuth } from '../../contexts/AuthContext';
|
import { useAuth } from '../../contexts/AuthContext';
|
||||||
@@ -1118,7 +1118,7 @@ const ShiftPlanView: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Assignment Preview Modal - FIXED CONDITION */}
|
{/* Assignment Preview Modal */}
|
||||||
{(showAssignmentPreview || assignmentResult) && (
|
{(showAssignmentPreview || assignmentResult) && (
|
||||||
<div style={{
|
<div style={{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
|
|||||||
Reference in New Issue
Block a user