Notification updates

This commit is contained in:
Eric Gullickson
2025-12-21 19:56:52 -06:00
parent 144f1d5bb0
commit 719c80ecd8
80 changed files with 7552 additions and 678 deletions

View File

@@ -96,13 +96,13 @@ export const DocumentForm: React.FC<DocumentFormProps> = ({ onSuccess, onCancel
}
const created = await create.mutateAsync({
vehicle_id: vehicleID,
document_type: documentType,
vehicleId: vehicleID,
documentType: documentType,
title: title.trim(),
notes: notes.trim() || undefined,
details,
issued_date,
expiration_date,
issuedDate: issued_date,
expirationDate: expiration_date,
});
if (file) {

View File

@@ -12,8 +12,8 @@ export const DocumentPreview: React.FC<Props> = ({ doc }) => {
const [error, setError] = useState<string | null>(null);
const previewable = useMemo(() => {
return doc.content_type === 'application/pdf' || doc.content_type?.startsWith('image/');
}, [doc.content_type]);
return doc.contentType === 'application/pdf' || doc.contentType?.startsWith('image/');
}, [doc.contentType]);
useEffect(() => {
let revoked: string | null = null;
@@ -37,7 +37,7 @@ export const DocumentPreview: React.FC<Props> = ({ doc }) => {
if (error) return <div className="text-red-600 text-sm">{error}</div>;
if (!blobUrl) return <div className="text-slate-500 text-sm">Loading preview...</div>;
if (doc.content_type === 'application/pdf') {
if (doc.contentType === 'application/pdf') {
return (
<object data={blobUrl} type="application/pdf" className="w-full h-[60vh] rounded-lg border" aria-label="PDF Preview">
<a href={blobUrl} target="_blank" rel="noopener noreferrer">Open PDF</a>

View File

@@ -36,23 +36,23 @@ export function useCreateDocument() {
// Create optimistic document record
const optimisticDocument: DocumentRecord = {
id: `temp-${Date.now()}`, // Temporary ID
user_id: '', // Will be filled by server
vehicle_id: newDocument.vehicle_id,
document_type: newDocument.document_type,
userId: '', // Will be filled by server
vehicleId: newDocument.vehicleId,
documentType: newDocument.documentType,
title: newDocument.title,
notes: newDocument.notes || null,
details: newDocument.details || null,
storage_bucket: null,
storage_key: null,
file_name: null,
content_type: null,
file_size: null,
file_hash: null,
issued_date: newDocument.issued_date || null,
expiration_date: newDocument.expiration_date || null,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
deleted_at: null,
storageBucket: null,
storageKey: null,
fileName: null,
contentType: null,
fileSize: null,
fileHash: null,
issuedDate: newDocument.issuedDate || null,
expirationDate: newDocument.expirationDate || null,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
deletedAt: null,
};
// Optimistically update cache
@@ -96,7 +96,7 @@ export function useUpdateDocument(id: string) {
return {
...old,
...updateData,
updated_at: new Date().toISOString(),
updatedAt: new Date().toISOString(),
};
});
@@ -105,7 +105,7 @@ export function useUpdateDocument(id: string) {
if (!old) return old;
return old.map(doc =>
doc.id === id
? { ...doc, ...updateData, updated_at: new Date().toISOString() }
? { ...doc, ...updateData, updatedAt: new Date().toISOString() }
: doc
);
});
@@ -186,10 +186,10 @@ export function useUploadDocument(id: string) {
// Optimistically update with upload in progress state
const optimisticUpdate = {
file_name: file.name,
content_type: file.type,
file_size: file.size,
updated_at: new Date().toISOString(),
fileName: file.name,
contentType: file.type,
fileSize: file.size,
updatedAt: new Date().toISOString(),
};
// Update individual document

View File

@@ -177,12 +177,12 @@ export const DocumentsMobileScreen: React.FC = () => {
{!isLoading && !hasError && data && data.length > 0 && (
<div className="space-y-3">
{data.map((doc) => {
const vehicleLabel = doc.vehicle_id ? `${doc.vehicle_id.slice(0, 8)}...` : '—';
const vehicleLabel = doc.vehicleId ? `${doc.vehicleId.slice(0, 8)}...` : '—';
return (
<div key={doc.id} className="flex items-center justify-between border rounded-xl p-3">
<div>
<div className="font-medium text-slate-800">{doc.title}</div>
<div className="text-xs text-slate-500">{doc.document_type} {vehicleLabel}</div>
<div className="text-xs text-slate-500">{doc.documentType} {vehicleLabel}</div>
</div>
<div className="flex gap-2 items-center">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>

View File

@@ -140,8 +140,8 @@ export const DocumentDetailPage: React.FC = () => {
<Card>
<div className="p-4 space-y-2">
<h2 className="text-xl font-semibold">{doc.title}</h2>
<div className="text-sm text-slate-500">Type: {doc.document_type}</div>
<div className="text-sm text-slate-500">Vehicle: {doc.vehicle_id}</div>
<div className="text-sm text-slate-500">Type: {doc.documentType}</div>
<div className="text-sm text-slate-500">Vehicle: {doc.vehicleId}</div>
<div className="pt-2">
<DocumentPreview doc={doc} />
</div>

View File

@@ -128,8 +128,8 @@ export const DocumentsPage: React.FC = () => {
<Card key={doc.id}>
<div className="p-4 space-y-2">
<div className="font-medium">{doc.title}</div>
<div className="text-sm text-slate-500">Type: {doc.document_type}</div>
<div className="text-sm text-slate-500">Vehicle: {doc.vehicle_id}</div>
<div className="text-sm text-slate-500">Type: {doc.documentType}</div>
<div className="text-sm text-slate-500">Vehicle: {doc.vehicleId}</div>
<div className="flex gap-2 pt-2">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>
<Button variant="danger" onClick={() => removeDoc.mutate(doc.id)}>Delete</Button>

View File

@@ -2,40 +2,43 @@ export type DocumentType = 'insurance' | 'registration';
export interface DocumentRecord {
id: string;
user_id: string;
vehicle_id: string;
document_type: DocumentType;
userId: string;
vehicleId: string;
documentType: DocumentType;
title: string;
notes?: string | null;
details?: Record<string, any> | null;
storage_bucket?: string | null;
storage_key?: string | null;
file_name?: string | null;
content_type?: string | null;
file_size?: number | null;
file_hash?: string | null;
issued_date?: string | null;
expiration_date?: string | null;
created_at: string;
updated_at: string;
deleted_at?: string | null;
storageBucket?: string | null;
storageKey?: string | null;
fileName?: string | null;
contentType?: string | null;
fileSize?: number | null;
fileHash?: string | null;
issuedDate?: string | null;
expirationDate?: string | null;
emailNotifications?: boolean;
createdAt: string;
updatedAt: string;
deletedAt?: string | null;
}
export interface CreateDocumentRequest {
vehicle_id: string;
document_type: DocumentType;
vehicleId: string;
documentType: DocumentType;
title: string;
notes?: string;
details?: Record<string, any>;
issued_date?: string;
expiration_date?: string;
issuedDate?: string;
expirationDate?: string;
emailNotifications?: boolean;
}
export interface UpdateDocumentRequest {
title?: string;
notes?: string | null;
details?: Record<string, any>;
issued_date?: string | null;
expiration_date?: string | null;
issuedDate?: string | null;
expirationDate?: string | null;
emailNotifications?: boolean;
}