feat: customer lookup from POS with order history and item search
- Customer dialog in cart panel: search accounts by name, phone, email, account # - Selected customer shown with name, phone, email in cart header - accountId passed when creating transactions - Order history view: tap a transaction to expand and see line items - Item search in history (e.g. "strings") — filters orders containing that item - Backend: add accountId and itemSearch filters to transaction list endpoint - itemSearch uses EXISTS subquery on line item descriptions (ILIKE) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,10 +3,11 @@ import { usePOSStore } from '@/stores/pos.store'
|
||||
import { posMutations, posKeys, type Transaction } from '@/api/pos'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { X, Banknote, CreditCard, FileText, Ban } from 'lucide-react'
|
||||
import { X, Banknote, CreditCard, FileText, Ban, UserRound } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import { useState } from 'react'
|
||||
import { POSPaymentDialog } from './pos-payment-dialog'
|
||||
import { POSCustomerDialog } from './pos-customer-dialog'
|
||||
|
||||
interface POSCartPanelProps {
|
||||
transaction: Transaction | null
|
||||
@@ -14,8 +15,9 @@ interface POSCartPanelProps {
|
||||
|
||||
export function POSCartPanel({ transaction }: POSCartPanelProps) {
|
||||
const queryClient = useQueryClient()
|
||||
const { currentTransactionId, setTransaction } = usePOSStore()
|
||||
const { currentTransactionId, setTransaction, accountName, accountPhone, accountEmail } = usePOSStore()
|
||||
const [paymentMethod, setPaymentMethod] = useState<string | null>(null)
|
||||
const [customerOpen, setCustomerOpen] = useState(false)
|
||||
const lineItems = transaction?.lineItems ?? []
|
||||
|
||||
const drawerSessionId = usePOSStore((s) => s.drawerSessionId)
|
||||
@@ -63,6 +65,24 @@ export function POSCartPanel({ transaction }: POSCartPanelProps) {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setCustomerOpen(true)}
|
||||
className="flex items-start gap-1.5 mt-1 text-xs text-muted-foreground hover:text-foreground text-left"
|
||||
>
|
||||
<UserRound className="h-3 w-3 mt-0.5 shrink-0" />
|
||||
{accountName ? (
|
||||
<span>
|
||||
<span className="font-medium text-foreground">{accountName}</span>
|
||||
{(accountPhone || accountEmail) && (
|
||||
<span className="block text-[11px]">
|
||||
{[accountPhone, accountEmail].filter(Boolean).join(' · ')}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
) : (
|
||||
<span>Walk-in — tap to add customer</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Line items */}
|
||||
@@ -182,6 +202,9 @@ export function POSCartPanel({ transaction }: POSCartPanelProps) {
|
||||
onComplete={handlePaymentComplete}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Customer dialog */}
|
||||
<POSCustomerDialog open={customerOpen} onOpenChange={setCustomerOpen} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user