Skip to content

Commit 1fb21a2

Browse files
fix: dark mode for cards
1 parent 1aa3739 commit 1fb21a2

File tree

2 files changed

+154
-24
lines changed

2 files changed

+154
-24
lines changed

src/components/card/TradingCard.tsx

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,71 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
200200
};
201201
}, [enable3D, handleMovement, resetCardPosition]);
202202

203+
// Determine if we're in dark mode by checking for the .dark class on html
204+
const isDarkMode = typeof document !== 'undefined' &&
205+
document.documentElement.classList.contains('dark');
206+
207+
// Handle custom colors in dark mode
208+
const isCustomBorderColor = borderColor !== "#4299e1";
209+
const isCustomBackgroundColor = backgroundColor !== "#ebf8ff";
210+
211+
// For custom colors, darken them in dark mode but preserve their hue
212+
const darkModeBorderColor = isDarkMode
213+
? isCustomBorderColor
214+
// If it's a custom color, darken it but preserve the hue
215+
? adjustColorForDarkMode(borderColor)
216+
// Default dark blue for the default border
217+
: "#1e40af"
218+
: borderColor;
219+
220+
// For custom background colors, darken them significantly in dark mode
221+
const darkModeBackgroundColor = isDarkMode
222+
? isCustomBackgroundColor
223+
// If it's a custom background, darken it but preserve the hue
224+
? adjustColorForDarkMode(backgroundColor, 0.3) // More darkening for backgrounds
225+
// Default dark blue background
226+
: "#0f172a"
227+
: backgroundColor;
228+
229+
// Helper function to adjust colors for dark mode
230+
function adjustColorForDarkMode(color: string, darkFactor = 0.6) {
231+
// Simple color darkening for hex colors
232+
if (color.startsWith('#')) {
233+
// Convert hex to RGB
234+
const r = parseInt(color.slice(1, 3), 16);
235+
const g = parseInt(color.slice(3, 5), 16);
236+
const b = parseInt(color.slice(5, 7), 16);
237+
238+
// Darken the color
239+
const darkenedR = Math.floor(r * darkFactor);
240+
const darkenedG = Math.floor(g * darkFactor);
241+
const darkenedB = Math.floor(b * darkFactor);
242+
243+
// Convert back to hex
244+
return `#${darkenedR.toString(16).padStart(2, '0')}${darkenedG.toString(16).padStart(2, '0')}${darkenedB.toString(16).padStart(2, '0')}`;
245+
}
246+
247+
return color;
248+
}
249+
250+
// Determine text colors based on background darkness
251+
const isDarkBackground = isDarkMode || isColorDark(backgroundColor);
252+
253+
// Helper function to determine if a color is dark
254+
function isColorDark(color: string): boolean {
255+
if (color.startsWith('#')) {
256+
const r = parseInt(color.slice(1, 3), 16);
257+
const g = parseInt(color.slice(3, 5), 16);
258+
const b = parseInt(color.slice(5, 7), 16);
259+
260+
// Calculate perceived brightness (YIQ formula)
261+
const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000;
262+
return yiq < 128; // Less than 128 is considered dark
263+
}
264+
265+
return false;
266+
}
267+
203268
return (
204269
<div
205270
ref={(node) => {
@@ -219,32 +284,52 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
219284
className
220285
)}
221286
style={{
222-
backgroundColor: backgroundColor,
223-
boxShadow: `0 10px 30px -5px rgba(0, 0, 0, 0.3)`,
224-
border: `8px solid ${borderColor}`,
287+
backgroundColor: darkModeBackgroundColor,
288+
boxShadow: isDarkMode
289+
? `0 10px 30px -5px rgba(0, 0, 0, 0.7), 0 0 15px rgba(255, 255, 255, 0.1)`
290+
: `0 10px 30px -5px rgba(0, 0, 0, 0.3)`,
291+
border: `8px solid ${darkModeBorderColor}`,
225292
transformStyle: 'preserve-3d',
226293
}}
227294
{...props}
228295
>
229-
{/* Glare effect overlay */}
296+
{/* Glare effect overlay - reduce intensity in dark mode */}
230297
<div
231298
ref={glareRef}
232299
className="absolute inset-0 z-20 pointer-events-none"
233300
style={{
234301
borderRadius: 'inherit',
302+
opacity: isDarkMode ? 0.7 : 1,
235303
}}
236304
/>
237305

238306
{/* Card header with title and attribute */}
239-
<div className="flex justify-between items-center p-3 border-b border-gray-200 bg-white/90">
307+
<div className={cn(
308+
"flex justify-between items-center p-3 border-b",
309+
isDarkMode || isDarkBackground
310+
? "border-gray-700 bg-gray-800/90 text-white"
311+
: "border-gray-200 bg-white/90 text-gray-900"
312+
)}>
240313
<div>
241-
<h3 className="font-bold text-lg">{title}</h3>
242-
{subtitle && <p className="text-xs text-gray-500">{subtitle}</p>}
314+
<h3 className={cn(
315+
"font-bold text-lg",
316+
isDarkMode || isDarkBackground ? "text-white" : "text-gray-900"
317+
)}>{title}</h3>
318+
{subtitle && <p className={cn(
319+
"text-xs",
320+
isDarkMode || isDarkBackground ? "text-gray-300" : "text-gray-500"
321+
)}>{subtitle}</p>}
243322
</div>
244323
{attributeValue && (
245324
<div className="flex items-center">
246-
<span className="font-bold text-xl">{attributeValue}</span>
247-
{attributeLabel && <span className="text-xs ml-1">{attributeLabel}</span>}
325+
<span className={cn(
326+
"font-bold text-xl",
327+
isDarkMode || isDarkBackground ? "text-white" : "text-gray-900"
328+
)}>{attributeValue}</span>
329+
{attributeLabel && <span className={cn(
330+
"text-xs ml-1",
331+
isDarkMode || isDarkBackground ? "text-gray-300" : "text-gray-700"
332+
)}>{attributeLabel}</span>}
248333
</div>
249334
)}
250335
</div>
@@ -256,20 +341,34 @@ export const TradingCard = React.forwardRef<HTMLDivElement, TradingCardProps>(
256341
backgroundImage: `url(${imageUrl})`,
257342
transform: 'translateZ(20px)', // 3D effect for the image
258343
transformStyle: 'preserve-3d',
344+
backgroundColor: isDarkMode ? '#1e293b' : '#f8fafc', // Subtle background for image area
259345
}}
260346
/>
261347

