add sales visits ui
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
} from '@/components/ui/dialog'
|
||||
import { toast } from '@/components/ui/toast'
|
||||
import { stores as storesApi } from '@/lib/api/index'
|
||||
import type { StoreResponse, StoreVisitHistoryItem } from '@/types/api'
|
||||
|
||||
interface StoreVisitHistorySheetProps {
|
||||
open: boolean
|
||||
onClose: () => void
|
||||
store: StoreResponse | null
|
||||
}
|
||||
|
||||
export function StoreVisitHistorySheet({ open, onClose, store }: StoreVisitHistorySheetProps) {
|
||||
const [visits, setVisits] = useState<StoreVisitHistoryItem[] | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || !store) return
|
||||
setVisits(null)
|
||||
storesApi.visitHistory(store.id)
|
||||
.then(setVisits)
|
||||
.catch(() => toast.add({ title: 'Failed to load visit history', type: 'error' }))
|
||||
}, [open, store])
|
||||
|
||||
if (!store) return null
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(v) => !v && onClose()}>
|
||||
<DialogContent className="overflow-y-auto sm:max-w-lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Visit History — {store.storeName}</DialogTitle>
|
||||
<DialogDescription>
|
||||
Check-ins and check-outs logged against this store.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
{visits === null ? (
|
||||
<p className="text-sm text-muted-foreground">Loading…</p>
|
||||
) : visits.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">No visits logged yet.</p>
|
||||
) : (
|
||||
<ul className="flex flex-col gap-2">
|
||||
{visits.map((v) => (
|
||||
<li key={v.visitId} className="flex items-center justify-between rounded-md border p-2 text-sm">
|
||||
<span>
|
||||
{new Date(v.visitDate).toLocaleString('en-GB', {
|
||||
day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit',
|
||||
})}
|
||||
</span>
|
||||
<Badge variant={v.outcome === 'Completed' ? 'default' : 'secondary'}>
|
||||
{v.outcome}
|
||||
</Badge>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import { stores as storesApi, getApiError, getPaginatedItems } from '@/lib/api/i
|
||||
import type { StoreResponse, KycStatus } from '@/types/api'
|
||||
|
||||
import { StoreSheet } from './store-sheet'
|
||||
import { StoreVisitHistorySheet } from './store-visit-history-sheet'
|
||||
|
||||
function kycBadgeVariant(status: KycStatus): 'default' | 'secondary' | 'destructive' {
|
||||
if (status === 'Verified') return 'default'
|
||||
@@ -29,6 +30,8 @@ export function StoresClient() {
|
||||
|
||||
const [sheetOpen, setSheetOpen] = useState(false)
|
||||
const [editing, setEditing] = useState<StoreResponse | null>(null)
|
||||
const [historyOpen, setHistoryOpen] = useState(false)
|
||||
const [viewingHistory, setViewingHistory] = useState<StoreResponse | null>(null)
|
||||
|
||||
const fetchData = useCallback(async (p: number, ps: number) => {
|
||||
setLoading(true)
|
||||
@@ -57,6 +60,11 @@ export function StoresClient() {
|
||||
setSheetOpen(true)
|
||||
}
|
||||
|
||||
function openHistory(store: StoreResponse) {
|
||||
setViewingHistory(store)
|
||||
setHistoryOpen(true)
|
||||
}
|
||||
|
||||
async function toggleActive(store: StoreResponse) {
|
||||
try {
|
||||
await storesApi.update(store.id, { isActive: !store.isActive })
|
||||
@@ -125,6 +133,11 @@ export function StoresClient() {
|
||||
label: 'Edit store',
|
||||
onClick: openEdit,
|
||||
},
|
||||
{
|
||||
action: 'confirm',
|
||||
label: 'View visit history',
|
||||
onClick: openHistory,
|
||||
},
|
||||
{
|
||||
action: 'deactivate',
|
||||
label: 'Deactivate store',
|
||||
@@ -139,7 +152,7 @@ export function StoresClient() {
|
||||
},
|
||||
],
|
||||
},
|
||||
}), [pageSize, openEdit, toggleActive])
|
||||
}), [pageSize, openEdit, openHistory, toggleActive])
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -173,6 +186,12 @@ export function StoresClient() {
|
||||
store={editing}
|
||||
onSuccess={() => fetchData(page, pageSize)}
|
||||
/>
|
||||
|
||||
<StoreVisitHistorySheet
|
||||
open={historyOpen}
|
||||
onClose={() => setHistoryOpen(false)}
|
||||
store={viewingHistory}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user