Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | "use client";
import React from "react";
import { Icon } from "@/components/ui/icons";
import { Address } from "@/types/user";
import { Button } from "@/components/ui";
interface AddressCardProps {
address: Address;
onEdit: () => void;
onSetDefault?: () => void;
onDelete?: () => void;
showActions?: boolean;
}
export default function AddressCard({
address,
onEdit,
onSetDefault,
onDelete,
showActions = true}: AddressCardProps) {
return (
<div className="bg-white dark:bg-gray-800 shadow-1 rounded-xl p-5 relative">
{/* Default Badge */}
{address.isDefault && (
<span className="absolute top-3 right-3 px-2 py-1 text-xs font-medium bg-blue text-white rounded-full">
Default
</span>
)}
{/* Contact Info */}
<div className="mb-4">
<h4 className="font-medium text-dark dark:text-white text-lg mb-1">
{address.name || "No name"}
</h4>
{address.email && (
<p className="text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5">
<Icon name="email" size={14} className="fill-current" />
{address.email}
</p>
)}
{address.phone && (
<p className="text-sm text-gray-600 dark:text-gray-400 flex items-center gap-1.5">
<Icon name="phone" size={14} className="fill-current" />
{address.phone}
</p>
)}
</div>
{/* Divider */}
<div className="border-t border-gray-200 dark:border-gray-700 my-3" />
{/* Address */}
<div className="text-sm text-dark dark:text-gray-300">
<p>{address.street}</p>
<p>
{address.city}, {address.state} {address.zipCode}
</p>
<p>{address.country}</p>
</div>
{/* Actions */}
{showActions && (
<div className="flex items-center gap-2 mt-4 pt-3 border-t border-gray-200 dark:border-gray-700">
<Button
variant="ghost"
size="sm"
onClick={onEdit}
className="text-blue hover:bg-blue/10"
>
<Icon name="edit" size={16} className="mr-1" />
Edit
</Button>
{!address.isDefault && onSetDefault && (
<Button
variant="ghost"
size="sm"
onClick={onSetDefault}
className="text-green hover:bg-green/10"
>
<Icon name="check" size={16} className="mr-1" />
Set Default
</Button>
)}
{onDelete && (
<Button
variant="ghost"
size="sm"
onClick={onDelete}
className="text-red hover:bg-red/10 ml-auto"
>
<Icon name="trash" size={16} className="mr-1" />
Delete
</Button>
)}
</div>
)}
</div>
);
}
// Empty state card for when there are no addresses
interface EmptyAddressCardProps {
type: "SHIPPING" | "BILLING";
onAdd: () => void;
}
export function EmptyAddressCard({ type, onAdd }: EmptyAddressCardProps) {
const title = type === "SHIPPING" ? "Shipping" : "Billing";
return (
<div className="bg-white dark:bg-gray-800 shadow-1 rounded-xl p-6 text-center border-2 border-dashed border-gray-300 dark:border-gray-600">
<Icon
name="map-pin"
size={32}
className="mx-auto mb-3 text-gray-400 dark:text-gray-500"
/>
<p className="text-gray-600 dark:text-gray-400 mb-4">
No {title.toLowerCase()} address added yet
</p>
<Button variant="primary" size="sm" onClick={onAdd}>
<Icon name="plus" size={16} className="mr-1" />
Add {title} Address
</Button>
</div>
);
}
|