Inbox: show who the enquiry came from and when it was received
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
24a28dce72
commit
46a462a0f4
@ -17,6 +17,8 @@ export interface ActivityResult { success?: boolean; message?: string; instance_
|
|||||||
export interface Enquiry {
|
export interface Enquiry {
|
||||||
instance_id: number;
|
instance_id: number;
|
||||||
current_state_name: string;
|
current_state_name: string;
|
||||||
|
created_at: string | null;
|
||||||
|
updated_at: string | null;
|
||||||
enquiry_ref: string | null;
|
enquiry_ref: string | null;
|
||||||
channel: string | null;
|
channel: string | null;
|
||||||
customer_contact: string | null;
|
customer_contact: string | null;
|
||||||
|
|||||||
@ -112,6 +112,7 @@ export function EnquiryPage() {
|
|||||||
{e.customer_contact && (e.channel === 'email' || e.customer_contact.includes('@')
|
{e.customer_contact && (e.channel === 'email' || e.customer_contact.includes('@')
|
||||||
? <span className="inline-flex items-center gap-1 text-sm text-muted"><Mail size={14} /> {e.customer_contact} · email</span>
|
? <span className="inline-flex items-center gap-1 text-sm text-muted"><Mail size={14} /> {e.customer_contact} · email</span>
|
||||||
: <span className="inline-flex items-center gap-1 text-sm text-muted"><MessageCircle size={14} /> +{e.customer_contact.replace(/^\+/, '')} · WhatsApp</span>)}
|
: <span className="inline-flex items-center gap-1 text-sm text-muted"><MessageCircle size={14} /> +{e.customer_contact.replace(/^\+/, '')} · WhatsApp</span>)}
|
||||||
|
{e.created_at && <span className="text-sm text-muted">Received {timeAgo(e.created_at)}</span>}
|
||||||
</div>
|
</div>
|
||||||
{e.ai_summary && <p className="text-muted">{e.ai_summary}</p>}
|
{e.ai_summary && <p className="text-muted">{e.ai_summary}</p>}
|
||||||
{e.assigned_trader && <p className="inline-flex items-center gap-1 text-sm text-muted"><User size={14} /> Trader on this enquiry: <span className="font-semibold text-ink">{e.assigned_trader}</span></p>}
|
{e.assigned_trader && <p className="inline-flex items-center gap-1 text-sm text-muted"><User size={14} /> Trader on this enquiry: <span className="font-semibold text-ink">{e.assigned_trader}</span></p>}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import { Mail, MessageCircle, Search } from 'lucide-react';
|
|||||||
import { useQuery, useZino } from '../api/provider';
|
import { useQuery, useZino } from '../api/provider';
|
||||||
import { RV_ENQUIRIES, STATES } from '../api/config';
|
import { RV_ENQUIRIES, STATES } from '../api/config';
|
||||||
import type { Enquiry } from '../api/types';
|
import type { Enquiry } from '../api/types';
|
||||||
import { Badge, Empty, ErrorNote, StateBadge, qtyText } from '../components/ui';
|
import { Badge, Empty, ErrorNote, StateBadge, qtyText, timeAgo } from '../components/ui';
|
||||||
|
|
||||||
/** Which enquiries are waiting on THIS user. */
|
/** Which enquiries are waiting on THIS user. */
|
||||||
function needsMe(e: Enquiry, has: (...r: string[]) => boolean): boolean {
|
function needsMe(e: Enquiry, has: (...r: string[]) => boolean): boolean {
|
||||||
@ -67,10 +67,10 @@ export function Inbox() {
|
|||||||
|
|
||||||
{error && <ErrorNote>{error}</ErrorNote>}
|
{error && <ErrorNote>{error}</ErrorNote>}
|
||||||
<div className="card overflow-x-auto">
|
<div className="card overflow-x-auto">
|
||||||
<table className="w-full min-w-[900px] text-sm">
|
<table className="w-full min-w-[1100px] text-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="border-b border-line bg-surface-2 text-left text-xs uppercase tracking-wide text-muted">
|
<tr className="border-b border-line bg-surface-2 text-left text-xs uppercase tracking-wide text-muted">
|
||||||
<th className="px-3 py-2">Reference</th><th className="px-3 py-2">Vessel</th><th className="px-3 py-2">Port</th>
|
<th className="px-3 py-2">Reference</th><th className="px-3 py-2">From</th><th className="px-3 py-2">Received</th><th className="px-3 py-2">Vessel</th><th className="px-3 py-2">Port</th>
|
||||||
<th className="px-3 py-2">ETA / Laycan</th><th className="px-3 py-2">Product</th><th className="px-3 py-2">Quantity</th>
|
<th className="px-3 py-2">ETA / Laycan</th><th className="px-3 py-2">Product</th><th className="px-3 py-2">Quantity</th>
|
||||||
<th className="px-3 py-2">Buyer</th><th className="px-3 py-2">Touch points</th><th className="px-3 py-2">Status</th>
|
<th className="px-3 py-2">Buyer</th><th className="px-3 py-2">Touch points</th><th className="px-3 py-2">Status</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -79,6 +79,8 @@ export function Inbox() {
|
|||||||
{shown.map((r) => (
|
{shown.map((r) => (
|
||||||
<tr key={r.instance_id} onClick={() => nav(`/enquiries/${r.instance_id}`)} className="cursor-pointer border-b border-line last:border-0 hover:bg-surface-2">
|
<tr key={r.instance_id} onClick={() => nav(`/enquiries/${r.instance_id}`)} className="cursor-pointer border-b border-line last:border-0 hover:bg-surface-2">
|
||||||
<td className="px-3 py-2.5 font-semibold text-accent"><span className="inline-flex items-center gap-1.5">{(r.customer_contact ?? '').includes('@') ? <Mail size={14} className="text-muted" /> : <MessageCircle size={14} className="text-muted" />}{r.enquiry_ref ?? `#${r.instance_id}`}</span></td>
|
<td className="px-3 py-2.5 font-semibold text-accent"><span className="inline-flex items-center gap-1.5">{(r.customer_contact ?? '').includes('@') ? <Mail size={14} className="text-muted" /> : <MessageCircle size={14} className="text-muted" />}{r.enquiry_ref ?? `#${r.instance_id}`}</span></td>
|
||||||
|
<td className="px-3 py-2.5 whitespace-nowrap">{r.customer_contact ?? '-'}<div className="text-xs text-muted">{(r.customer_contact ?? '').includes('@') ? 'Email' : 'WhatsApp'}</div></td>
|
||||||
|
<td className="px-3 py-2.5 whitespace-nowrap tabular-nums">{timeAgo(r.created_at) || '-'}{r.updated_at && r.updated_at !== r.created_at && <div className="text-xs text-muted">updated {timeAgo(r.updated_at)}</div>}</td>
|
||||||
<td className="px-3 py-2.5">{r.vessel_name ?? <span className="text-muted">-</span>}{r.imo_number && <div className="text-xs text-muted">IMO {r.imo_number}</div>}</td>
|
<td className="px-3 py-2.5">{r.vessel_name ?? <span className="text-muted">-</span>}{r.imo_number && <div className="text-xs text-muted">IMO {r.imo_number}</div>}</td>
|
||||||
<td className="px-3 py-2.5">{r.port ?? '-'}</td>
|
<td className="px-3 py-2.5">{r.port ?? '-'}</td>
|
||||||
<td className="px-3 py-2.5">{r.eta_laycan ?? '-'}</td>
|
<td className="px-3 py-2.5">{r.eta_laycan ?? '-'}</td>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user