@chainloyalty/react 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -143,6 +143,7 @@ const getRankIcon = (rank: number): React.ReactNode => {
143
143
  interface LeaderboardRowProps {
144
144
  entry: LeaderboardEntry;
145
145
  accentColor: string;
146
+ theme: ReturnType<typeof getThemeColors>;
146
147
  isCurrentUser?: boolean;
147
148
  onCopyAddress?: (address: string) => void;
148
149
  }
@@ -150,6 +151,7 @@ interface LeaderboardRowProps {
150
151
  const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
151
152
  entry,
152
153
  accentColor,
154
+ theme,
153
155
  isCurrentUser = false,
154
156
  onCopyAddress,
155
157
  }) => {
@@ -169,9 +171,11 @@ const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
169
171
 
170
172
  return (
171
173
  <tr
172
- className={`border-b border-gray-700 transition-all hover:bg-gray-700/30 ${
173
- isCurrentUser ? 'bg-gray-700/20' : ''
174
- }`}
174
+ className="border-b transition-all hover:opacity-80"
175
+ style={{
176
+ borderColor: theme.border,
177
+ backgroundColor: isCurrentUser ? 'rgba(0,0,0,0.1)' : 'transparent'
178
+ }}
175
179
  >
176
180
  {/* Rank */}
177
181
  <td className="px-4 py-3 text-sm">
@@ -191,12 +195,13 @@ const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
191
195
  {/* Wallet Address */}
192
196
  <td className="px-4 py-3 text-sm">
193
197
  <div className="flex items-center gap-2 group">
194
- <span className="text-white font-mono">
198
+ <span className="font-mono" style={{ color: theme.foreground }}>
195
199
  {shortenAddress(entry.walletAddress)}
196
200
  </span>
197
201
  <button
198
202
  onClick={handleCopy}
199
- className="p-1.5 rounded-md text-gray-500 group-hover:text-gray-300 hover:bg-gray-700/50 transition-all opacity-0 group-hover:opacity-100"
203
+ className="p-1.5 rounded-md transition-all opacity-0 group-hover:opacity-100"
204
+ style={{ color: theme.mutedForeground }}
200
205
  title={entry.walletAddress}
201
206
  >
202
207
  {copied ? (
@@ -206,7 +211,7 @@ const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
206
211
  )}
207
212
  </button>
208
213
  {entry.displayName && (
209
- <span className="hidden sm:inline text-xs text-gray-400">({entry.displayName})</span>
214
+ <span className="hidden sm:inline text-xs" style={{ color: theme.mutedForeground }}>({entry.displayName})</span>
210
215
  )}
211
216
  </div>
212
217
  </td>
@@ -217,7 +222,7 @@ const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
217
222
  <p className="font-bold" style={{ color: accentColor }}>
218
223
  {entry.points.toLocaleString()}
219
224
  </p>
220
- <p className="text-xs text-gray-400 hidden sm:block">points</p>
225
+ <p className="text-xs hidden sm:block" style={{ color: theme.mutedForeground }}>points</p>
221
226
  </div>
222
227
  </td>
223
228
 
@@ -226,12 +231,13 @@ const LeaderboardRow: React.FC<LeaderboardRowProps> = ({
226
231
  <div
227
232
  className="inline-flex items-center gap-1 px-2 py-1 rounded-lg"
228
233
  style={{
229
- backgroundColor: 'rgba(47, 129, 247, 0.1)',
230
- borderColor: accentColor,
234
+ backgroundColor: theme.muted,
235
+ borderColor: theme.border,
236
+ border: '1px solid',
231
237
  }}
232
238
  >
233
239
  <Award className="w-4 h-4" style={{ color: accentColor }} />
234
- <span className="font-semibold text-white">{entry.badgesCount}</span>
240
+ <span className="font-semibold" style={{ color: theme.foreground }}>{entry.badgesCount}</span>
235
241
  </div>
236
242
  </td>
237
243
  </tr>
@@ -261,7 +267,6 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
261
267
  // Override with customColors if provided (backward compatibility)
262
268
  const accentColor = customColors.accent1 || theme.accent;
263
269
  const accentColor2 = customColors.accent2 || theme.primary;
264
- const backgroundColor = customColors.background || theme.card;
265
270
 
266
271
  // Fetch data when timeframe changes
267
272
  useEffect(() => {
@@ -299,20 +304,21 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
299
304
 
300
305
  return (
301
306
  <div
302
- className="rounded-lg border border-gray-700 overflow-hidden"
303
- style={{ backgroundColor }}
307
+ className="rounded-lg border overflow-hidden"
308
+ style={{ backgroundColor: theme.card, borderColor: theme.border }}
304
309
  >
305
310
  {/* Header */}
306
- <div className="p-6 border-b border-gray-700">
311
+ <div className="p-6" style={{ borderBottom: `1px solid ${theme.border}` }}>
307
312
  <div className="flex items-center justify-between mb-4">
308
313
  <div className="flex items-center gap-3">
309
314
  <Trophy className="w-6 h-6" style={{ color: accentColor2 }} />
310
- <h2 className="text-2xl font-bold text-white">Leaderboard</h2>
315
+ <h2 className="text-2xl font-bold" style={{ color: theme.foreground }}>Leaderboard</h2>
311
316
  </div>
312
317
  <button
313
318
  onClick={handleRefresh}
314
319
  disabled={loading}
315
- className="p-2 rounded-lg text-gray-400 hover:text-white hover:bg-gray-700 transition-all disabled:opacity-50"
320
+ className="p-2 rounded-lg transition-all disabled:opacity-50"
321
+ style={{ color: theme.mutedForeground }}
316
322
  title="Refresh leaderboard"
317
323
  >
318
324
  <RefreshCw className={`w-5 h-5 ${loading ? 'animate-spin' : ''}`} />
@@ -322,11 +328,11 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
322
328
  {/* Stats */}
323
329
  <div className="grid grid-cols-2 md:grid-cols-3 gap-3 mb-4">
324
330
  <div
325
- className="p-3 rounded-lg border border-gray-700"
326
- style={{ backgroundColor: 'rgba(31, 41, 55, 0.5)' }}
331
+ className="p-3 rounded-lg border"
332
+ style={{ backgroundColor: theme.muted, borderColor: theme.border }}
327
333
  >
328
- <p className="text-xs text-gray-400">Total Users</p>
329
- <p className="text-2xl font-bold text-white">{data.length.toLocaleString()}</p>
334
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>Total Users</p>
335
+ <p className="text-2xl font-bold" style={{ color: theme.foreground }}>{data.length.toLocaleString()}</p>
330
336
  </div>
331
337
 
332
338
  {currentUserRank && (
@@ -335,10 +341,10 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
335
341
  className="p-3 rounded-lg border"
336
342
  style={{
337
343
  borderColor: accentColor,
338
- backgroundColor: 'rgba(47, 129, 247, 0.1)',
344
+ backgroundColor: theme.card,
339
345
  }}
340
346
  >
341
- <p className="text-xs text-gray-400">Your Rank</p>
347
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>Your Rank</p>
342
348
  <p className="text-2xl font-bold" style={{ color: accentColor }}>
343
349
  #{currentUserRank.rank}
344
350
  </p>
@@ -348,10 +354,10 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
348
354
  className="p-3 rounded-lg border"
349
355
  style={{
350
356
  borderColor: accentColor2,
351
- backgroundColor: 'rgba(63, 185, 80, 0.1)',
357
+ backgroundColor: theme.card,
352
358
  }}
353
359
  >
354
- <p className="text-xs text-gray-400">Your Points</p>
360
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>Your Points</p>
355
361
  <p className="text-2xl font-bold" style={{ color: accentColor2 }}>
356
362
  {currentUserRank.points.toLocaleString()}
357
363
  </p>
@@ -363,7 +369,7 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
363
369
  {/* Filters */}
364
370
  {!hideTimeframeFilter && (
365
371
  <div className="flex items-center gap-2">
366
- <Calendar className="w-4 h-4 text-gray-400" />
372
+ <Calendar className="w-4 h-4" style={{ color: theme.mutedForeground }} />
367
373
  <div className="flex gap-2">
368
374
  {(['alltime', 'month'] as const).map((tf) => (
369
375
  <button
@@ -371,8 +377,8 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
371
377
  onClick={() => setTimeframe(tf)}
372
378
  className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-all ${
373
379
  timeframe === tf
374
- ? 'text-white'
375
- : 'text-gray-400 hover:text-white hover:bg-gray-700/50'
380
+ ? ''
381
+ : ''
376
382
  }`}
377
383
  style={
378
384
  timeframe === tf
@@ -380,7 +386,7 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
380
386
  backgroundColor: accentColor,
381
387
  color: 'white',
382
388
  }
383
- : {}
389
+ : { color: theme.mutedForeground }
384
390
  }
385
391
  >
386
392
  {tf === 'alltime' ? 'All Time' : 'This Month'}
@@ -392,12 +398,12 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
392
398
  </div>
393
399
 
394
400
  {/* Content */}
395
- <div style={{ backgroundColor: 'rgba(31, 41, 55, 0.2)' }}>
401
+ <div style={{ backgroundColor: theme.background }}>
396
402
  {/* Loading State */}
397
403
  {loading && !data.length && (
398
404
  <div className="p-6 space-y-3">
399
405
  {[...Array(5)].map((_, i) => (
400
- <div key={i} className="h-12 bg-gray-700 rounded-lg animate-pulse" />
406
+ <div key={i} className="h-12 rounded-lg animate-pulse" style={{ backgroundColor: theme.muted }} />
401
407
  ))}
402
408
  </div>
403
409
  )}
@@ -405,10 +411,10 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
405
411
  {/* Error State */}
406
412
  {error && !data.length && (
407
413
  <div className="p-6 text-center">
408
- <p className="text-red-400 mb-4">{error}</p>
414
+ <p className="mb-4" style={{ color: '#ef4444' }}>{error}</p>
409
415
  <button
410
416
  onClick={handleRefresh}
411
- className="px-4 py-2 rounded-lg text-white text-sm transition-all"
417
+ className="px-4 py-2 rounded-lg text-sm transition-all text-white"
412
418
  style={{ backgroundColor: accentColor }}
413
419
  >
414
420
  Try Again
@@ -419,9 +425,9 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
419
425
  {/* Empty State */}
420
426
  {!loading && !error && data.length === 0 && (
421
427
  <div className="p-12 text-center">
422
- <TrendingUp className="w-12 h-12 mx-auto mb-4 text-gray-500" />
423
- <h3 className="text-lg font-semibold text-white mb-2">No Leaderboard Data</h3>
424
- <p className="text-gray-400">The leaderboard will be populated as users start earning points.</p>
428
+ <TrendingUp className="w-12 h-12 mx-auto mb-4" style={{ color: theme.mutedForeground }} />
429
+ <h3 className="text-lg font-semibold mb-2" style={{ color: theme.foreground }}>No Leaderboard Data</h3>
430
+ <p style={{ color: theme.mutedForeground }}>The leaderboard will be populated as users start earning points.</p>
425
431
  </div>
426
432
  )}
427
433
 
@@ -430,17 +436,17 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
430
436
  <div className="overflow-x-auto">
431
437
  <table className="w-full">
432
438
  <thead>
433
- <tr className="border-b border-gray-700 bg-gray-800/50">
434
- <th className="px-4 py-3 text-left text-xs font-semibold text-gray-400 uppercase">
439
+ <tr className="border-b" style={{ borderColor: theme.border, backgroundColor: theme.muted }}>
440
+ <th className="px-4 py-3 text-left text-xs font-semibold uppercase" style={{ color: theme.mutedForeground }}>
435
441
  Rank
436
442
  </th>
437
- <th className="px-4 py-3 text-left text-xs font-semibold text-gray-400 uppercase">
443
+ <th className="px-4 py-3 text-left text-xs font-semibold uppercase" style={{ color: theme.mutedForeground }}>
438
444
  Wallet
439
445
  </th>
440
- <th className="px-4 py-3 text-right text-xs font-semibold text-gray-400 uppercase">
446
+ <th className="px-4 py-3 text-right text-xs font-semibold uppercase" style={{ color: theme.mutedForeground }}>
441
447
  Points
442
448
  </th>
443
- <th className="px-4 py-3 text-center text-xs font-semibold text-gray-400 uppercase">
449
+ <th className="px-4 py-3 text-center text-xs font-semibold uppercase" style={{ color: theme.mutedForeground }}>
444
450
  Badges
445
451
  </th>
446
452
  </tr>
@@ -451,6 +457,7 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
451
457
  key={entry.rank}
452
458
  entry={entry}
453
459
  accentColor={accentColor}
460
+ theme={theme}
454
461
  isCurrentUser={
455
462
  walletAddress
456
463
  ? entry.walletAddress.toLowerCase() === walletAddress.toLowerCase()
@@ -470,15 +477,16 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
470
477
 
471
478
  {/* Pagination */}
472
479
  {!compactMode && data.length > itemsPerPage && (
473
- <div className="px-6 py-4 border-t border-gray-700 flex items-center justify-between">
474
- <div className="text-sm text-gray-400">
480
+ <div className="px-6 py-4 border-t flex items-center justify-between" style={{ borderColor: theme.border }}>
481
+ <div className="text-sm" style={{ color: theme.mutedForeground }}>
475
482
  Showing {startIndex + 1} to {Math.min(endIndex, data.length)} of {data.length}
476
483
  </div>
477
484
  <div className="flex gap-2">
478
485
  <button
479
486
  onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
480
487
  disabled={currentPage === 1}
481
- className="px-3 py-1.5 rounded-lg text-sm font-medium text-gray-400 hover:text-white hover:bg-gray-700 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
488
+ className="px-3 py-1.5 rounded-lg text-sm font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed"
489
+ style={{ color: theme.mutedForeground }}
482
490
  >
483
491
  ← Previous
484
492
  </button>
@@ -489,18 +497,14 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
489
497
  <button
490
498
  key={pageNum}
491
499
  onClick={() => setCurrentPage(pageNum)}
492
- className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-all ${
493
- currentPage === pageNum
494
- ? 'text-white'
495
- : 'text-gray-400 hover:text-white hover:bg-gray-700'
496
- }`}
500
+ className="px-3 py-1.5 rounded-lg text-sm font-medium transition-all"
497
501
  style={
498
502
  currentPage === pageNum
499
503
  ? {
500
504
  backgroundColor: accentColor,
501
505
  color: 'white',
502
506
  }
503
- : {}
507
+ : { color: theme.mutedForeground }
504
508
  }
505
509
  >
506
510
  {pageNum}
@@ -511,7 +515,8 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
511
515
  <button
512
516
  onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
513
517
  disabled={currentPage === totalPages}
514
- className="px-3 py-1.5 rounded-lg text-sm font-medium text-gray-400 hover:text-white hover:bg-gray-700 transition-all disabled:opacity-50 disabled:cursor-not-allowed"
518
+ className="px-3 py-1.5 rounded-lg text-sm font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed"
519
+ style={{ color: theme.mutedForeground }}
515
520
  >
516
521
  Next →
517
522
  </button>
@@ -520,7 +525,7 @@ export const Leaderboard: React.FC<LeaderboardProps> = ({
520
525
  )}
521
526
 
522
527
  {/* Footer */}
523
- <div className="px-6 py-3 border-t border-gray-700 flex items-center justify-end text-xs text-gray-500">
528
+ <div className="px-6 py-3 border-t flex items-center justify-end text-xs" style={{ borderColor: theme.border, color: theme.mutedForeground }}>
524
529
  <span className="flex items-center gap-1">
525
530
  <ExternalLink className="w-3 h-3" />
526
531
  @chainloyalty/react
@@ -245,34 +245,40 @@ const getRarityColor = (rarity: string): string => {
245
245
  interface RewardHistoryProps {
246
246
  items: RewardHistoryItem[];
247
247
  accentColor: string;
248
+ theme: ReturnType<typeof getThemeColors>;
248
249
  }
249
250
 
250
- const RewardHistory: React.FC<RewardHistoryProps> = ({ items, accentColor }) => {
251
+ const RewardHistory: React.FC<RewardHistoryProps> = ({ items, accentColor, theme }) => {
251
252
  return (
252
253
  <div className="space-y-3">
253
254
  {items.map((item) => (
254
255
  <div
255
256
  key={item.id}
256
- className="flex items-start justify-between p-3 rounded-lg border border-gray-700 hover:border-gray-600 transition-colors"
257
- style={{ borderLeftColor: accentColor, borderLeftWidth: '3px' }}
257
+ className="flex items-start justify-between p-3 rounded-lg border transition-colors hover:opacity-80"
258
+ style={{
259
+ borderColor: theme.border,
260
+ borderLeftColor: accentColor,
261
+ borderLeftWidth: '3px',
262
+ backgroundColor: 'transparent',
263
+ }}
258
264
  >
259
265
  <div className="flex-1">
260
266
  <div className="flex items-center gap-2">
261
- <span className="text-sm font-semibold text-white">{item.title}</span>
262
- <span className="text-xs px-2 py-0.5 rounded-full bg-gray-700 text-gray-300">
267
+ <span className="text-sm font-semibold" style={{ color: theme.foreground }}>{item.title}</span>
268
+ <span className="text-xs px-2 py-0.5 rounded-full" style={{ backgroundColor: theme.muted, color: theme.mutedForeground }}>
263
269
  {item.type}
264
270
  </span>
265
271
  </div>
266
272
  {item.description && (
267
- <p className="text-xs text-gray-400 mt-1">{item.description}</p>
273
+ <p className="text-xs mt-1" style={{ color: theme.mutedForeground }}>{item.description}</p>
268
274
  )}
269
- <p className="text-xs text-gray-500 mt-1">{formatDate(item.timestamp)}</p>
275
+ <p className="text-xs mt-1" style={{ color: theme.mutedForeground }}>{formatDate(item.timestamp)}</p>
270
276
  </div>
271
277
  <div className="ml-4 text-right">
272
278
  <p className="text-lg font-bold" style={{ color: accentColor }}>
273
279
  +{item.points}
274
280
  </p>
275
- <p className="text-xs text-gray-400">points</p>
281
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>points</p>
276
282
  </div>
277
283
  </div>
278
284
  ))}
@@ -286,10 +292,11 @@ const RewardHistory: React.FC<RewardHistoryProps> = ({ items, accentColor }) =>
286
292
 
287
293
  interface BadgeGridProps {
288
294
  badges: Badge[];
295
+ theme: ReturnType<typeof getThemeColors>;
289
296
  compactMode?: boolean;
290
297
  }
291
298
 
292
- const BadgeGrid: React.FC<BadgeGridProps> = ({ badges, compactMode = false }) => {
299
+ const BadgeGrid: React.FC<BadgeGridProps> = ({ badges, theme, compactMode = false }) => {
293
300
  const displayBadges = compactMode ? badges.slice(0, 4) : badges;
294
301
 
295
302
  return (
@@ -302,18 +309,19 @@ const BadgeGrid: React.FC<BadgeGridProps> = ({ badges, compactMode = false }) =>
302
309
  className="group relative p-3 rounded-lg border transition-all hover:scale-105 cursor-pointer"
303
310
  style={{
304
311
  borderColor: getRarityColor(badge.rarity),
305
- backgroundColor: 'rgba(31, 41, 55, 0.5)',
312
+ backgroundColor: theme.card,
313
+ opacity: 0.9,
306
314
  }}
307
315
  title={`${badge.name} - ${badge.description}`}
308
316
  >
309
317
  <div className="text-3xl mb-1 text-center">{badge.icon}</div>
310
- <p className="text-xs font-semibold text-white text-center truncate">{badge.name}</p>
311
- <p className="text-xs text-gray-400 text-center mt-0.5">
318
+ <p className="text-xs font-semibold text-center truncate" style={{ color: theme.foreground }}>{badge.name}</p>
319
+ <p className="text-xs text-center mt-0.5" style={{ color: theme.mutedForeground }}>
312
320
  {new Date(badge.earnedAt).toLocaleDateString()}
313
321
  </p>
314
322
 
315
323
  {/* Tooltip on hover */}
316
- <div className="hidden group-hover:block absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 p-2 bg-gray-900 border border-gray-700 rounded-lg text-xs text-gray-300 w-32 text-center whitespace-normal z-10">
324
+ <div className="hidden group-hover:block absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 p-2 border rounded-lg text-xs w-32 text-center whitespace-normal z-10" style={{ backgroundColor: theme.muted, borderColor: theme.border, color: theme.mutedForeground }}>
317
325
  {badge.description}
318
326
  </div>
319
327
  </div>
@@ -329,9 +337,10 @@ const BadgeGrid: React.FC<BadgeGridProps> = ({ badges, compactMode = false }) =>
329
337
  interface TierCardProps {
330
338
  tier: TierInfo;
331
339
  accentColor: string;
340
+ theme: ReturnType<typeof getThemeColors>;
332
341
  }
333
342
 
334
- const TierCard: React.FC<TierCardProps> = ({ tier, accentColor }) => {
343
+ const TierCard: React.FC<TierCardProps> = ({ tier, accentColor, theme }) => {
335
344
  const progressPercent = (tier.currentProgress / tier.nextMilestone) * 100;
336
345
 
337
346
  return (
@@ -339,24 +348,24 @@ const TierCard: React.FC<TierCardProps> = ({ tier, accentColor }) => {
339
348
  className="p-4 rounded-lg border"
340
349
  style={{
341
350
  borderColor: accentColor,
342
- backgroundColor: 'rgba(31, 41, 55, 0.3)',
351
+ backgroundColor: theme.card,
343
352
  }}
344
353
  >
345
354
  <div className="flex items-start justify-between mb-3">
346
355
  <div className="flex items-center gap-2">
347
356
  <span className="text-3xl">{tier.icon}</span>
348
357
  <div>
349
- <p className="text-sm font-semibold text-white">{tier.name}</p>
350
- <p className="text-xs text-gray-400">Level {tier.level}</p>
358
+ <p className="text-sm font-semibold" style={{ color: theme.foreground }}>{tier.name}</p>
359
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>Level {tier.level}</p>
351
360
  </div>
352
361
  </div>
353
362
  </div>
354
363
  <div className="space-y-2">
355
- <div className="flex justify-between text-xs text-gray-400">
364
+ <div className="flex justify-between text-xs" style={{ color: theme.mutedForeground }}>
356
365
  <span>{tier.currentProgress.toLocaleString()} points</span>
357
366
  <span>{tier.nextMilestone.toLocaleString()} goal</span>
358
367
  </div>
359
- <div className="w-full bg-gray-700 rounded-full h-2 overflow-hidden">
368
+ <div className="w-full rounded-full h-2 overflow-hidden" style={{ backgroundColor: theme.muted }}>
360
369
  <div
361
370
  className="h-full rounded-full transition-all duration-500"
362
371
  style={{
@@ -438,21 +447,22 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
438
447
  if (!walletAddress) {
439
448
  return (
440
449
  <div
441
- className="p-6 rounded-lg border border-gray-700 max-w-2xl"
442
- style={{ backgroundColor }}
450
+ className="p-6 rounded-lg border max-w-2xl"
451
+ style={{ backgroundColor: theme.card, borderColor: theme.border }}
443
452
  >
444
453
  <div className="text-center">
445
- <Lock className="w-12 h-12 mx-auto mb-4 text-gray-500" />
446
- <h2 className="text-xl font-bold text-white mb-2">Connect Your Wallet</h2>
447
- <p className="text-gray-400 mb-6">
454
+ <Lock className="w-12 h-12 mx-auto mb-4" style={{ color: theme.mutedForeground }} />
455
+ <h2 className="text-xl font-bold mb-2" style={{ color: theme.foreground }}>Connect Your Wallet</h2>
456
+ <p className="mb-6" style={{ color: theme.mutedForeground }}>
448
457
  Connect your wallet to view your rewards, badges, and track your achievements.
449
458
  </p>
450
459
  {onConnectWallet && (
451
460
  <button
452
461
  onClick={onConnectWallet}
453
- className="inline-flex items-center gap-2 px-6 py-2 rounded-lg font-semibold text-white transition-all hover:opacity-90"
462
+ className="inline-flex items-center gap-2 px-6 py-2 rounded-lg font-semibold transition-all hover:opacity-90"
454
463
  style={{
455
464
  backgroundColor: accentColor,
465
+ color: '#fff',
456
466
  }}
457
467
  >
458
468
  <Wallet className="w-5 h-5" />
@@ -468,13 +478,13 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
468
478
  if (loading && !data) {
469
479
  return (
470
480
  <div
471
- className="p-6 rounded-lg border border-gray-700 max-w-2xl"
472
- style={{ backgroundColor }}
481
+ className="p-6 rounded-lg border max-w-2xl"
482
+ style={{ backgroundColor: theme.card, borderColor: theme.border }}
473
483
  >
474
484
  <div className="space-y-4">
475
- <div className="h-20 bg-gray-700 rounded-lg animate-pulse" />
476
- <div className="h-40 bg-gray-700 rounded-lg animate-pulse" />
477
- <div className="h-32 bg-gray-700 rounded-lg animate-pulse" />
485
+ <div className="h-20 rounded-lg animate-pulse" style={{ backgroundColor: theme.muted }} />
486
+ <div className="h-40 rounded-lg animate-pulse" style={{ backgroundColor: theme.muted }} />
487
+ <div className="h-32 rounded-lg animate-pulse" style={{ backgroundColor: theme.muted }} />
478
488
  </div>
479
489
  </div>
480
490
  );
@@ -484,10 +494,10 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
484
494
  if (error && !data) {
485
495
  return (
486
496
  <div
487
- className="p-6 rounded-lg border border-red-700 max-w-2xl"
488
- style={{ backgroundColor }}
497
+ className="p-6 rounded-lg border max-w-2xl"
498
+ style={{ backgroundColor: theme.card, borderColor: '#dc2626' }}
489
499
  >
490
- <p className="text-red-400">Failed to load rewards: {error}</p>
500
+ <p style={{ color: '#ef4444' }}>Failed to load rewards: {error}</p>
491
501
  <button
492
502
  onClick={handleRefresh}
493
503
  className="mt-4 px-4 py-2 rounded-lg text-white text-sm transition-all"
@@ -509,28 +519,30 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
509
519
  {/* Header */}
510
520
  <div className="p-6 border-b border-gray-700">
511
521
  <div className="flex items-center justify-between mb-4">
512
- <h2 className="text-2xl font-bold text-white">Rewards Dashboard</h2>
522
+ <h2 className="text-2xl font-bold" style={{ color: theme.foreground }}>Rewards Dashboard</h2>
513
523
  <button
514
524
  onClick={handleRefresh}
515
525
  disabled={loading}
516
- className="p-2 rounded-lg text-gray-400 hover:text-white hover:bg-gray-700 transition-all disabled:opacity-50"
526
+ className="p-2 rounded-lg transition-all disabled:opacity-50"
527
+ style={{ color: theme.mutedForeground }}
517
528
  >
518
529
  <RefreshCw className={`w-5 h-5 ${loading ? 'animate-spin' : ''}`} />
519
530
  </button>
520
531
  </div>
521
532
 
522
533
  {/* Wallet Display */}
523
- <div className="flex items-center justify-between p-3 rounded-lg bg-gray-800/50 border border-gray-700">
534
+ <div className="flex items-center justify-between p-3 rounded-lg border" style={{ backgroundColor: theme.muted, borderColor: theme.border }}>
524
535
  <div className="flex items-center gap-2">
525
536
  <Wallet className="w-5 h-5" style={{ color: accentColor }} />
526
537
  <div>
527
- <p className="text-xs text-gray-400">Connected Wallet</p>
528
- <p className="text-sm font-mono font-semibold text-white">{shortenAddress(walletAddress)}</p>
538
+ <p className="text-xs" style={{ color: theme.mutedForeground }}>Connected Wallet</p>
539
+ <p className="text-sm font-mono font-semibold" style={{ color: theme.foreground }}>{shortenAddress(walletAddress)}</p>
529
540
  </div>
530
541
  </div>
531
542
  <button
532
543
  onClick={handleCopyAddress}
533
- className="p-2 rounded-lg text-gray-400 hover:text-white hover:bg-gray-700 transition-all"
544
+ className="p-2 rounded-lg transition-all"
545
+ style={{ color: theme.mutedForeground }}
534
546
  title={walletAddress}
535
547
  >
536
548
  {copied ? <CheckCircle className="w-5 h-5" style={{ color: accentColor2 }} /> : <Copy className="w-5 h-5" />}
@@ -539,28 +551,28 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
539
551
  </div>
540
552
 
541
553
  {/* Main Content */}
542
- <div className={`p-6 space-y-6 ${compactMode ? 'max-w-3xl' : ''}`} style={{backgroundColor: 'rgba(31, 41, 55, 0.2)'}}>
554
+ <div className={`p-6 space-y-6 ${compactMode ? 'max-w-3xl' : ''}`} style={{backgroundColor: theme.background}}>
543
555
  {/* Points Display */}
544
556
  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
545
557
  <div
546
558
  className="p-6 rounded-lg border text-center"
547
559
  style={{
548
560
  borderColor: accentColor,
549
- backgroundColor: 'rgba(47, 129, 247, 0.1)',
561
+ backgroundColor: theme.card,
550
562
  }}
551
563
  >
552
- <p className="text-sm text-gray-400 mb-2">Total Points</p>
564
+ <p className="text-sm mb-2" style={{ color: theme.mutedForeground }}>Total Points</p>
553
565
  <p className="text-4xl font-bold" style={{ color: accentColor }}>
554
566
  {data.totalPoints.toLocaleString()}
555
567
  </p>
556
- <div className="flex items-center justify-center gap-1 mt-2 text-xs text-gray-400">
568
+ <div className="flex items-center justify-center gap-1 mt-2 text-xs" style={{ color: theme.mutedForeground }}>
557
569
  <TrendingUp className="w-4 h-4" />
558
570
  <span>Keep earning rewards</span>
559
571
  </div>
560
572
  </div>
561
573
 
562
574
  {!hideTier && (
563
- <TierCard tier={data.tier} accentColor={accentColor2} />
575
+ <TierCard tier={data.tier} accentColor={accentColor2} theme={theme} />
564
576
  )}
565
577
  </div>
566
578
 
@@ -569,11 +581,11 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
569
581
  <div>
570
582
  <div className="flex items-center gap-2 mb-4">
571
583
  <Award className="w-5 h-5" style={{ color: accentColor }} />
572
- <h3 className="text-lg font-semibold text-white">
584
+ <h3 className="text-lg font-semibold" style={{ color: theme.foreground }}>
573
585
  Badges ({data.badges.length})
574
586
  </h3>
575
587
  </div>
576
- <BadgeGrid badges={data.badges} compactMode={compactMode} />
588
+ <BadgeGrid badges={data.badges} theme={theme} compactMode={compactMode} />
577
589
  </div>
578
590
  )}
579
591
 
@@ -582,18 +594,19 @@ export const RewardsDashboard: React.FC<RewardsDashboardProps> = ({
582
594
  <div>
583
595
  <div className="flex items-center gap-2 mb-4">
584
596
  <Zap className="w-5 h-5" style={{ color: accentColor2 }} />
585
- <h3 className="text-lg font-semibold text-white">Recent Rewards</h3>
597
+ <h3 className="text-lg font-semibold" style={{ color: theme.foreground }}>Recent Rewards</h3>
586
598
  </div>
587
599
  <RewardHistory
588
600
  items={compactMode ? data.rewardHistory.slice(0, 3) : data.rewardHistory}
589
601
  accentColor={accentColor}
602
+ theme={theme}
590
603
  />
591
604
  </div>
592
605
  )}
593
606
  </div>
594
607
 
595
608
  {/* Footer */}
596
- <div className="px-6 py-3 border-t border-gray-700 flex items-center justify-between text-xs text-gray-500">
609
+ <div className="px-6 py-3 border-t flex items-center justify-between text-xs" style={{ borderColor: theme.border, color: theme.mutedForeground }}>
597
610
  <span>Last updated: {formatDate(data.lastUpdated)}</span>
598
611
  <span className="flex items-center gap-1">
599
612
  <ExternalLink className="w-3 h-3" />
package/src/index.ts CHANGED
@@ -14,9 +14,13 @@ export type { RewardsDashboardProps, Badge, RewardHistoryItem, TierInfo, Dashboa
14
14
  export { Leaderboard } from './Leaderboard.js';
15
15
  export type { LeaderboardProps, LeaderboardEntry, LeaderboardTimeframe } from './Leaderboard.js';
16
16
 
17
+ // Export page components
18
+ export { RewardsDashboardPage } from './pages/RewardsDashboardPage.js';
19
+ export { LeaderboardPage } from './pages/LeaderboardPage.js';
20
+
17
21
  // Export theme utilities
18
22
  export { getThemeColors, getThemeStylesheet, createThemeStyles } from './theme.js';
19
23
  export type { ThemeColors } from './theme.js';
20
24
 
21
25
  // Version info
22
- export const PACKAGE_VERSION = '1.0.0';
26
+ export const PACKAGE_VERSION = '1.3.0';