feat(ui): add ticket attention badges and sharpen border radius
This commit is contained in:
@@ -2,11 +2,48 @@
|
|||||||
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
|
import { CalendarClock, ClipboardCheck } from 'lucide-react';
|
||||||
|
|
||||||
|
import { Badge } from '@/components/ui/badge';
|
||||||
import type { TicketListItem } from '@/types';
|
import type { TicketListItem } from '@/types';
|
||||||
|
|
||||||
import { formatDate } from '@/utils/date';
|
import { formatDate } from '@/utils/date';
|
||||||
|
|
||||||
|
function TicketAttention({ ticket }: { ticket: TicketListItem }) {
|
||||||
|
const summary = ticket.attention_summary;
|
||||||
|
const reviewCount = summary?.pending_repair_review_count ?? 0;
|
||||||
|
const extensionCount = summary?.pending_extension_request_count ?? 0;
|
||||||
|
const showReview = reviewCount > 0;
|
||||||
|
const showExtension = extensionCount > 0;
|
||||||
|
|
||||||
|
if (!showReview && !showExtension) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap items-center gap-1.5">
|
||||||
|
{showReview ? (
|
||||||
|
<Badge
|
||||||
|
className="gap-1.5 border-0 bg-orange-100 text-orange-700 shadow-none dark:bg-orange-950/60 dark:text-orange-300"
|
||||||
|
title={`${reviewCount} pending repair ${reviewCount === 1 ? 'review' : 'reviews'}`}
|
||||||
|
>
|
||||||
|
<ClipboardCheck aria-hidden="true" />
|
||||||
|
Review
|
||||||
|
<span className="font-semibold tabular-nums">{reviewCount}</span>
|
||||||
|
</Badge>
|
||||||
|
) : null}
|
||||||
|
{showExtension ? (
|
||||||
|
<Badge
|
||||||
|
className="gap-1.5 border-0 bg-blue-100 text-blue-700 shadow-none dark:bg-blue-950/60 dark:text-blue-300"
|
||||||
|
title={`${extensionCount} pending extension ${extensionCount === 1 ? 'request' : 'requests'}`}
|
||||||
|
>
|
||||||
|
<CalendarClock aria-hidden="true" />
|
||||||
|
Extension
|
||||||
|
<span className="font-semibold tabular-nums">+{extensionCount}</span>
|
||||||
|
</Badge>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function useTicketColumns(): ColumnDef<TicketListItem>[] {
|
export function useTicketColumns(): ColumnDef<TicketListItem>[] {
|
||||||
return useMemo(
|
return useMemo(
|
||||||
() => [
|
() => [
|
||||||
@@ -29,6 +66,13 @@ export function useTicketColumns(): ColumnDef<TicketListItem>[] {
|
|||||||
header: 'Detections',
|
header: 'Detections',
|
||||||
size: 120,
|
size: 120,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'attention',
|
||||||
|
header: 'Attention',
|
||||||
|
size: 210,
|
||||||
|
meta: { disableTruncate: true },
|
||||||
|
cell: ({ row }) => <TicketAttention ticket={row.original} />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'created_by',
|
id: 'created_by',
|
||||||
header: 'Uploaded By',
|
header: 'Uploaded By',
|
||||||
|
|||||||
@@ -103,6 +103,12 @@ function buildTicketListItem(
|
|||||||
created_by_email: event.created_by_email ?? null,
|
created_by_email: event.created_by_email ?? null,
|
||||||
created_at: event.created_at ?? event.updated_at,
|
created_at: event.created_at ?? event.updated_at,
|
||||||
updated_at: event.updated_at,
|
updated_at: event.updated_at,
|
||||||
|
attention_summary: event.attention_summary ?? {
|
||||||
|
has_pending_extension_request: false,
|
||||||
|
pending_extension_request_count: 0,
|
||||||
|
has_pending_repair_review: false,
|
||||||
|
pending_repair_review_count: 0,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,6 +128,7 @@ function mergeTicketListItem(
|
|||||||
created_by_email: event.created_by_email ?? current.created_by_email,
|
created_by_email: event.created_by_email ?? current.created_by_email,
|
||||||
created_at: event.created_at ?? current.created_at,
|
created_at: event.created_at ?? current.created_at,
|
||||||
updated_at: event.updated_at ?? current.updated_at,
|
updated_at: event.updated_at ?? current.updated_at,
|
||||||
|
attention_summary: event.attention_summary ?? current.attention_summary,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
@custom-variant dark (&:is(.dark *));
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.5rem;
|
--radius: 0.1rem;
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(1 0 0);
|
||||||
--card-foreground: oklch(0.145 0 0);
|
--card-foreground: oklch(0.145 0 0);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1 0 0);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { TicketStatus } from './status';
|
import type { TicketStatus } from './status';
|
||||||
|
import type { TicketAttentionSummary } from './list';
|
||||||
|
|
||||||
export interface SseTokenResponse {
|
export interface SseTokenResponse {
|
||||||
sse_token: string;
|
sse_token: string;
|
||||||
@@ -18,6 +19,7 @@ export type TicketTableStatusEvent = {
|
|||||||
created_by_email?: string | null;
|
created_by_email?: string | null;
|
||||||
created_at?: string;
|
created_at?: string;
|
||||||
updated_at?: string;
|
updated_at?: string;
|
||||||
|
attention_summary?: TicketAttentionSummary;
|
||||||
message?: string;
|
message?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,13 @@ export interface TicketListParams extends PaginationParams {
|
|||||||
chainage_id?: string;
|
chainage_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TicketAttentionSummary {
|
||||||
|
has_pending_extension_request: boolean;
|
||||||
|
pending_extension_request_count: number;
|
||||||
|
has_pending_repair_review: boolean;
|
||||||
|
pending_repair_review_count: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface TicketListItem {
|
export interface TicketListItem {
|
||||||
id: string;
|
id: string;
|
||||||
ticket_name: string;
|
ticket_name: string;
|
||||||
@@ -15,6 +22,7 @@ export interface TicketListItem {
|
|||||||
created_by_email: string | null;
|
created_by_email: string | null;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
|
attention_summary: TicketAttentionSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TicketListResponse {
|
export interface TicketListResponse {
|
||||||
|
|||||||
Reference in New Issue
Block a user