rework vehicle handling
This commit is contained in:
@@ -560,7 +560,7 @@ class IncidentService {
|
|||||||
[targetYear]
|
[targetYear]
|
||||||
);
|
);
|
||||||
|
|
||||||
const totals = totalsResult.rows[0];
|
const totals = totalsResult.rows[0] ?? { gesamt: 0, abgeschlossen: 0, aktiv: 0, avg_hilfsfrist_min: null };
|
||||||
|
|
||||||
// Monthly breakdown — target year
|
// Monthly breakdown — target year
|
||||||
const monthlyResult = await pool.query(
|
const monthlyResult = await pool.query(
|
||||||
@@ -636,21 +636,21 @@ class IncidentService {
|
|||||||
const haeufigste_art: EinsatzArt | null =
|
const haeufigste_art: EinsatzArt | null =
|
||||||
byArtResult.rows.length > 0 ? (byArtResult.rows[0].einsatz_art as EinsatzArt) : null;
|
byArtResult.rows.length > 0 ? (byArtResult.rows[0].einsatz_art as EinsatzArt) : null;
|
||||||
|
|
||||||
const monthly: MonthlyStatRow[] = monthlyResult.rows.map((r) => ({
|
const monthly: MonthlyStatRow[] = (monthlyResult.rows ?? []).map((r) => ({
|
||||||
monat: r.monat,
|
monat: r.monat,
|
||||||
anzahl: r.anzahl,
|
anzahl: r.anzahl,
|
||||||
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
||||||
avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null,
|
avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const prev_year_monthly: MonthlyStatRow[] = prevMonthlyResult.rows.map((r) => ({
|
const prev_year_monthly: MonthlyStatRow[] = (prevMonthlyResult.rows ?? []).map((r) => ({
|
||||||
monat: r.monat,
|
monat: r.monat,
|
||||||
anzahl: r.anzahl,
|
anzahl: r.anzahl,
|
||||||
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
||||||
avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null,
|
avg_dauer_min: r.avg_dauer_min !== null ? Number(r.avg_dauer_min) : null,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const by_art: EinsatzArtStatRow[] = byArtResult.rows.map((r) => ({
|
const by_art: EinsatzArtStatRow[] = (byArtResult.rows ?? []).map((r) => ({
|
||||||
einsatz_art: r.einsatz_art as EinsatzArt,
|
einsatz_art: r.einsatz_art as EinsatzArt,
|
||||||
anzahl: r.anzahl,
|
anzahl: r.anzahl,
|
||||||
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
avg_hilfsfrist_min: r.avg_hilfsfrist_min !== null ? Number(r.avg_hilfsfrist_min) : null,
|
||||||
|
|||||||
@@ -236,6 +236,8 @@ class MemberService {
|
|||||||
// Attach rank history when the profile exists
|
// Attach rank history when the profile exists
|
||||||
if (member.profile) {
|
if (member.profile) {
|
||||||
member.dienstgrad_verlauf = await this.getDienstgradVerlauf(userId);
|
member.dienstgrad_verlauf = await this.getDienstgradVerlauf(userId);
|
||||||
|
} else {
|
||||||
|
member.dienstgrad_verlauf = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return member;
|
return member;
|
||||||
@@ -583,7 +585,15 @@ class MemberService {
|
|||||||
FROM mitglieder_profile
|
FROM mitglieder_profile
|
||||||
`);
|
`);
|
||||||
|
|
||||||
return result.rows[0] as MemberStats;
|
return (result.rows[0] as MemberStats) ?? {
|
||||||
|
total: 0,
|
||||||
|
aktiv: 0,
|
||||||
|
passiv: 0,
|
||||||
|
ehrenmitglied: 0,
|
||||||
|
jugendfeuerwehr: 0,
|
||||||
|
'anwärter': 0,
|
||||||
|
ausgetreten: 0,
|
||||||
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Error fetching member stats', { error });
|
logger.error('Error fetching member stats', { error });
|
||||||
throw new Error('Failed to fetch member stats');
|
throw new Error('Failed to fetch member stats');
|
||||||
|
|||||||
@@ -373,16 +373,16 @@ class VehicleService {
|
|||||||
WHERE deleted_at IS NULL
|
WHERE deleted_at IS NULL
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const totals = totalsResult.rows[0];
|
const totals = totalsResult.rows[0] ?? { total: '0', einsatzbereit: '0', ausser_dienst: '0', in_lehrgang: '0' };
|
||||||
const alerts = alertResult.rows[0];
|
const alerts = alertResult.rows[0] ?? { inspections_due: '0', inspections_overdue: '0' };
|
||||||
|
|
||||||
return {
|
return {
|
||||||
total: parseInt(totals.total, 10),
|
total: parseInt(totals.total ?? '0', 10),
|
||||||
einsatzbereit: parseInt(totals.einsatzbereit, 10),
|
einsatzbereit: parseInt(totals.einsatzbereit ?? '0', 10),
|
||||||
ausserDienst: parseInt(totals.ausser_dienst, 10),
|
ausserDienst: parseInt(totals.ausser_dienst ?? '0', 10),
|
||||||
inLehrgang: parseInt(totals.in_lehrgang, 10),
|
inLehrgang: parseInt(totals.in_lehrgang ?? '0', 10),
|
||||||
inspectionsDue: parseInt(alerts.inspections_due, 10),
|
inspectionsDue: parseInt(alerts.inspections_due ?? '0', 10),
|
||||||
inspectionsOverdue: parseInt(alerts.inspections_overdue, 10),
|
inspectionsOverdue: parseInt(alerts.inspections_overdue ?? '0', 10),
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('VehicleService.getVehicleStats failed', { error });
|
logger.error('VehicleService.getVehicleStats failed', { error });
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
Fab,
|
Fab,
|
||||||
FormControl,
|
FormControl,
|
||||||
Grid,
|
Grid,
|
||||||
|
IconButton,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Paper,
|
Paper,
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ export const incidentsApi = {
|
|||||||
const response = await api.get<{ success: boolean; data: IncidentListResponse }>(
|
const response = await api.get<{ success: boolean; data: IncidentListResponse }>(
|
||||||
`/api/incidents?${params.toString()}`
|
`/api/incidents?${params.toString()}`
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -230,7 +230,7 @@ export const incidentsApi = {
|
|||||||
const response = await api.get<{ success: boolean; data: EinsatzStats }>(
|
const response = await api.get<{ success: boolean; data: EinsatzStats }>(
|
||||||
`/api/incidents/stats${params}`
|
`/api/incidents/stats${params}`
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -243,7 +243,7 @@ export const incidentsApi = {
|
|||||||
const response = await api.get<{ success: boolean; data: EinsatzDetail }>(
|
const response = await api.get<{ success: boolean; data: EinsatzDetail }>(
|
||||||
`/api/incidents/${id}`
|
`/api/incidents/${id}`
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -257,7 +257,7 @@ export const incidentsApi = {
|
|||||||
'/api/incidents',
|
'/api/incidents',
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -271,7 +271,7 @@ export const incidentsApi = {
|
|||||||
`/api/incidents/${id}`,
|
`/api/incidents/${id}`,
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const membersService = {
|
|||||||
const response = await api.get<ApiListResponse<MemberListItem>>(
|
const response = await api.get<ApiListResponse<MemberListItem>>(
|
||||||
`/api/members?${params.toString()}`
|
`/api/members?${params.toString()}`
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -72,7 +72,7 @@ export const membersService = {
|
|||||||
const response = await api.get<ApiItemResponse<MemberWithProfile>>(
|
const response = await api.get<ApiItemResponse<MemberWithProfile>>(
|
||||||
`/api/members/${userId}`
|
`/api/members/${userId}`
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -90,7 +90,7 @@ export const membersService = {
|
|||||||
`/api/members/${userId}/profile`,
|
`/api/members/${userId}/profile`,
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -109,7 +109,7 @@ export const membersService = {
|
|||||||
`/api/members/${userId}`,
|
`/api/members/${userId}`,
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -120,7 +120,7 @@ export const membersService = {
|
|||||||
*/
|
*/
|
||||||
async getMemberStats(): Promise<MemberStats> {
|
async getMemberStats(): Promise<MemberStats> {
|
||||||
const response = await api.get<ApiItemResponse<MemberStats>>('/api/members/stats');
|
const response = await api.get<ApiItemResponse<MemberStats>>('/api/members/stats');
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ async function unwrap<T>(
|
|||||||
promise: ReturnType<typeof api.get<{ success: boolean; data: T }>>
|
promise: ReturnType<typeof api.get<{ success: boolean; data: T }>>
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const response = await promise;
|
const response = await promise;
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -47,7 +47,7 @@ export const vehiclesApi = {
|
|||||||
'/api/vehicles',
|
'/api/vehicles',
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -58,7 +58,7 @@ export const vehiclesApi = {
|
|||||||
`/api/vehicles/${id}`,
|
`/api/vehicles/${id}`,
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
@@ -83,7 +83,7 @@ export const vehiclesApi = {
|
|||||||
`/api/vehicles/${id}/wartung`,
|
`/api/vehicles/${id}/wartung`,
|
||||||
payload
|
payload
|
||||||
);
|
);
|
||||||
if (!response.data?.data) {
|
if (response.data?.data === undefined || response.data?.data === null) {
|
||||||
throw new Error('Invalid API response');
|
throw new Error('Invalid API response');
|
||||||
}
|
}
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
|
|||||||
Reference in New Issue
Block a user