refactor(ui): update branding assets and clean up repair proof UI

This commit is contained in:
2026-07-22 18:47:00 +05:30
parent 725c256791
commit 062e89fcba
7 changed files with 35 additions and 163 deletions

View File

@@ -1,13 +1,7 @@
'use client';
import { useEffect, useMemo, useState } from 'react';
import {
AlertTriangle,
ChevronLeft,
ChevronRight,
ImageIcon,
Trash2,
} from 'lucide-react';
import { AlertTriangle, ChevronLeft, ChevronRight, Trash2 } from 'lucide-react';
import DetectionLocationMap from '@/components/map/detectionLocationMap';
import { Badge } from '@/components/ui/badge';
@@ -16,15 +10,12 @@ import { Skeleton } from '@/components/ui/skeleton';
import AnnotatedDetectionImage from '@/components/video/annotatedDetectionImage';
import { getDefectVisual } from '@/constants/defectVisualConfig';
import { cn } from '@/lib/utils';
import type { DetectionRepairProof } from '@/types';
import {
useDiscardDetectionMutation,
useTicketClassDetectionsQuery,
} from '../../hooks/useTicketQueries';
import { DetectionDiscardDialog } from './DetectionDiscardDialog';
import { RepairProofGallery } from './repair/RepairProofGallery';
import { RepairSubmittedBanner } from './repair/RepairSubmittedBanner';
interface TicketClassDetectionPreviewProps {
ticketId: string;
@@ -63,44 +54,6 @@ function DetectionMetadataBar({
);
}
function DetectionRepairProofPanel({
repairProof,
}: {
repairProof: DetectionRepairProof;
}) {
if (!repairProof.submitted) {
return null;
}
return (
<section className="space-y-4 rounded-lg border bg-muted/20 p-4">
<div className="flex items-center gap-2">
<ImageIcon className="size-5 text-primary" />
<h4 className="font-semibold">Repair Proof</h4>
</div>
{repairProof.submitted_at ? (
<RepairSubmittedBanner
submittedAt={repairProof.submitted_at}
submitterName="Ticket Worker"
/>
) : null}
<RepairProofGallery
imageUrls={repairProof.proof_image_urls}
maxVisibleImages={4}
/>
<div className="space-y-1.5">
<p className="text-xs font-semibold text-foreground">Repair Notes</p>
<p className="text-sm leading-relaxed whitespace-pre-wrap text-muted-foreground">
{repairProof.notes?.trim() || 'No repair notes provided.'}
</p>
</div>
</section>
);
}
function TicketClassDetectionPreviewSkeleton() {
return (
<>
@@ -330,12 +283,6 @@ export function TicketClassDetectionPreview({
]}
/>
{activeDetection.repair_proof ? (
<DetectionRepairProofPanel
repairProof={activeDetection.repair_proof}
/>
) : null}
<div className="flex justify-end">
<Button
type="button"

View File

@@ -1,27 +0,0 @@
import { CheckCircle2 } from 'lucide-react';
import { formatDate } from '@/utils/date';
interface RepairSubmittedBannerProps {
submittedAt: string;
submitterName: string;
}
export function RepairSubmittedBanner({
submittedAt,
submitterName,
}: RepairSubmittedBannerProps) {
return (
<div className="flex items-start gap-3 rounded-lg border border-emerald-200 bg-emerald-50 px-3 py-3 dark:border-emerald-900/60 dark:bg-emerald-950/30">
<CheckCircle2 className="mt-0.5 size-5 shrink-0 text-emerald-600 dark:text-emerald-400" />
<div className="min-w-0 space-y-0.5">
<p className="text-sm font-semibold text-emerald-800 dark:text-emerald-200">
Repair Submitted
</p>
<p className="text-xs text-emerald-700/80 dark:text-emerald-300/80">
{formatDate(submittedAt)} by {submitterName}
</p>
</div>
</div>
);
}

View File

@@ -1,57 +0,0 @@
import Image from 'next/image';
import { cn } from '@/lib/utils';
const sizeClasses = {
sm: 'size-8 rounded-lg border-2 p-0.5',
md: 'size-12 rounded-lg border-2 p-1.5',
lg: 'size-28 rounded-lg border-[5px] p-3',
} as const;
const variantClasses = {
default: 'border-white bg-primary shadow-md',
solid: 'border-white bg-primary',
glass: 'border-primary-foreground bg-primary/85 shadow-md',
sidebar: 'border-0 bg-primary',
} as const;
type LogoWrapperProps = {
alt?: string;
className?: string;
imageClassName?: string;
priority?: boolean;
size?: keyof typeof sizeClasses;
variant?: keyof typeof variantClasses;
};
export function LogoWrapper({
alt = 'RoadMonitor logo',
className,
imageClassName,
priority = false,
size = 'md',
variant = 'default',
}: LogoWrapperProps) {
return (
<span
className={cn(
'inline-flex shrink-0 items-center justify-center',
sizeClasses[size],
variantClasses[variant],
className,
)}
>
<Image
src="/logo.png"
alt={alt}
width={112}
height={112}
className={cn(
'size-full object-contain brightness-0 invert',
imageClassName,
)}
priority={priority}
/>
</span>
);
}

View File

@@ -1,7 +1,7 @@
'use client';
import * as React from 'react';
import { ChevronRight } from 'lucide-react';
import { LogoWrapper } from '@/components/LogoWrapper';
import Image from 'next/image';
import { NavUser } from '@/components/nav-user';
import {
filterMenuItems,
@@ -97,10 +97,13 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
function SidebarBrandControl({ isMobile }: { isMobile: boolean }) {
return (
<div className="group/sidebar-brand relative flex size-8 shrink-0 items-center justify-center">
<LogoWrapper
size="sm"
variant="sidebar"
className="transition-opacity duration-150 group-data-[collapsible=icon]:group-hover/sidebar-brand:opacity-0 group-data-[collapsible=icon]:group-focus-within/sidebar-brand:opacity-0"
<Image
src="/color_logo.svg"
alt="RoadMonitor logo"
width={81}
height={58}
className="h-auto w-10 transition-opacity duration-150 group-data-[collapsible=icon]:group-hover/sidebar-brand:opacity-0 group-data-[collapsible=icon]:group-focus-within/sidebar-brand:opacity-0"
priority
/>
<Tooltip>
<TooltipTrigger asChild>

View File

@@ -1,5 +1,5 @@
import { LogoWrapper } from '@/components/LogoWrapper';
import { cn } from '@/lib/utils';
import Image from 'next/image';
const BOKEH_ORBS = [
'top-[20%] left-[10%] size-[min(18vw,140px)] opacity-[0.14]',
@@ -82,24 +82,21 @@ export function AuthBackground({ className }: AuthBackgroundProps) {
/>
))}
<div className="absolute inset-x-10 top-1/2 -translate-y-1/2 text-center text-primary-foreground">
<div className="mb-9 inline-flex items-center gap-5 text-left">
<LogoWrapper
alt=""
className="size-28 rounded-lg border-[5px] p-4"
priority
variant="glass"
/>
<span className="min-w-0">
<span className="block text-5xl font-semibold leading-none tracking-normal">
Road
</span>
<span className="block text-5xl font-semibold leading-none tracking-normal">
Monitor
</span>
</span>
</div>
<p className="mx-auto max-w-md text-base leading-7 text-primary-foreground/82">
<Image
src="/logo.svg"
alt=""
width={81}
height={58}
className="absolute left-10 top-12 h-auto w-16 object-contain"
priority
/>
<div className="absolute bottom-10 left-10 right-10 text-left text-primary-foreground">
<p className="text-3xl leading-none tracking-tight">
<span className="font-semibold">Road</span>
<span className="font-normal">Monitor</span>
</p>
<p className="mt-1 max-w-sm text-xs leading-4 text-primary-foreground/90">
Map, monitor, and repair road issues with data-driven surface
intelligence.
</p>
@@ -107,4 +104,3 @@ export function AuthBackground({ className }: AuthBackgroundProps) {
</div>
);
}