From 309c29276489b30e626984fa2cfbacb9fabaf1b2 Mon Sep 17 00:00:00 2001 From: Madeleine Charity Date: Wed, 25 Feb 2026 11:09:42 -0500 Subject: [PATCH 1/2] fix: design polish for yield demo cards, headers, and transaction history Add consistent border to all dashboard cards, sentence-case section headers, and redesign transaction history rows to show sentence-style amounts with date column and status-only tags. Co-Authored-By: Claude Opus 4.6 Committed-By-Agent: claude --- .../privy-next-yield-demo/src/app/globals.css | 14 --- .../src/components/FeeRecipientCard.tsx | 16 +-- .../src/components/PositionDisplay.tsx | 16 +-- .../src/components/TransactionHistory.tsx | 99 ++++++++----------- .../src/components/WalletCard.tsx | 4 +- .../src/components/ui/fullscreen-loader.tsx | 2 +- .../src/components/ui/header.tsx | 10 +- .../src/lib/constants.ts | 2 - 8 files changed, 64 insertions(+), 99 deletions(-) diff --git a/examples/privy-next-yield-demo/src/app/globals.css b/examples/privy-next-yield-demo/src/app/globals.css index dccdaa7..a9eb2f4 100644 --- a/examples/privy-next-yield-demo/src/app/globals.css +++ b/examples/privy-next-yield-demo/src/app/globals.css @@ -35,20 +35,6 @@ button, a, input, select, textarea { text-sm leading-5 cursor-pointer; } - .button { - @apply flex flex-row items-center - px-3 py-2 gap-3 cursor-pointer - bg-white border border-[#E2E3F0] rounded-xl - text-[#040217] font-normal text-base leading-6 - hover:bg-gray-50 hover:border-gray-300 - focus:bg-gray-50 focus:border-gray-300 - active:bg-gray-100 - focus:outline-none focus:ring-2 focus:ring-gray-300 focus:ring-offset-2 - transition-all duration-200 ease-in-out - disabled:opacity-50 disabled:cursor-not-allowed - box-border; - } - .text-primary { @apply text-[#5B4FFF]; } diff --git a/examples/privy-next-yield-demo/src/components/FeeRecipientCard.tsx b/examples/privy-next-yield-demo/src/components/FeeRecipientCard.tsx index 3b7dfca..f64c30c 100644 --- a/examples/privy-next-yield-demo/src/components/FeeRecipientCard.tsx +++ b/examples/privy-next-yield-demo/src/components/FeeRecipientCard.tsx @@ -50,8 +50,8 @@ export function FeeRecipientCard() { if (isLoading) { return ( -
-

Vault Info

+
+

Vault info

@@ -62,8 +62,8 @@ export function FeeRecipientCard() { if (error) { return ( -
-

Vault Info

+
+

Vault info

{error}

); @@ -71,17 +71,17 @@ export function FeeRecipientCard() { if (!vaultInfo || !vaultId) { return ( -
-

Vault Info

+
+

Vault info

Vault not configured

); } return ( -
+
-

Vault Info

+

Vault info

diff --git a/examples/privy-next-yield-demo/src/components/PositionDisplay.tsx b/examples/privy-next-yield-demo/src/components/PositionDisplay.tsx index d9a4125..6b1f530 100644 --- a/examples/privy-next-yield-demo/src/components/PositionDisplay.tsx +++ b/examples/privy-next-yield-demo/src/components/PositionDisplay.tsx @@ -62,8 +62,8 @@ export function PositionDisplay({ walletId }: { walletId?: string } = {}) { if (isLoading) { return ( -
-

Your Position

+
+

Your position

@@ -75,8 +75,8 @@ export function PositionDisplay({ walletId }: { walletId?: string } = {}) { if (error) { return ( -
-

Your Position

+
+

Your position

{error}

); @@ -84,8 +84,8 @@ export function PositionDisplay({ walletId }: { walletId?: string } = {}) { if (!position || !vaultId) { return ( -
-

Your Position

+
+

Your position

{!vaultId ? 'Vault not configured' : 'No active position'}

@@ -94,9 +94,9 @@ export function PositionDisplay({ walletId }: { walletId?: string } = {}) { } return ( -
+
-

Your Position

+

Your position

diff --git a/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx b/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx index 6f0c526..78b6c05 100644 --- a/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx +++ b/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx @@ -2,7 +2,7 @@ import { useEffect, useState, useCallback } from "react"; import { usePrivy } from "@privy-io/react-auth"; -import { formatUSDC, truncateAddress } from "@/lib/constants"; +import { formatUSDC } from "@/lib/constants"; interface Transaction { id: string; @@ -19,43 +19,33 @@ interface Transaction { function formatTimestamp(unixSeconds: number): string { const date = new Date(unixSeconds * 1000); - return date.toLocaleDateString("en-US", { - month: "short", - day: "numeric", - hour: "2-digit", - minute: "2-digit", - }); -} - -function TypeBadge({ type }: { type: string }) { - const isDeposit = type === "deposit"; - return ( - - {isDeposit ? "Deposit" : "Withdrawal"} - - ); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + const year = String(date.getFullYear()).slice(-2); + const hours = date.getHours(); + const minutes = String(date.getMinutes()).padStart(2, "0"); + const ampm = hours >= 12 ? "PM" : "AM"; + const displayHours = String(hours % 12 || 12).padStart(2, "0"); + return `${month}/${day}/${year} ${displayHours}:${minutes} ${ampm}`; } function StatusBadge({ status }: { status: string }) { - const styles: Record = { - pending: "bg-[#FEF3C7] text-[#906218]", - confirmed: "bg-[#DCFCE7] text-[#135638]", - failed: "bg-[#FEE2E2] text-[#991B1B]", + const config: Record = { + pending: { style: "bg-[#FEF3C7] text-[#906218]", label: "Pending" }, + confirmed: { style: "bg-[#DCFCE7] text-[#135638]", label: "Successful" }, + failed: { style: "bg-[#FEE2E2] text-[#991B1B]", label: "Failed" }, + }; + + const { style, label } = config[status] ?? { + style: "bg-[#F1F2F9] text-[#64668B]", + label: status, }; return ( - {status} + {label} ); } @@ -114,9 +104,9 @@ export function TransactionHistory({ if (isLoading) { return ( -
+

- Transaction History + Transaction history

@@ -129,9 +119,9 @@ export function TransactionHistory({ if (error) { return ( -
+

- Transaction History + Transaction history

{error}

@@ -140,9 +130,9 @@ export function TransactionHistory({ if (transactions.length === 0) { return ( -
+

- Transaction History + Transaction history

No transactions yet. Make a deposit or withdrawal to get started. @@ -152,37 +142,32 @@ export function TransactionHistory({ } return ( -

+

- Transaction History + Transaction history

-
- {transactions.map((tx) => { +
+ {transactions.map((tx, index) => { const isDeposit = tx.type === "deposit"; - const sign = isDeposit ? "+" : "-"; return (
-
-
-
- - -
-
-
- - - {sign}${formatUSDC(tx.asset_amount)} USDC + + {isDeposit ? "Deposited" : "Withdrew"} $ + {formatUSDC(tx.asset_amount)} USDC + + + {formatTimestamp(tx.created_at)} +
); })} diff --git a/examples/privy-next-yield-demo/src/components/WalletCard.tsx b/examples/privy-next-yield-demo/src/components/WalletCard.tsx index aa369e1..8e1cefa 100644 --- a/examples/privy-next-yield-demo/src/components/WalletCard.tsx +++ b/examples/privy-next-yield-demo/src/components/WalletCard.tsx @@ -78,10 +78,10 @@ export function WalletCard() { }; return ( -
+
-

Your Wallet

+

Your wallet

{walletAddress ? truncateAddress(walletAddress) : 'No wallet'} diff --git a/examples/privy-next-yield-demo/src/components/ui/fullscreen-loader.tsx b/examples/privy-next-yield-demo/src/components/ui/fullscreen-loader.tsx index 8270059..df9449a 100644 --- a/examples/privy-next-yield-demo/src/components/ui/fullscreen-loader.tsx +++ b/examples/privy-next-yield-demo/src/components/ui/fullscreen-loader.tsx @@ -18,7 +18,7 @@ export const FullScreenLoader = () => { d="M 28.746094 0.015625 C 28.359375 0.03125 27.722656 0.0703125 27.363281 0.105469 C 22.929688 0.515625 18.730469 2.207031 15.242188 4.992188 C 10.347656 8.894531 7.28125 14.597656 6.730469 20.804688 C 6.667969 21.515625 6.648438 21.972656 6.648438 22.863281 C 6.648438 23.753906 6.667969 24.207031 6.730469 24.929688 C 7.152344 29.683594 9.066406 34.183594 12.210938 37.816406 C 13.949219 39.832031 16.046875 41.53125 18.394531 42.84375 C 18.953125 43.15625 19.9375 43.636719 20.53125 43.890625 C 22.722656 44.820312 25.042969 45.40625 27.398438 45.617188 C 28.769531 45.746094 30.207031 45.746094 31.578125 45.617188 C 35.304688 45.28125 38.875 44.035156 42.035156 41.964844 C 43.890625 40.75 45.613281 39.210938 47.058594 37.476562 C 49.902344 34.066406 51.683594 29.910156 52.1875 25.5 C 52.386719 23.769531 52.386719 21.882812 52.179688 20.144531 C 51.65625 15.714844 49.839844 11.539062 46.96875 8.132812 C 46.183594 7.207031 45.144531 6.164062 44.21875 5.382812 C 42.054688 3.558594 39.523438 2.128906 36.859375 1.222656 C 34.933594 0.570312 33.109375 0.207031 31.019531 0.0585938 C 30.558594 0.0234375 29.148438 -0.00390625 28.746094 0.015625 Z M 28.746094 0.015625 " /> -
+
Privy Logo Yield Demo
@@ -78,7 +74,7 @@ export function Header({ authenticated, onLogout }: HeaderProps) { )} -
+
Date: Wed, 25 Feb 2026 11:27:29 -0500 Subject: [PATCH 2/2] fix: handle millisecond timestamps in transaction history The Privy API and webhook Date.now() fallback both return timestamps in milliseconds, but formatTimestamp assumed seconds. Auto-detect the format so dates display correctly. Co-Authored-By: Claude Opus 4.6 Committed-By-Agent: claude --- .../src/components/TransactionHistory.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx b/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx index 78b6c05..9149e10 100644 --- a/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx +++ b/examples/privy-next-yield-demo/src/components/TransactionHistory.tsx @@ -17,8 +17,10 @@ interface Transaction { updated_at: number; } -function formatTimestamp(unixSeconds: number): string { - const date = new Date(unixSeconds * 1000); +function formatTimestamp(timestamp: number): string { + // Handle both seconds and milliseconds: if > 1e12, it's already ms + const ms = timestamp > 1e12 ? timestamp : timestamp * 1000; + const date = new Date(ms); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); const year = String(date.getFullYear()).slice(-2);