feat(registratura): AC validity 12/24 months + reminder config in Ghid termene
- Add ACValidityPeriod type (12 | 24) and validityMonths field to ACValidityTracking - Replace hardcoded 12-month validity with configurable dropdown (12/24 luni) - Update computed dates, reminder counter, and tooltip to use selected period - Add "Configurare remindere si alerte" section in Ghid termene with: - Threshold table (urgent 5z, depasit 0z, CU alert 30z, AC monthly, prelungire 45z lucr, anuntare 10z cal, transmitere 1z) - Pause/resume explanation for clarification requests - Update AC expiry description to mention configurable 12/24 month validity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@ import {
|
||||
import { Textarea } from "@/shared/components/ui/textarea";
|
||||
import type {
|
||||
ACValidityTracking,
|
||||
ACValidityPeriod,
|
||||
ACExecutionDuration,
|
||||
ACPhase,
|
||||
} from "../types";
|
||||
@@ -52,6 +53,11 @@ interface ACValidityTrackerProps {
|
||||
entryDate: string;
|
||||
}
|
||||
|
||||
const VALIDITY_LABELS: Record<ACValidityPeriod, string> = {
|
||||
12: "12 luni",
|
||||
24: "24 luni",
|
||||
};
|
||||
|
||||
const EXECUTION_LABELS: Record<ACExecutionDuration, string> = {
|
||||
6: "6 luni",
|
||||
12: "12 luni",
|
||||
@@ -158,9 +164,10 @@ export function ACValidityTracker({
|
||||
now.setHours(0, 0, 0, 0);
|
||||
const today = now.toISOString().slice(0, 10);
|
||||
|
||||
// 12-month validity period
|
||||
// Configurable validity period (12 or 24 months)
|
||||
const validityMonths = ac.validityMonths ?? 12;
|
||||
const validityEnd = new Date(issuance);
|
||||
validityEnd.setMonth(validityEnd.getMonth() + 12);
|
||||
validityEnd.setMonth(validityEnd.getMonth() + validityMonths);
|
||||
const validityEndStr = validityEnd.toISOString().slice(0, 10);
|
||||
const daysToValidityEnd = daysBetween(today, validityEndStr);
|
||||
const monthsToValidityEnd = monthsBetween(today, validityEndStr);
|
||||
@@ -243,10 +250,10 @@ export function ACValidityTracker({
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right" className="max-w-sm">
|
||||
<p className="text-xs">
|
||||
Urmărirea completă a ciclului de viață al AC: valabilitate 12
|
||||
luni, anunțare lucrări, documente obligatorii, durată
|
||||
execuție, prelungire. Conform Legii 50/1991 și normelor
|
||||
aferente.
|
||||
Urmărirea completă a ciclului de viață al AC: valabilitate
|
||||
12 sau 24 luni (configurabil), anunțare lucrări, documente
|
||||
obligatorii, durată execuție, prelungire. Conform Legii
|
||||
50/1991 și normelor aferente.
|
||||
</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
@@ -288,8 +295,8 @@ export function ACValidityTracker({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Issuance date + duration */}
|
||||
<div className="grid gap-3 sm:grid-cols-3">
|
||||
{/* Issuance date + validity period + duration */}
|
||||
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<div>
|
||||
<Label className="text-xs">Data emitere AC</Label>
|
||||
<Input
|
||||
@@ -299,6 +306,28 @@ export function ACValidityTracker({
|
||||
className="mt-1"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Perioadă valabilitate</Label>
|
||||
<Select
|
||||
value={String(ac.validityMonths ?? 12)}
|
||||
onValueChange={(v) =>
|
||||
update({
|
||||
validityMonths: parseInt(v, 10) as ACValidityPeriod,
|
||||
})
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="mt-1">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{([12, 24] as ACValidityPeriod[]).map((d) => (
|
||||
<SelectItem key={d} value={String(d)}>
|
||||
{VALIDITY_LABELS[d]}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<Label className="text-xs">Valabilitate până la</Label>
|
||||
<div className="mt-1 rounded border bg-muted/50 px-3 py-2 text-sm font-mono">
|
||||
@@ -633,7 +662,7 @@ export function ACValidityTracker({
|
||||
<span className="text-muted-foreground">
|
||||
{ac.reminder.dismissed
|
||||
? "Remindere dezactivate"
|
||||
: `Reminder lunar activ (luna ${computedData.monthsToValidityEnd > 0 ? 12 - computedData.monthsToValidityEnd : 12}/12)`}
|
||||
: `Reminder lunar activ (luna ${computedData.monthsToValidityEnd > 0 ? (ac.validityMonths ?? 12) - computedData.monthsToValidityEnd : (ac.validityMonths ?? 12)}/${ac.validityMonths ?? 12})`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex gap-1">
|
||||
|
||||
@@ -257,6 +257,125 @@ export function DeadlineConfigOverview() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Reminder & alert configuration ── */}
|
||||
<div className="rounded-lg border bg-card">
|
||||
<div className="flex items-center gap-3 px-4 py-3">
|
||||
<Timer className="h-4 w-4 text-orange-500" />
|
||||
<span className="text-sm font-medium">Configurare remindere si alerte</span>
|
||||
</div>
|
||||
<Separator />
|
||||
<div className="px-4 py-3 space-y-4">
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Praguri si intervale folosite de sistem pentru a genera alerte si notificari. Valorile se aplica automat tuturor inregistrarilor.
|
||||
</p>
|
||||
|
||||
{/* Thresholds table */}
|
||||
<div className="overflow-hidden rounded-md border">
|
||||
<table className="w-full text-xs">
|
||||
<thead>
|
||||
<tr className="bg-muted/50">
|
||||
<th className="px-3 py-2 text-left font-medium">Parametru</th>
|
||||
<th className="px-3 py-2 text-left font-medium">Valoare</th>
|
||||
<th className="px-3 py-2 text-left font-medium">Descriere</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y">
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Prag "Urgent"</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-yellow-50 text-yellow-700 border-yellow-300 text-[10px] dark:bg-yellow-900/20 dark:text-yellow-300 dark:border-yellow-700">
|
||||
5 zile
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Termenele cu 5 sau mai putine zile ramase sunt marcate ca urgente (galben) si incluse in digest-ul zilnic.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Prag "Depasit"</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-red-50 text-red-700 border-red-300 text-[10px] dark:bg-red-900/20 dark:text-red-300 dark:border-red-700">
|
||||
0 zile
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Termenele depasite (dupa data scadenta) sunt marcate rosu si raportate zilnic pana la rezolvare.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Alerta expirare CU</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-amber-50 text-amber-700 border-amber-300 text-[10px] dark:bg-amber-900/20 dark:text-amber-300 dark:border-amber-700">
|
||||
30 zile (implicit)
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Se poate configura per inregistrare (campul "Zile alerta expirare"). Implicit 30 zile inainte de expirare.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Reminder lunar AC</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-indigo-50 text-indigo-700 border-indigo-300 text-[10px] dark:bg-indigo-900/20 dark:text-indigo-300 dark:border-indigo-700">
|
||||
Lunar
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
In faza de valabilitate AC, se afiseaza reminder lunar. Se poate amana (+1 luna) sau dezactiva (dismiss) per AC.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Cerere prelungire AC</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-amber-50 text-amber-700 border-amber-300 text-[10px] dark:bg-amber-900/20 dark:text-amber-300 dark:border-amber-700">
|
||||
45 zile lucr.
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Alerta automata: cererea de prelungire trebuie depusa cu minim 45 zile lucratoare inainte de expirarea AC/executiei.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Anuntare lucrari AC</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="bg-green-50 text-green-700 border-green-300 text-[10px] dark:bg-green-900/20 dark:text-green-300 dark:border-green-700">
|
||||
10 zile cal.
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Lucrarile trebuie anuntate la Primarie si ISC cu minim 10 zile calendaristice inainte de incepere.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="px-3 py-2 font-medium">Transmitere in termen</td>
|
||||
<td className="px-3 py-2">
|
||||
<Badge variant="outline" className="border-dashed text-[10px] text-muted-foreground">
|
||||
1 zi (fundal)
|
||||
</Badge>
|
||||
</td>
|
||||
<td className="px-3 py-2 text-muted-foreground">
|
||||
Verificare automata in fundal: actul administrativ trebuie transmis in 1 zi de la emitere. Se creeaza automat la inchidere.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* Pause/resume info */}
|
||||
<div className="rounded-md border bg-muted/20 px-3 py-2.5 space-y-1.5">
|
||||
<p className="text-xs font-medium flex items-center gap-1.5">
|
||||
<Clock className="h-3.5 w-3.5 text-blue-500" />
|
||||
Suspendare / reluare termene (clarificari)
|
||||
</p>
|
||||
<p className="text-[11px] text-muted-foreground leading-relaxed">
|
||||
Cand se primeste o solicitare de clarificari (document intrat conex), termenele active ale inregistrarii mama se suspenda automat.
|
||||
La depunerea completarilor (document iesit conex), termenele se reiau, iar data scadenta se decaleaza cu numarul de zile suspendate.
|
||||
Suspendarea se poate face si manual din fisa termenului.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* ── Document expiry overview ── */}
|
||||
<div className="rounded-lg border bg-card">
|
||||
<div className="flex items-center gap-3 px-4 py-3">
|
||||
@@ -280,7 +399,7 @@ export function DeadlineConfigOverview() {
|
||||
<div className="text-xs">
|
||||
<span className="font-medium">Autorizatie de Construire (AC)</span>
|
||||
<span className="ml-1 text-muted-foreground">
|
||||
— validitate 12 luni de la emitere, executie 6/12/24/36 luni, prelungire +24 luni.
|
||||
— valabilitate 12 sau 24 luni (configurabil per AC), executie 6/12/24/36 luni, prelungire +24 luni.
|
||||
Reminder lunar automat (snooze/dismiss disponibil).
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -226,6 +226,8 @@ export interface ACReminder {
|
||||
dismissed: boolean;
|
||||
}
|
||||
|
||||
export type ACValidityPeriod = 12 | 24;
|
||||
|
||||
/** Full AC validity tracking state */
|
||||
export interface ACValidityTracking {
|
||||
/** Whether AC tracking is enabled for this entry */
|
||||
@@ -234,6 +236,8 @@ export interface ACValidityTracking {
|
||||
issuanceDate: string;
|
||||
/** Current phase */
|
||||
phase: ACPhase;
|
||||
/** Validity period in months (default 12, can be 24 for special cases) */
|
||||
validityMonths?: ACValidityPeriod;
|
||||
/** Execution duration selected (months) */
|
||||
executionDuration: ACExecutionDuration;
|
||||
/** Date works were announced to City Hall & ISC */
|
||||
|
||||
Reference in New Issue
Block a user