262348
{/* Card content */}
263-
<div className="p-4 bg-white/90">
349+
<div className={cn(
350+
"p-4",
351+
isDarkMode || isDarkBackground
352+
? "bg-gray-800/95 text-gray-100"
353+
: "bg-white/90 text-gray-800"
354+
)}>
264355
{description && (
265-
<p className="text-sm">{description}</p>
356+
<p className={cn(
357+
"text-sm",
358+
isDarkMode || isDarkBackground ? "text-gray-200" : "text-gray-700"
359+
)}>{description}</p>
266360
)}
267361
{children}
268362
</div>
269363

270364
{/* Card footer */}
271365
{footer && (
272-
<div className="absolute bottom-0 left-0 right-0 p-2 text-xs text-center bg-gray-100 border-t border-gray-200">
366+
<div className={cn(
367+
"absolute bottom-0 left-0 right-0 p-2 text-xs text-center border-t",
368+
isDarkMode || isDarkBackground
369+
? "bg-gray-900 border-gray-700 text-gray-300"
370+
: "bg-gray-100 border-gray-200 text-gray-600"
371+
)}>
273372
{footer}
274373
</div>
275374
)}

src/components/card/VerifiableCredentialCard.tsx

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,23 @@ export const VerifiableCredentialCard = React.forwardRef<HTMLDivElement, Verifia
7575
// Format issuance date
7676
const issuanceDate = new Date(credential.issuanceDate).toLocaleDateString();
7777

