fix and update language for company workspace

This commit is contained in:
root
2026-05-11 23:40:40 -04:00
committed by Administrator
parent 193aeae834
commit 1a39aa8433
43 changed files with 5034 additions and 802 deletions
@@ -2,6 +2,7 @@
import { useState } from 'react'
import { apiFetch } from '@/lib/api'
import { useDashboardI18n } from '@/components/I18nProvider'
type InspectionType = 'CHECKIN' | 'CHECKOUT'
type FuelLevel = 'FULL' | 'SEVEN_EIGHTHS' | 'THREE_QUARTERS' | 'FIVE_EIGHTHS' | 'HALF' | 'THREE_EIGHTHS' | 'QUARTER' | 'ONE_EIGHTH' | 'EMPTY'
@@ -50,6 +51,9 @@ export default function DamageInspectionCard({
initialInspection?: DamageInspection | null
onSaved: (inspection: DamageInspection) => void
}) {
const { dict } = useDashboardI18n()
const r = dict.reservations
const [inspection, setInspection] = useState<DamageInspection>({
id: initialInspection?.id ?? `${type.toLowerCase()}-draft`,
type,
@@ -80,20 +84,14 @@ export default function DamageInspectionCard({
employeeNotes: inspection.employeeNotes,
customerAgreed: inspection.customerAgreed,
damagePoints: inspection.damagePoints.map(({ viewType, x, y, damageType, severity, description, isPreExisting }) => ({
viewType,
x,
y,
damageType,
severity,
description,
isPreExisting,
viewType, x, y, damageType, severity, description, isPreExisting,
})),
}),
})
setInspection(result)
onSaved(result)
} catch (err: any) {
setError(err.message ?? 'Failed to save inspection')
setError(err.message ?? r.failedSaveInspection)
} finally {
setSaving(false)
}
@@ -107,15 +105,7 @@ export default function DamageInspectionCard({
...current,
damagePoints: [
...current.damagePoints,
{
viewType: 'TOP',
x,
y,
damageType,
severity,
description: '',
isPreExisting: type === 'CHECKIN',
},
{ viewType: 'TOP', x, y, damageType, severity, description: '', isPreExisting: type === 'CHECKIN' },
],
}))
}
@@ -123,7 +113,7 @@ export default function DamageInspectionCard({
function removePoint(index: number) {
setInspection((current) => ({
...current,
damagePoints: current.damagePoints.filter((_, pointIndex) => pointIndex !== index),
damagePoints: current.damagePoints.filter((_, i) => i !== index),
}))
}
@@ -131,11 +121,11 @@ export default function DamageInspectionCard({
<div className="card p-6">
<div className="flex items-start justify-between gap-4">
<div>
<h3 className="text-base font-semibold text-slate-900">{type === 'CHECKIN' ? 'Check-in inspection' : 'Check-out inspection'}</h3>
<p className="mt-1 text-sm text-slate-500">Mark existing and newly discovered damage directly on the vehicle diagram.</p>
<h3 className="text-base font-semibold text-slate-900">{r.inspectionCardTitle(type)}</h3>
<p className="mt-1 text-sm text-slate-500">{r.inspectionSubtitle}</p>
</div>
<button onClick={saveInspection} disabled={saving} className="btn-primary">
{saving ? 'Saving…' : 'Save inspection'}
{saving ? r.savingInspection : r.saveInspection}
</button>
</div>
@@ -151,7 +141,7 @@ export default function DamageInspectionCard({
onClick={() => setDamageType(option)}
className={`rounded-full px-3 py-1.5 font-semibold ${damageType === option ? 'bg-slate-900 text-white' : 'bg-white text-slate-600'}`}
>
{option}
{r.damageTypeLabels[option]}
</button>
))}
</div>
@@ -164,7 +154,7 @@ export default function DamageInspectionCard({
className="rounded-full px-3 py-1.5 font-semibold text-white"
style={{ backgroundColor: severityColors[option], opacity: severity === option ? 1 : 0.55 }}
>
{option}
{r.severityLabels[option]}
</button>
))}
</div>
@@ -184,61 +174,61 @@ export default function DamageInspectionCard({
</g>
))}
</svg>
<p className="mt-2 text-xs text-slate-500">Click anywhere on the diagram to add a damage marker with the selected type and severity.</p>
<p className="mt-2 text-xs text-slate-500">{r.diagramHelp}</p>
</div>
<div className="space-y-4">
<div className="grid gap-4 sm:grid-cols-2">
<div>
<label className="mb-1.5 block text-sm font-medium text-slate-700">Mileage</label>
<label className="mb-1.5 block text-sm font-medium text-slate-700">{r.mileageLabel}</label>
<input
type="number"
className="input-field"
value={inspection.mileage ?? ''}
onChange={(event) => setInspection((current) => ({ ...current, mileage: event.target.value ? Number(event.target.value) : null }))}
onChange={(e) => setInspection((cur) => ({ ...cur, mileage: e.target.value ? Number(e.target.value) : null }))}
/>
</div>
<div>
<label className="mb-1.5 block text-sm font-medium text-slate-700">Fuel level</label>
<select className="input-field" value={inspection.fuelLevel} onChange={(event) => setInspection((current) => ({ ...current, fuelLevel: event.target.value as FuelLevel }))}>
{fuelLevels.map((fuelLevel) => <option key={fuelLevel} value={fuelLevel}>{fuelLevel}</option>)}
<label className="mb-1.5 block text-sm font-medium text-slate-700">{r.fuelLevelLabel}</label>
<select className="input-field" value={inspection.fuelLevel} onChange={(e) => setInspection((cur) => ({ ...cur, fuelLevel: e.target.value as FuelLevel }))}>
{fuelLevels.map((fl) => <option key={fl} value={fl}>{r.fuelLevels[fl]}</option>)}
</select>
</div>
</div>
<div>
<label className="mb-1.5 block text-sm font-medium text-slate-700">General condition</label>
<textarea className="input-field min-h-24" value={inspection.generalCondition ?? ''} onChange={(event) => setInspection((current) => ({ ...current, generalCondition: event.target.value }))} />
<label className="mb-1.5 block text-sm font-medium text-slate-700">{r.generalConditionLabel}</label>
<textarea className="input-field min-h-24" value={inspection.generalCondition ?? ''} onChange={(e) => setInspection((cur) => ({ ...cur, generalCondition: e.target.value }))} />
</div>
<div>
<label className="mb-1.5 block text-sm font-medium text-slate-700">Employee notes</label>
<textarea className="input-field min-h-24" value={inspection.employeeNotes ?? ''} onChange={(event) => setInspection((current) => ({ ...current, employeeNotes: event.target.value }))} />
<label className="mb-1.5 block text-sm font-medium text-slate-700">{r.employeeNotesLabel}</label>
<textarea className="input-field min-h-24" value={inspection.employeeNotes ?? ''} onChange={(e) => setInspection((cur) => ({ ...cur, employeeNotes: e.target.value }))} />
</div>
<label className="flex items-center gap-3 text-sm font-medium text-slate-700">
<input type="checkbox" checked={inspection.customerAgreed} onChange={(event) => setInspection((current) => ({ ...current, customerAgreed: event.target.checked }))} />
Customer acknowledged this inspection
<input type="checkbox" checked={inspection.customerAgreed} onChange={(e) => setInspection((cur) => ({ ...cur, customerAgreed: e.target.checked }))} />
{r.customerAcknowledged}
</label>
<div className="rounded-2xl border border-slate-200">
<div className="border-b border-slate-200 px-4 py-3">
<p className="text-sm font-semibold text-slate-900">Damage markers</p>
<p className="text-sm font-semibold text-slate-900">{r.damageMarkersHeading}</p>
</div>
<div className="divide-y divide-slate-100">
{inspection.damagePoints.map((point, index) => (
<div key={`${point.x}-${point.y}-${index}`} className="flex items-center justify-between gap-3 px-4 py-3 text-sm">
<div>
<p className="font-medium text-slate-900">{point.damageType} · {point.severity}</p>
<p className="font-medium text-slate-900">{r.damageTypeLabels[point.damageType]} · {r.severityLabels[point.severity]}</p>
<p className="text-xs text-slate-500">x {point.x.toFixed(1)} · y {point.y.toFixed(1)}</p>
</div>
<button type="button" onClick={() => removePoint(index)} className="rounded-full border border-slate-300 px-3 py-1 text-xs font-semibold text-slate-600">
Remove
{r.removeMarker}
</button>
</div>
))}
{inspection.damagePoints.length === 0 && (
<div className="px-4 py-6 text-sm text-slate-400">No damage markers saved yet.</div>
<div className="px-4 py-6 text-sm text-slate-400">{r.noMarkers}</div>
)}
</div>
</div>