aboutsummaryrefslogtreecommitdiff
path: root/web/src/components/tickets/TicketCard.tsx
diff options
context:
space:
mode:
authorzwlucas <lucas.fariamo08@gmail.com>2026-07-25 21:23:29 +0000
committerzwlucas <lucas.fariamo08@gmail.com>2026-07-25 21:23:29 +0000
commitef55d9bb24430610b60c1b77821307cd72c08c55 (patch)
treee6935a810b34370b0a4c821e55f6397aac50c832 /web/src/components/tickets/TicketCard.tsx
downloadhelpdesk-master.tar.gz
helpdesk-master.zip
feat: upload of the projectHEADmaster
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'web/src/components/tickets/TicketCard.tsx')
-rw-r--r--web/src/components/tickets/TicketCard.tsx66
1 files changed, 66 insertions, 0 deletions
diff --git a/web/src/components/tickets/TicketCard.tsx b/web/src/components/tickets/TicketCard.tsx
new file mode 100644
index 0000000..3b3926b
--- /dev/null
+++ b/web/src/components/tickets/TicketCard.tsx
@@ -0,0 +1,66 @@
+/**
+ * TicketCard.tsx
+ * Card de ticket para uso na lista do dashboard.
+ */
+
+import { useNavigate } from 'react-router-dom';
+import type { Ticket } from '@/lib/api';
+import { StatusBadge } from './StatusBadge';
+import { PriorityBadge } from './PriorityBadge';
+import styles from './TicketCard.module.css';
+
+interface TicketCardProps {
+ ticket: Ticket;
+}
+
+function formatDate(iso: string): string {
+ return new Intl.DateTimeFormat('pt-BR', {
+ day: '2-digit',
+ month: 'short',
+ hour: '2-digit',
+ minute: '2-digit',
+ }).format(new Date(iso));
+}
+
+export function TicketCard({ ticket }: TicketCardProps) {
+ const navigate = useNavigate();
+
+ return (
+ <article
+ className={`${styles.card} ${styles[`priority_${ticket.priority}`]}`}
+ onClick={() => navigate(`/tickets/${ticket.id}`)}
+ role="button"
+ tabIndex={0}
+ onKeyDown={(e) => e.key === 'Enter' && navigate(`/tickets/${ticket.id}`)}
+ aria-label={`Ticket #${ticket.id}: ${ticket.title}`}
+ >
+ <div className={styles.top}>
+ <div className={styles.badges}>
+ <StatusBadge status={ticket.status} />
+ <PriorityBadge priority={ticket.priority} />
+ </div>
+ <span className={styles.id}>#{ticket.id}</span>
+ </div>
+
+ <h3 className={styles.title}>{ticket.title}</h3>
+
+ <p className={styles.description}>{ticket.description}</p>
+
+ <div className={styles.footer}>
+ <span className={styles.meta}>
+ Aberto em {formatDate(ticket.createdAt)}
+ </span>
+ {ticket.assigneeId ? (
+ <span className={styles.assigned}>
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
+ <circle cx="12" cy="8" r="4" /><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7" />
+ </svg>
+ Agente #{ticket.assigneeId}
+ </span>
+ ) : (
+ <span className={styles.unassigned}>Sem agente</span>
+ )}
+ </div>
+ </article>
+ );
+}