97 lines
3.5 KiB
TypeScript
97 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { SubCard } from "@/components/molecules/SubCard";
|
|
import { MapPinIcon, PencilIcon, CheckIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
|
import { AddressForm, type Address, type AddressFormProps } from "@/features/catalog/components";
|
|
|
|
interface AddressCardProps {
|
|
address: Address;
|
|
isEditing: boolean;
|
|
isSaving: boolean;
|
|
error?: string | null;
|
|
onEdit: () => void;
|
|
onCancel: () => void;
|
|
onSave: () => void;
|
|
onAddressChange: NonNullable<AddressFormProps["onChange"]>;
|
|
}
|
|
|
|
export function AddressCard({
|
|
address,
|
|
isEditing,
|
|
isSaving,
|
|
error,
|
|
onEdit,
|
|
onCancel,
|
|
onSave,
|
|
onAddressChange,
|
|
}: AddressCardProps) {
|
|
return (
|
|
<SubCard>
|
|
<div className="pb-5 border-b border-gray-200">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center space-x-3">
|
|
<MapPinIcon className="h-6 w-6 text-blue-600" />
|
|
<h2 className="text-xl font-semibold text-gray-900">Address Information</h2>
|
|
</div>
|
|
{!isEditing && (
|
|
<button
|
|
onClick={onEdit}
|
|
className="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-lg text-gray-700 bg-white hover:bg-gray-50 transition-colors"
|
|
>
|
|
<PencilIcon className="h-4 w-4 mr-2" />
|
|
Edit
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="pt-5">
|
|
{isEditing ? (
|
|
<div className="space-y-6">
|
|
<AddressForm initialAddress={address} onChange={addr => onAddressChange(addr, true)} />
|
|
{error && <div className="text-sm text-red-600">{error}</div>}
|
|
<div className="flex items-center justify-end space-x-3 pt-4 border-t border-gray-200">
|
|
<button
|
|
onClick={onCancel}
|
|
disabled={isSaving}
|
|
className="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-lg text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50 transition-colors"
|
|
>
|
|
<XMarkIcon className="h-4 w-4 mr-2" />
|
|
Cancel
|
|
</button>
|
|
<button
|
|
onClick={onSave}
|
|
disabled={isSaving}
|
|
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-lg text-white bg-blue-600 hover:bg-blue-700 disabled:opacity-50 transition-colors"
|
|
>
|
|
{isSaving ? (
|
|
<>
|
|
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
|
|
Saving...
|
|
</>
|
|
) : (
|
|
<>
|
|
<CheckIcon className="h-4 w-4 mr-2" />
|
|
Save Address
|
|
</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-1 text-gray-900">
|
|
{address.street && <p className="font-semibold text-base">{address.street}</p>}
|
|
{address.streetLine2 && <p className="text-gray-700">{address.streetLine2}</p>}
|
|
{(address.city || address.state || address.postalCode) && (
|
|
<p className="text-gray-700">
|
|
{[address.city, address.state, address.postalCode].filter(Boolean).join(", ")}
|
|
</p>
|
|
)}
|
|
{address.country && <p className="text-gray-600 font-medium">{address.country}</p>}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</SubCard>
|
|
);
|
|
}
|