78-
// Determine border color based on verification status
78+
// Determine if we're in dark mode
79+
const isDarkMode = typeof document !== 'undefined' &&
80+
document.documentElement.classList.contains('dark');
81+
82+
// Determine border color based on verification status and dark mode
7983
const statusColor = !borderColor && credential.verificationStatus
8084
? credential.verificationStatus === 'verified'
81-
? '#10b981' // Green for verified
85+
? isDarkMode ? '#059669' : '#10b981' // Green for verified
8286
: credential.verificationStatus === 'invalid'
83-
? '#ef4444' // Red for invalid
84-
: '#f59e0b' // Amber for unverified
87+
? isDarkMode ? '#b91c1c' : '#ef4444' // Red for invalid
88+
: isDarkMode ? '#b45309' : '#f59e0b' // Amber for unverified
8589
: borderColor;
8690

87-
// Determine background color based on credential type
88-
const typeColor = !backgroundColor ? 'rgba(236, 253, 245, 0.8)' : backgroundColor;
91+
// Determine background color based on credential type and dark mode
92+
const typeColor = !backgroundColor
93+
? isDarkMode ? '#134e4a' : 'rgba(236, 253, 245, 0.8)'
94+
: backgroundColor;
8995

9096
return (
9197
<TradingCard
@@ -102,19 +108,34 @@ export const VerifiableCredentialCard = React.forwardRef<HTMLDivElement, Verifia
102108
{showVerificationStatus && credential.verificationStatus && (
103109
<div className="absolute top-3 right-3 z-10">
104110
{credential.verificationStatus === 'verified' && (
105-
<div className="flex items-center bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">
111+
<div className={cn(
112+
"flex items-center text-xs px-2 py-1 rounded-full",
113+
isDarkMode
114+
? "bg-green-900 text-green-100"
115+
: "bg-green-100 text-green-800"
116+
)}>
106117
<CheckCircle className="w-3 h-3 mr-1" />
107118
<span>Verified</span>
108119
</div>
109120
)}
110121
{credential.verificationStatus === 'invalid' && (
111-
<div className="flex items-center bg-red-100 text-red-800 text-xs px-2 py-1 rounded-full">
122+
<div className={cn(
123+
"flex items-center text-xs px-2 py-1 rounded-full",
124+
isDarkMode
125+
? "bg-red-900 text-red-100"
126+
: "bg-red-100 text-red-800"
127+
)}>
112128
<AlertCircle className="w-3 h-3 mr-1" />
113129
<span>Invalid</span>
114130
</div>
115131
)}
116132
{credential.verificationStatus === 'unverified' && (
117-
<div className="flex items-center bg-amber-100 text-amber-800 text-xs px-2 py-1 rounded-full">
133+
<div className={cn(
134+
"flex items-center text-xs px-2 py-1 rounded-full",
135+
isDarkMode
136+
? "bg-amber-900 text-amber-100"
137+
: "bg-amber-100 text-amber-800"
138+
)}>
118139
<Shield className="w-3 h-3 mr-1" />
119140
<span>Unverified</span>
120141
</div>
@@ -129,8 +150,13 @@ export const VerifiableCredentialCard = React.forwardRef<HTMLDivElement, Verifia
129150

130151
return (
131152
<div key={prop} className="flex justify-between text-sm">
132-
<span className="font-medium text-gray-600">{prop}:</span>
133-
<span className="text-gray-900">
153+
<span className={cn(
154+
"font-medium",
155+
isDarkMode ? "text-gray-300" : "text-gray-600"
156+
)}>{prop}:</span>
157+
<span className={cn(
158+
isDarkMode ? "text-white" : "text-gray-900"
159+
)}>
134160
{typeof credential.credentialSubject[prop] === 'object'
135161
? JSON.stringify(credential.credentialSubject[prop])
136162
: credential.credentialSubject[prop].toString()}
@@ -142,7 +168,12 @@ export const VerifiableCredentialCard = React.forwardRef<HTMLDivElement, Verifia
142168

143169
{/* Credential ID (truncated) */}
144170
{credential.id && (
145-
<div className="mt-3 pt-2 border-t border-gray-200 text-xs text-gray-500 truncate">
171+
<div className={cn(
172+
"mt-3 pt-2 border-t text-xs truncate",
173+
isDarkMode
174+
? "border-gray-700 text-gray-400"
175+
: "border-gray-200 text-gray-500"
176+
)}>
146177
ID: {credential.id}
147178
</div>
148179
)}

0 commit comments

Comments
 (0)