import { useState } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import { usePOSStore } from '@/stores/pos.store' import { api } from '@/lib/api-client' import { posMutations, posKeys } from '@/api/pos' import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Textarea } from '@/components/ui/textarea' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' import { Search, Wrench, Plus } from 'lucide-react' import { toast } from 'sonner' interface Account { id: string name: string email: string | null phone: string | null accountNumber: string | null } interface RepairTicketSummary { id: string ticketNumber: string | null customerName: string customerPhone: string | null itemDescription: string | null estimatedCost: string | null status: string } interface POSRepairDialogProps { open: boolean onOpenChange: (open: boolean) => void } export function POSRepairDialog({ open, onOpenChange }: POSRepairDialogProps) { const queryClient = useQueryClient() const { locationId, setTransaction, setAccount } = usePOSStore() const [search, setSearch] = useState('') const [tab, setTab] = useState('pickup') // --- Pickup tab --- const { data, isLoading } = useQuery({ queryKey: ['pos', 'repair-tickets-ready', search], queryFn: () => api.get<{ data: RepairTicketSummary[] }>('/v1/repair-tickets/ready', { q: search || undefined, limit: 20 }), enabled: open && tab === 'pickup', }) const tickets = data?.data ?? [] const pickupMutation = useMutation({ mutationFn: (ticketId: string) => posMutations.createFromRepair(ticketId, locationId ?? undefined), onSuccess: (txn) => { setTransaction(txn.id) if (txn.accountId) { const ticket = tickets.find((t) => t.id === pickupMutation.variables) if (ticket) setAccount(txn.accountId, ticket.customerName, ticket.customerPhone) } queryClient.invalidateQueries({ queryKey: posKeys.transaction(txn.id) }) toast.success(`Repair payment loaded — ${txn.transactionNumber}`) close() }, onError: (err) => toast.error(err.message), }) // --- New intake tab --- const [customerName, setCustomerName] = useState('') const [customerPhone, setCustomerPhone] = useState('') const [itemDescription, setItemDescription] = useState('') const [problemDescription, setProblemDescription] = useState('') const [estimatedCost, setEstimatedCost] = useState('') const [accountId, setAccountId] = useState(null) const [customerSearch, setCustomerSearch] = useState('') const [showCustomers, setShowCustomers] = useState(false) const { data: customerData } = useQuery({ queryKey: ['pos', 'accounts', customerSearch], queryFn: () => api.get<{ data: Account[] }>('/v1/accounts', { q: customerSearch, limit: 10 }), enabled: customerSearch.length >= 2 && tab === 'intake', }) const customerResults = customerData?.data ?? [] function selectCustomer(account: Account) { setAccountId(account.id) setCustomerName(account.name) setCustomerPhone(account.phone ?? '') setCustomerSearch('') setShowCustomers(false) } function clearCustomer() { setAccountId(null) setCustomerName('') setCustomerPhone('') } const intakeMutation = useMutation({ mutationFn: (data: Record) => api.post<{ id: string; ticketNumber: string }>('/v1/repair-tickets', data), onSuccess: (ticket) => { toast.success(`Repair ticket #${ticket.ticketNumber} created`) close() }, onError: (err) => toast.error(err.message), }) function handleIntakeSubmit(e: React.FormEvent) { e.preventDefault() intakeMutation.mutate({ customerName, customerPhone: customerPhone || undefined, accountId: accountId ?? undefined, itemDescription: itemDescription || undefined, problemDescription, estimatedCost: estimatedCost ? parseFloat(estimatedCost) : undefined, locationId: locationId ?? undefined, }) } function close() { onOpenChange(false) setSearch('') setCustomerName('') setCustomerPhone('') setItemDescription('') setProblemDescription('') setEstimatedCost('') setAccountId(null) setCustomerSearch('') setShowCustomers(false) } return ( { if (!o) close(); else onOpenChange(true) }}> Repairs Pickup New Intake
setSearch(e.target.value)} className="pl-9" autoFocus={tab === 'pickup'} />
{isLoading ? (

Loading...

) : tickets.length === 0 ? (

{search ? 'No ready tickets found' : 'No tickets ready for pickup'}

) : ( tickets.map((ticket) => ( )) )}
{/* Customer lookup */}
{ setCustomerSearch(e.target.value); setShowCustomers(true) }} onFocus={() => customerSearch.length >= 2 && setShowCustomers(true)} className="pl-9 h-8 text-sm" />
{accountId && (
Linked {customerName}
)} {showCustomers && customerSearch.length >= 2 && (
{customerResults.length === 0 ? (
No accounts found
) : customerResults.map((a) => ( ))}
)}
setCustomerName(e.target.value)} required />
setCustomerPhone(e.target.value)} />
setItemDescription(e.target.value)} placeholder="e.g. Violin, iPhone 12, Trek bicycle" />