Skip to content

Commit 56e2b2b

Browse files
committed
better card
1 parent 10ccab6 commit 56e2b2b

File tree

1 file changed

+111
-55
lines changed

1 file changed

+111
-55
lines changed

apps/dashboard/app/(main)/billing/components/credit-card-display.tsx

Lines changed: 111 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function CreditCardDisplay({ customer }: CreditCardDisplayProps) {
2020

2121
if (!card) {
2222
return (
23-
<div className="flex aspect-[1.586/1] w-full flex-col items-center justify-center rounded-xl border border-dashed bg-background">
23+
<div className="flex aspect-[1.586/1] w-full flex-col items-center justify-center rounded border border-dashed bg-muted/30">
2424
<CreditCardIcon
2525
className="mb-2 text-muted-foreground"
2626
size={28}
@@ -41,68 +41,124 @@ export function CreditCardDisplay({ customer }: CreditCardDisplayProps) {
4141
const brand = (card.brand || "card").toLowerCase();
4242

4343
return (
44-
<div className="relative aspect-[1.586/1] w-full">
44+
<div className="relative aspect-[1.586/1] w-full select-none">
45+
{/* Card base */}
4546
<div
4647
className={cn(
47-
"absolute inset-0 flex flex-col justify-between overflow-hidden rounded-xl p-4",
48-
"bg-linear-to-tr from-foreground to-foreground/80 dark:from-zinc-800 dark:to-zinc-900",
49-
"before:pointer-events-none before:absolute before:inset-0 before:z-1 before:rounded-[inherit] before:ring-1 before:ring-white/20 before:ring-inset"
48+
"absolute inset-0 flex flex-col justify-between overflow-hidden rounded p-4",
49+
"bg-[#0a0a0a]",
50+
"ring-1 ring-white/[0.06] ring-inset"
5051
)}
5152
>
52-
<div className="relative z-2 flex items-start justify-between">
53-
<WifiHighIcon
54-
className="rotate-90 text-white/80"
55-
size={20}
56-
weight="bold"
57-
/>
58-
<span className="font-semibold text-white/60 text-xs uppercase tracking-wider">
53+
{/* Holographic strip */}
54+
<div
55+
className="pointer-events-none absolute top-0 right-0 h-full w-1/3 opacity-30"
56+
style={{
57+
background: `
58+
linear-gradient(
59+
115deg,
60+
transparent 20%,
61+
hsl(var(--primary) / 0.4) 35%,
62+
rgba(139, 92, 246, 0.3) 45%,
63+
rgba(6, 182, 212, 0.3) 55%,
64+
hsl(var(--primary) / 0.4) 65%,
65+
transparent 80%
66+
)
67+
`,
68+
}}
69+
/>
70+
71+
{/* Top row */}
72+
<div className="relative z-10 flex items-start justify-between">
73+
<div className="flex items-center gap-2.5">
74+
{/* EMV Chip */}
75+
<div className="relative flex h-8 w-10 items-center justify-center overflow-hidden rounded-sm bg-linear-to-br from-amber-200 via-amber-300 to-amber-400 shadow-sm">
76+
<div className="absolute inset-0.5 rounded-[2px] bg-linear-to-br from-amber-100 to-amber-300 opacity-60" />
77+
<div className="relative grid h-5 w-6 grid-cols-3 grid-rows-3 gap-px">
78+
{Array.from({ length: 9 }).map((_, i) => (
79+
<div
80+
className="rounded-[1px] bg-amber-600/40"
81+
key={i.toString()}
82+
/>
83+
))}
84+
</div>
85+
</div>
86+
{/* Contactless */}
87+
<WifiHighIcon
88+
className="rotate-90 text-white/40"
89+
size={18}
90+
weight="bold"
91+
/>
92+
</div>
93+
<span className="font-mono text-[10px] text-white/40 uppercase tracking-[0.25em]">
5994
{brand}
6095
</span>
6196
</div>
6297

63-
<div className="relative z-2 flex flex-col gap-2">
98+
{/* Bottom content */}
99+
<div className="relative z-10 flex flex-col gap-3">
64100
{showCardDetails ? (
65101
<>
66-
<div className="flex items-end gap-2">
67-
<p className="font-semibold text-white/80 text-xs uppercase tracking-wide">
68-
{cardHolder}
69-
</p>
70-
<p className="ml-auto font-semibold text-white/80 text-xs tabular-nums">
71-
{expiration}
72-
</p>
73-
</div>
74-
<div className="flex items-end justify-between gap-3">
75-
<button
76-
aria-label="Hide card details"
77-
className="cursor-pointer font-semibold text-white tabular-nums tracking-wider transition-opacity hover:opacity-80"
78-
onClick={() => setShowCardDetails(false)}
79-
type="button"
80-
>
81-
{cardNumber}
82-
</button>
83-
<CardBrandLogo brand={brand} />
102+
<button
103+
aria-label="Hide card details"
104+
className="w-fit cursor-pointer text-left font-mono text-[15px] text-white/90 tabular-nums tracking-[0.2em] transition-colors hover:text-white"
105+
onClick={() => setShowCardDetails(false)}
106+
type="button"
107+
>
108+
{cardNumber}
109+
</button>
110+
<div className="flex items-end justify-between">
111+
<div className="flex flex-col">
112+
<span className="text-[8px] text-white/30 uppercase tracking-wider">
113+
Card Holder
114+
</span>
115+
<p className="font-medium text-white/70 text-xs uppercase tracking-wide">
116+
{cardHolder}
117+
</p>
118+
</div>
119+
<div className="flex items-end gap-4">
120+
<div className="flex flex-col text-right">
121+
<span className="text-[8px] text-white/30 uppercase tracking-wider">
122+
Expires
123+
</span>
124+
<p className="font-mono text-white/70 text-xs tabular-nums">
125+
{expiration}
126+
</p>
127+
</div>
128+
<CardBrandLogo brand={brand} />
129+
</div>
84130
</div>
85131
</>
86132
) : (
87133
<>
88-
<div className="flex items-end gap-2">
89-
<p className="font-semibold text-white/40 text-xs uppercase tracking-wide">
90-
•••• ••••
91-
</p>
92-
<p className="ml-auto font-semibold text-white/40 text-xs tabular-nums">
93-
••/••
94-
</p>
95-
</div>
96-
<div className="flex items-end justify-between gap-3">
97-
<button
98-
aria-label="Show card details"
99-
className="cursor-pointer font-semibold text-white/40 tabular-nums tracking-wider transition-opacity hover:opacity-80"
100-
onClick={() => setShowCardDetails(true)}
101-
type="button"
102-
>
103-
•••• •••• •••• ••••
104-
</button>
105-
<CardBrandLogo brand={brand} />
134+
<button
135+
aria-label="Show card details"
136+
className="w-fit cursor-pointer text-left font-mono text-[15px] text-white/25 tabular-nums tracking-[0.2em] transition-colors hover:text-white/40"
137+
onClick={() => setShowCardDetails(true)}
138+
type="button"
139+
>
140+
•••• •••• •••• ••••
141+
</button>
142+
<div className="flex items-end justify-between">
143+
<div className="flex flex-col">
144+
<span className="text-[8px] text-white/30 uppercase tracking-wider">
145+
Card Holder
146+
</span>
147+
<p className="font-medium text-white/25 text-xs uppercase tracking-wide">
148+
•••• ••••
149+
</p>
150+
</div>
151+
<div className="flex items-end gap-4">
152+
<div className="flex flex-col text-right">
153+
<span className="text-[8px] text-white/30 uppercase tracking-wider">
154+
Expires
155+
</span>
156+
<p className="font-mono text-white/25 text-xs tabular-nums">
157+
••/••
158+
</p>
159+
</div>
160+
<CardBrandLogo brand={brand} />
161+
</div>
106162
</div>
107163
</>
108164
)}
@@ -115,7 +171,7 @@ export function CreditCardDisplay({ customer }: CreditCardDisplayProps) {
115171
function CardBrandLogo({ brand }: { brand: string }) {
116172
if (brand === "visa") {
117173
return (
118-
<div className="flex h-6 w-10 items-center justify-center rounded bg-white/10 font-bold text-white text-xs italic">
174+
<div className="flex h-6 w-10 items-center justify-center font-bold text-sm text-white/80 italic tracking-tight">
119175
VISA
120176
</div>
121177
);
@@ -124,22 +180,22 @@ function CardBrandLogo({ brand }: { brand: string }) {
124180
return (
125181
<div className="flex h-6 w-10 items-center justify-center">
126182
<div className="relative flex">
127-
<div className="h-5 w-5 rounded-full bg-red-500/90" />
128-
<div className="-ml-2 h-5 w-5 rounded-full bg-yellow-500/90" />
183+
<div className="h-5 w-5 rounded-full bg-[#eb001b]" />
184+
<div className="-ml-2.5 h-5 w-5 rounded-full bg-[#f79e1b] mix-blend-hard-light" />
129185
</div>
130186
</div>
131187
);
132188
}
133189
if (brand === "amex") {
134190
return (
135-
<div className="flex h-6 w-10 items-center justify-center rounded bg-white/10 font-bold text-[8px] text-white">
191+
<div className="flex h-6 w-10 items-center justify-center font-bold text-[#006fcf] text-[9px]">
136192
AMEX
137193
</div>
138194
);
139195
}
140196
return (
141-
<div className="flex h-6 w-10 items-center justify-center rounded bg-white/10">
142-
<CreditCardIcon className="text-white/80" size={16} weight="duotone" />
197+
<div className="flex h-6 w-10 items-center justify-center">
198+
<CreditCardIcon className="text-white/50" size={18} weight="duotone" />
143199
</div>
144200
);
145201
}

0 commit comments

Comments
 (0)