new features

This commit is contained in:
Matthias Hochmeister
2026-03-23 14:08:01 +01:00
parent 3326156b15
commit 1d011ec2df
6 changed files with 22 additions and 27 deletions

View File

@@ -364,7 +364,7 @@ class BestellungController {
res.status(400).json({ success: false, message: 'Ungültige Bestellungs-ID' }); res.status(400).json({ success: false, message: 'Ungültige Bestellungs-ID' });
return; return;
} }
const { nachricht, faellig_am } = req.body; const { faellig_am } = req.body;
if (!faellig_am) { if (!faellig_am) {
res.status(400).json({ success: false, message: 'Fälligkeitsdatum ist erforderlich' }); res.status(400).json({ success: false, message: 'Fälligkeitsdatum ist erforderlich' });
return; return;

View File

@@ -394,7 +394,8 @@ class EquipmentController {
async getStatusHistory(req: Request, res: Response): Promise<void> { async getStatusHistory(req: Request, res: Response): Promise<void> {
try { try {
const history = await equipmentService.getStatusHistory(req.params.id); const { id } = req.params as Record<string, string>;
const history = await equipmentService.getStatusHistory(id);
res.status(200).json({ success: true, data: history }); res.status(200).json({ success: true, data: history });
} catch (error) { } catch (error) {
logger.error('getStatusHistory error', { error, id: req.params.id }); logger.error('getStatusHistory error', { error, id: req.params.id });
@@ -403,8 +404,9 @@ class EquipmentController {
} }
async uploadWartungFile(req: Request, res: Response): Promise<void> { async uploadWartungFile(req: Request, res: Response): Promise<void> {
const wartungId = parseInt(req.params.wartungId, 10); const { wartungId } = req.params as Record<string, string>;
if (isNaN(wartungId)) { const id = parseInt(wartungId, 10);
if (isNaN(id)) {
res.status(400).json({ success: false, message: 'Ungültige Wartungs-ID' }); res.status(400).json({ success: false, message: 'Ungültige Wartungs-ID' });
return; return;
} }
@@ -414,7 +416,7 @@ class EquipmentController {
return; return;
} }
try { try {
const result = await equipmentService.updateWartungslogFile(wartungId, file.path); const result = await equipmentService.updateWartungslogFile(id, file.path);
res.status(200).json({ success: true, data: result }); res.status(200).json({ success: true, data: result });
} catch (error) { } catch (error) {
logger.error('uploadWartungFile error', { error, wartungId }); logger.error('uploadWartungFile error', { error, wartungId });

View File

@@ -375,7 +375,8 @@ class VehicleController {
async getStatusHistory(req: Request, res: Response): Promise<void> { async getStatusHistory(req: Request, res: Response): Promise<void> {
try { try {
const history = await vehicleService.getStatusHistory(req.params.id); const { id } = req.params as Record<string, string>;
const history = await vehicleService.getStatusHistory(id);
res.status(200).json({ success: true, data: history }); res.status(200).json({ success: true, data: history });
} catch (error) { } catch (error) {
logger.error('getStatusHistory error', { error, id: req.params.id }); logger.error('getStatusHistory error', { error, id: req.params.id });
@@ -384,8 +385,9 @@ class VehicleController {
} }
async uploadWartungFile(req: Request, res: Response): Promise<void> { async uploadWartungFile(req: Request, res: Response): Promise<void> {
const wartungId = parseInt(req.params.wartungId, 10); const { wartungId } = req.params as Record<string, string>;
if (isNaN(wartungId)) { const id = parseInt(wartungId, 10);
if (isNaN(id)) {
res.status(400).json({ success: false, message: 'Ungültige Wartungs-ID' }); res.status(400).json({ success: false, message: 'Ungültige Wartungs-ID' });
return; return;
} }
@@ -395,7 +397,7 @@ class VehicleController {
return; return;
} }
try { try {
const result = await vehicleService.updateWartungslogFile(wartungId, file.path); const result = await vehicleService.updateWartungslogFile(id, file.path);
res.status(200).json({ success: true, data: result }); res.status(200).json({ success: true, data: result });
} catch (error) { } catch (error) {
logger.error('uploadWartungFile error', { error, wartungId }); logger.error('uploadWartungFile error', { error, wartungId });

View File

@@ -79,7 +79,7 @@ const wartungStorage = multer.diskStorage({
}); });
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export const uploadWartung: any = multer({ const wartungOptions: any = {
storage: wartungStorage, storage: wartungStorage,
fileFilter(_req: any, file: any, cb: any) { fileFilter(_req: any, file: any, cb: any) {
if (ALLOWED_TYPES.includes(file.mimetype)) { if (ALLOWED_TYPES.includes(file.mimetype)) {
@@ -89,6 +89,9 @@ export const uploadWartung: any = multer({
} }
}, },
limits: { fileSize: 20 * 1024 * 1024 }, limits: { fileSize: 20 * 1024 * 1024 },
}); };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const uploadWartung: any = multer(wartungOptions);
export { UPLOAD_DIR, THUMBNAIL_DIR, WARTUNG_DIR }; export { UPLOAD_DIR, THUMBNAIL_DIR, WARTUNG_DIR };

View File

@@ -558,7 +558,7 @@ const WartungTab: React.FC<WartungTabProps> = ({ fahrzeugId, wartungslog, onAdde
const file = e.target.files?.[0]; const file = e.target.files?.[0];
if (!file) return; if (!file) return;
try { try {
await vehiclesApi.uploadWartungFile(entry.id, file); await vehiclesApi.uploadWartungFile(Number(entry.id), file);
onAdded(); onAdded();
} catch { } catch {
// silent fail — user can retry // silent fail — user can retry

View File

@@ -5,12 +5,8 @@ import {
Button, Button,
CircularProgress, CircularProgress,
Container, Container,
FormControl,
Grid, Grid,
InputLabel,
MenuItem,
Paper, Paper,
Select,
TextField, TextField,
Typography, Typography,
} from '@mui/material'; } from '@mui/material';
@@ -19,8 +15,6 @@ import { useNavigate, useParams } from 'react-router-dom';
import DashboardLayout from '../components/dashboard/DashboardLayout'; import DashboardLayout from '../components/dashboard/DashboardLayout';
import { vehiclesApi } from '../services/vehicles'; import { vehiclesApi } from '../services/vehicles';
import { import {
FahrzeugStatus,
FahrzeugStatusLabel,
CreateFahrzeugPayload, CreateFahrzeugPayload,
UpdateFahrzeugPayload, UpdateFahrzeugPayload,
} from '../types/vehicle.types'; } from '../types/vehicle.types';
@@ -33,16 +27,14 @@ interface FormState {
kurzname: string; kurzname: string;
amtliches_kennzeichen: string; amtliches_kennzeichen: string;
fahrgestellnummer: string; fahrgestellnummer: string;
baujahr: string; // kept as string for input, parsed on submit baujahr: string;
hersteller: string; hersteller: string;
typ_schluessel: string; typ_schluessel: string;
besatzung_soll: string; besatzung_soll: string;
status: FahrzeugStatus;
status_bemerkung: string;
standort: string; standort: string;
bild_url: string; bild_url: string;
paragraph57a_faellig_am: string; // ISO date 'YYYY-MM-DD' or '' paragraph57a_faellig_am: string;
naechste_wartung_am: string; // ISO date 'YYYY-MM-DD' or '' naechste_wartung_am: string;
} }
const EMPTY_FORM: FormState = { const EMPTY_FORM: FormState = {
@@ -54,8 +46,6 @@ const EMPTY_FORM: FormState = {
hersteller: '', hersteller: '',
typ_schluessel: '', typ_schluessel: '',
besatzung_soll: '', besatzung_soll: '',
status: FahrzeugStatus.Einsatzbereit,
status_bemerkung: '',
standort: 'Feuerwehrhaus', standort: 'Feuerwehrhaus',
bild_url: '', bild_url: '',
paragraph57a_faellig_am: '', paragraph57a_faellig_am: '',
@@ -102,8 +92,6 @@ function FahrzeugForm() {
hersteller: vehicle.hersteller ?? '', hersteller: vehicle.hersteller ?? '',
typ_schluessel: vehicle.typ_schluessel ?? '', typ_schluessel: vehicle.typ_schluessel ?? '',
besatzung_soll: vehicle.besatzung_soll ?? '', besatzung_soll: vehicle.besatzung_soll ?? '',
status: vehicle.status,
status_bemerkung: vehicle.status_bemerkung ?? '',
standort: vehicle.standort, standort: vehicle.standort,
bild_url: vehicle.bild_url ?? '', bild_url: vehicle.bild_url ?? '',
paragraph57a_faellig_am: toDateInput(vehicle.paragraph57a_faellig_am), paragraph57a_faellig_am: toDateInput(vehicle.paragraph57a_faellig_am),