freshyo/apps/web-ui/src/components/CheckoutAddressSelector.tsx
2026-05-10 19:44:26 +05:30

150 lines
5.9 KiB
TypeScript

import React from 'react'
import { useCheckoutAddress } from '../hooks/checkout-hooks'
import { trpc } from '../lib/trpc-client'
import { useQueryClient } from '@tanstack/react-query'
import { p, div } from 'web-components'
import { MapPin, Home, Briefcase, Check, Plus, Edit2, Trash2 } from 'lucide-react'
interface AddressSelectorProps {
onAddressSelect?: (addressId: number) => void
onAddAddress?: () => void
onEditAddress?: (address: any) => void
}
export function CheckoutAddressSelector({ onAddressSelect, onAddAddress, onEditAddress }: AddressSelectorProps) {
const {
sortedAddresses,
selectedAddressId,
handleAddressSelect,
} = useCheckoutAddress({ onAddressSelect })
const queryClient = useQueryClient()
const deleteMutation = trpc.user.address.deleteAddress.useMutation({
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user.address.getUserAddresses'] })
},
})
const getAddressIcon = (name: string) => {
const lower = name.toLowerCase()
if (lower.includes('home')) return <Home className="h-5 w-5" />
if (lower.includes('work')) return <Briefcase className="h-5 w-5" />
return <MapPin className="h-5 w-5" />
}
return (
<div className="mb-6">
<div className="mb-4 flex items-center justify-between">
<div className="flex items-center gap-2">
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-blue-50">
<MapPin className="h-4 w-4 text-blue-500" />
</div>
<p className="font-bold text-lg text-gray-900">
Delivery Address
</p>
</div>
<div
onClick={onAddAddress}
className="flex items-center gap-1 text-brand-500"
>
<Plus className="h-4 w-4" />
<p className="font-bold text-sm">
Add New
</p>
</div>
</div>
{sortedAddresses.length === 0 ? (
<div className="flex flex-col items-center justify-center rounded-xl border-2 border-dashed border-gray-200 bg-gray-50 p-8">
<MapPin className="mb-2 h-10 w-10 text-gray-400" />
<p className="mb-1 text-gray-500">No addresses found</p>
<div
onClick={onAddAddress}
className="mt-3 rounded-lg bg-brand-500 px-4 py-2"
>
<p className="font-bold text-sm text-white">
Add Address
</p>
</div>
</div>
) : (
<div className="space-y-3">
{sortedAddresses.map((address: any) => (
<div
key={address.id}
onClick={() => handleAddressSelect(address.id)}
className={`relative cursor-pointer rounded-xl border-2 p-4 transition-all ${
selectedAddressId === address.id
? 'border-brand-500 bg-blue-50'
: 'border-gray-200 bg-white hover:border-gray-300'
}`}
>
<div className="flex items-start justify-between">
<div className="flex items-start gap-3">
<div
className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-full ${
selectedAddressId === address.id ? 'bg-brand-500 text-white' : 'bg-gray-100 text-gray-500'
}`}
>
{getAddressIcon(address.name)}
</div>
<div className="min-w-0 flex-1">
<div className="mb-1 flex items-center gap-2">
<p className={`font-bold ${selectedAddressId === address.id ? 'text-brand-600' : 'text-gray-900'}`}>
{address.name}
</p>
{address.isDefault && (
<span className="rounded bg-green-100 px-2 py-0.5 text-xs font-medium text-green-700">
Default
</span>
)}
</div>
<p className="text-sm leading-relaxed text-gray-600">
{address.addressLine1}
{address.addressLine2 ? `, ${address.addressLine2}` : ''}
</p>
<p className="text-sm text-gray-600">
{address.city}, {address.state} - {address.pincode}
</p>
<p className="mt-1 text-xs text-gray-500">
Phone: {address.phone}
</p>
</div>
</div>
<div className="flex flex-col items-end gap-2">
{selectedAddressId === address.id && (
<div className="flex h-6 w-6 items-center justify-center rounded-full bg-brand-500">
<Check className="h-4 w-4 text-white" />
</div>
)}
<div className="flex gap-1">
<div
onClick={(e) => {
e.stopPropagation()
onEditAddress?.(address)
}}
className="flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600"
>
<Edit2 className="h-4 w-4" />
</div>
<div
onClick={(e) => {
e.stopPropagation()
if (confirm('Are you sure you want to delete this address?')) {
deleteMutation.mutate({ id: address.id })
}
}}
className="flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-red-50 hover:text-red-500"
>
<Trash2 className="h-4 w-4" />
</div>
</div>
</div>
</div>
</div>
))}
</div>
)}
</div>
)
}