Revízny systém - kompletná implementácia
- Backend: CRUD revízií, schedule endpoint (agregovaný plán), skip revízia, stats - Shared utility revisionSchedule.ts - centralizovaná logika výpočtu cyklov - Equipment detail s revíznym plánom, históriou a prílohami - Frontend: RevisionsList s tabmi (nadchádzajúce/po termíne/vykonané/preskočené) - Pozičné labeling cyklov (eliminuje drift 4×90≠365) - EquipmentRevisionSchedule model (many-to-many typy revízií) - Aktualizovaná dokumentácia HELPDESK_INIT_V2.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
102
frontend/src/hooks/useRevisionStatus.ts
Normal file
102
frontend/src/hooks/useRevisionStatus.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { settingsApi } from '@/services/settings.api';
|
||||
import { AlertTriangle, Clock, CheckCircle, SkipForward, type LucideIcon } from 'lucide-react';
|
||||
|
||||
export interface RevisionThreshold {
|
||||
days: number;
|
||||
label: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
const DEFAULT_THRESHOLDS: RevisionThreshold[] = [
|
||||
{ days: 30, label: 'Blíži sa', color: '#EAB308' },
|
||||
{ days: 14, label: 'Blíži sa!', color: '#F97316' },
|
||||
{ days: 7, label: 'Urgentné!', color: '#EF4444' },
|
||||
];
|
||||
|
||||
const OVERDUE_COLOR = '#DC2626';
|
||||
const OK_COLOR = '#22C55E';
|
||||
const SKIP_COLOR = '#9CA3AF';
|
||||
|
||||
export type RevisionContext = 'schedule' | 'performed' | 'skipped';
|
||||
|
||||
export interface RevisionStatusResult {
|
||||
label: string;
|
||||
color: string | null;
|
||||
icon: LucideIcon | null;
|
||||
variant: 'default' | 'secondary' | 'destructive' | 'outline';
|
||||
}
|
||||
|
||||
export function useRevisionStatus() {
|
||||
const { data: settingData } = useQuery({
|
||||
queryKey: ['system-setting', 'REVISION_STATUS_THRESHOLDS'],
|
||||
queryFn: () => settingsApi.getSystemSetting('REVISION_STATUS_THRESHOLDS'),
|
||||
staleTime: 5 * 60 * 1000,
|
||||
});
|
||||
|
||||
const thresholds: RevisionThreshold[] = Array.isArray(settingData?.data?.value)
|
||||
? (settingData.data.value as RevisionThreshold[])
|
||||
: DEFAULT_THRESHOLDS;
|
||||
|
||||
// Zoradiť vzostupne podľa dní
|
||||
const sorted = [...thresholds].sort((a, b) => a.days - b.days);
|
||||
|
||||
function getStatus(nextDueDate?: string | null, context?: RevisionContext | boolean): RevisionStatusResult {
|
||||
// Spätná kompatibilita: boolean → context
|
||||
let ctx: RevisionContext;
|
||||
if (typeof context === 'boolean') {
|
||||
ctx = context ? 'schedule' : 'performed';
|
||||
} else {
|
||||
ctx = context || 'schedule';
|
||||
}
|
||||
|
||||
if (ctx === 'performed') {
|
||||
return { label: 'Vykonaná', color: OK_COLOR, icon: CheckCircle, variant: 'secondary' };
|
||||
}
|
||||
|
||||
if (ctx === 'skipped') {
|
||||
return { label: 'Vynechaná', color: SKIP_COLOR, icon: SkipForward, variant: 'secondary' };
|
||||
}
|
||||
|
||||
// context === 'schedule' → countdown logika
|
||||
if (!nextDueDate) {
|
||||
return { label: '-', color: null, icon: null, variant: 'secondary' };
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const due = new Date(nextDueDate);
|
||||
const diffDays = Math.ceil((due.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
|
||||
|
||||
// Po termíne
|
||||
if (diffDays < 0) {
|
||||
return {
|
||||
label: `Po termíne (${Math.abs(diffDays)} dní)`,
|
||||
color: OVERDUE_COLOR,
|
||||
icon: AlertTriangle,
|
||||
variant: 'destructive',
|
||||
};
|
||||
}
|
||||
|
||||
// Nájsť prvý prah kde diffDays <= threshold.days
|
||||
for (const threshold of sorted) {
|
||||
if (diffDays <= threshold.days) {
|
||||
return {
|
||||
label: `${threshold.label} (${diffDays} dní)`,
|
||||
color: threshold.color,
|
||||
icon: Clock,
|
||||
variant: 'default',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// V poriadku - ďaleko od termínu
|
||||
return {
|
||||
label: `Za ${diffDays} dní`,
|
||||
color: OK_COLOR,
|
||||
icon: CheckCircle,
|
||||
variant: 'default',
|
||||
};
|
||||
}
|
||||
|
||||
return { getStatus, thresholds };
|
||||
}
|
||||
Reference in New Issue
Block a user