feat: integrate HeroUI component library
Implemented HeroUI migration plan with the following changes: Stage 0: Environment Setup - Installed @heroui/react@2.8.7, @heroui/theme@2.4.26, framer-motion@12.29.2 - Configured Tailwind with HeroUI plugin - Added HeroUI content paths to Tailwind config Stage 1: Provider Architecture - Created Providers.tsx wrapper combining HeroUIProvider and AppProvider - Updated app/layout.tsx to use new Providers component - Preserved all AppContext functionality (theme, language, translations) Stage 2: Component Migrations - TabNavigation: Migrated to HeroUI Tabs with keyboard navigation support - TopBar: Migrated buttons to HeroUI Button components - LanguageSwitch: Migrated to HeroUI Dropdown for better UX - ThemeSwitch: Migrated to HeroUI Button (isIconOnly variant) - MintSwapPanel: Migrated to HeroUI Tabs and Button components Benefits: - Enhanced accessibility with ARIA attributes and keyboard navigation - Smooth animations and transitions via Framer Motion - Consistent component API across the application - Maintained all existing design tokens and color system - Preserved dark mode functionality Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,237 +1,237 @@
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { useApp } from "@/contexts/AppContext";
|
||||
|
||||
interface VerificationCardProps {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
}
|
||||
|
||||
function VerificationCard({ icon, title, description, buttonText }: VerificationCardProps) {
|
||||
return (
|
||||
<div className="flex-1 bg-bg-surface dark:bg-gray-700 rounded-2xl border border-border-normal dark:border-gray-600 p-6 flex flex-col justify-between">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-5 h-5 flex-shrink-0">
|
||||
<Image src={icon} alt={title} width={20} height={20} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<h4 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{title}
|
||||
</h4>
|
||||
<p className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button className="flex items-center gap-2 hover:opacity-80 transition-opacity mt-[118px]">
|
||||
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9ca1af] dark:text-gray-400">
|
||||
{buttonText}
|
||||
</span>
|
||||
<Image src="/component-118.svg" alt="" width={16} height={16} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AssetCustodyVerification() {
|
||||
const { t } = useApp();
|
||||
return (
|
||||
<div className="flex flex-col gap-8 w-full">
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-2">
|
||||
<h2 className="text-body-large font-bold text-text-primary dark:text-white">
|
||||
{t("custody.title")}
|
||||
</h2>
|
||||
<p className="text-body-small font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Holdings Table Card */}
|
||||
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-8 flex flex-col gap-6">
|
||||
{/* Table Header */}
|
||||
<div className="flex flex-col gap-6 pb-6 border-b border-border-gray dark:border-gray-700">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h3 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{t("custody.underlyingHoldings")}
|
||||
</h3>
|
||||
<p className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.verifiedBy")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src="/component-115.svg" alt="" width={16} height={16} />
|
||||
<span className="text-caption-tiny font-medium text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.lastUpdated")}: 2 {t("custody.minutesAgo")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table */}
|
||||
<div className="flex flex-col">
|
||||
{/* Table Header Row */}
|
||||
<div className="grid grid-cols-5 gap-4 pb-4 border-b border-border-gray dark:border-gray-700">
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.custodian")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.assetType")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.maturity")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.valueUSD")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.status")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table Body Row */}
|
||||
<div className="grid grid-cols-5 gap-4 py-6">
|
||||
{/* Custodian */}
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0"
|
||||
style={{
|
||||
background: "linear-gradient(135deg, rgba(255, 137, 4, 1) 0%, rgba(245, 73, 0, 1) 100%)",
|
||||
}}
|
||||
>
|
||||
<span className="text-[13.5px] font-bold leading-[19px] text-white tracking-tight">
|
||||
GY
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.morganStanley")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.primeBroker")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Asset Type */}
|
||||
<div className="flex items-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
{t("custody.usEquityPortfolio")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Maturity */}
|
||||
<div className="flex flex-col justify-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
05 Feb 2026
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
(77 {t("custody.days")})
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Value */}
|
||||
<div className="flex items-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
$12,500,000.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Status */}
|
||||
<div className="flex items-center">
|
||||
<div className="rounded-full px-3 py-1.5 flex items-center gap-2 bg-[#f2fcf7] dark:bg-green-900/20">
|
||||
<Image src="/component-116.svg" alt="" width={12} height={12} />
|
||||
<span className="text-[10px] font-bold leading-[150%] text-[#10b981] dark:text-green-400">
|
||||
{t("custody.verified")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table Footer Row */}
|
||||
<div className="grid grid-cols-5 gap-4 pt-6 border-t border-border-gray dark:border-gray-700">
|
||||
<div className="col-span-3 flex items-center">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.totalValue")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="col-span-2 flex items-center">
|
||||
<span className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
$12,500,000.00
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Verification Cards Row */}
|
||||
<div className="flex flex-row gap-6 pt-6">
|
||||
<VerificationCard
|
||||
icon="/component-117.svg"
|
||||
title={t("custody.smartContract")}
|
||||
description={t("custody.smartContractDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
<VerificationCard
|
||||
icon="/component-119.svg"
|
||||
title={t("custody.compliance")}
|
||||
description={t("custody.complianceDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
<VerificationCard
|
||||
icon="/component-121.svg"
|
||||
title={t("custody.proofOfReserves")}
|
||||
description={t("custody.proofDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
|
||||
{/* Independent Verifications */}
|
||||
<div className="flex-1 rounded-2xl border bg-[#f9fafb] dark:bg-gray-700 border-[#e5e7eb] dark:border-gray-600 p-6 flex flex-col">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{t("custody.independentVerifications")}
|
||||
</h3>
|
||||
<p className="text-body-small font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.independentDesc")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 mt-6">
|
||||
<div className="rounded-2xl border bg-white dark:bg-gray-800 border-[#e5e7eb] dark:border-gray-600 p-4 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.attestationReport")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
November 2025
|
||||
</span>
|
||||
</div>
|
||||
<Image src="/component-123.svg" alt="" width={24} height={24} />
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border bg-white dark:bg-gray-800 border-[#e5e7eb] dark:border-gray-600 p-4 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.attestationReport")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
October 2025
|
||||
</span>
|
||||
</div>
|
||||
<Image src="/component-124.svg" alt="" width={24} height={24} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="flex items-center gap-2 hover:opacity-80 transition-opacity mt-4">
|
||||
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.viewAllArchive")}
|
||||
</span>
|
||||
<Image src="/component-125.svg" alt="" width={16} height={16} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
"use client";
|
||||
|
||||
import Image from "next/image";
|
||||
import { useApp } from "@/contexts/AppContext";
|
||||
|
||||
interface VerificationCardProps {
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
buttonText: string;
|
||||
}
|
||||
|
||||
function VerificationCard({ icon, title, description, buttonText }: VerificationCardProps) {
|
||||
return (
|
||||
<div className="flex-1 bg-bg-surface dark:bg-gray-700 rounded-2xl border border-border-normal dark:border-gray-600 p-6 flex flex-col justify-between">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-5 h-5 flex-shrink-0">
|
||||
<Image src={icon} alt={title} width={20} height={20} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-1">
|
||||
<h4 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{title}
|
||||
</h4>
|
||||
<p className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button className="flex items-center gap-2 hover:opacity-80 transition-opacity mt-[118px]">
|
||||
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9ca1af] dark:text-gray-400">
|
||||
{buttonText}
|
||||
</span>
|
||||
<Image src="/component-118.svg" alt="" width={16} height={16} />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AssetCustodyVerification() {
|
||||
const { t } = useApp();
|
||||
return (
|
||||
<div className="flex flex-col gap-8 w-full">
|
||||
{/* Header */}
|
||||
<div className="flex flex-col gap-2">
|
||||
<h2 className="text-body-large font-bold text-text-primary dark:text-white">
|
||||
{t("custody.title")}
|
||||
</h2>
|
||||
<p className="text-body-small font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.description")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Holdings Table Card */}
|
||||
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-8 flex flex-col gap-6">
|
||||
{/* Table Header */}
|
||||
<div className="flex flex-col gap-6 pb-6 border-b border-border-gray dark:border-gray-700">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h3 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{t("custody.underlyingHoldings")}
|
||||
</h3>
|
||||
<p className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.verifiedBy")}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Image src="/component-115.svg" alt="" width={16} height={16} />
|
||||
<span className="text-caption-tiny font-medium text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.lastUpdated")}: 2 {t("custody.minutesAgo")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table */}
|
||||
<div className="flex flex-col">
|
||||
{/* Table Header Row */}
|
||||
<div className="grid grid-cols-5 gap-4 pb-4 border-b border-border-gray dark:border-gray-700">
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.custodian")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.assetType")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.maturity")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.valueUSD")}
|
||||
</div>
|
||||
<div className="text-caption-tiny font-bold uppercase tracking-wider text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.status")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table Body Row */}
|
||||
<div className="grid grid-cols-5 gap-4 py-6">
|
||||
{/* Custodian */}
|
||||
<div className="flex items-center gap-3">
|
||||
<div
|
||||
className="w-8 h-8 rounded-full flex items-center justify-center flex-shrink-0"
|
||||
style={{
|
||||
background: "linear-gradient(135deg, rgba(255, 137, 4, 1) 0%, rgba(245, 73, 0, 1) 100%)",
|
||||
}}
|
||||
>
|
||||
<span className="text-[13.5px] font-bold leading-[19px] text-white tracking-tight">
|
||||
GY
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.morganStanley")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.primeBroker")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Asset Type */}
|
||||
<div className="flex items-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
{t("custody.usEquityPortfolio")}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Maturity */}
|
||||
<div className="flex flex-col justify-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
05 Feb 2026
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
(77 {t("custody.days")})
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Value */}
|
||||
<div className="flex items-center">
|
||||
<span className="text-body-small font-medium text-text-primary dark:text-white">
|
||||
$12,500,000.00
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Status */}
|
||||
<div className="flex items-center">
|
||||
<div className="rounded-full px-3 py-1.5 flex items-center gap-2 bg-[#f2fcf7] dark:bg-green-900/20">
|
||||
<Image src="/component-116.svg" alt="" width={12} height={12} />
|
||||
<span className="text-[10px] font-bold leading-[150%] text-[#10b981] dark:text-green-400">
|
||||
{t("custody.verified")}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Table Footer Row */}
|
||||
<div className="grid grid-cols-5 gap-4 pt-6 border-t border-border-gray dark:border-gray-700">
|
||||
<div className="col-span-3 flex items-center">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.totalValue")}
|
||||
</span>
|
||||
</div>
|
||||
<div className="col-span-2 flex items-center">
|
||||
<span className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
$12,500,000.00
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Verification Cards Row */}
|
||||
<div className="flex flex-row gap-6 pt-6">
|
||||
<VerificationCard
|
||||
icon="/component-117.svg"
|
||||
title={t("custody.smartContract")}
|
||||
description={t("custody.smartContractDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
<VerificationCard
|
||||
icon="/component-119.svg"
|
||||
title={t("custody.compliance")}
|
||||
description={t("custody.complianceDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
<VerificationCard
|
||||
icon="/component-121.svg"
|
||||
title={t("custody.proofOfReserves")}
|
||||
description={t("custody.proofDesc")}
|
||||
buttonText={t("custody.viewReports")}
|
||||
/>
|
||||
|
||||
{/* Independent Verifications */}
|
||||
<div className="flex-1 rounded-2xl border bg-[#f9fafb] dark:bg-gray-700 border-[#e5e7eb] dark:border-gray-600 p-6 flex flex-col">
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="text-body-default font-bold text-text-primary dark:text-white">
|
||||
{t("custody.independentVerifications")}
|
||||
</h3>
|
||||
<p className="text-body-small font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.independentDesc")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2 mt-6">
|
||||
<div className="rounded-2xl border bg-white dark:bg-gray-800 border-[#e5e7eb] dark:border-gray-600 p-4 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.attestationReport")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
November 2025
|
||||
</span>
|
||||
</div>
|
||||
<Image src="/component-123.svg" alt="" width={24} height={24} />
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border bg-white dark:bg-gray-800 border-[#e5e7eb] dark:border-gray-600 p-4 flex items-center justify-between">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className="text-body-small font-bold text-text-primary dark:text-white">
|
||||
{t("custody.attestationReport")}
|
||||
</span>
|
||||
<span className="text-caption-tiny font-regular text-[#9ca1af] dark:text-gray-400">
|
||||
October 2025
|
||||
</span>
|
||||
</div>
|
||||
<Image src="/component-124.svg" alt="" width={24} height={24} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button className="flex items-center gap-2 hover:opacity-80 transition-opacity mt-4">
|
||||
<span className="text-[10px] font-bold leading-[150%] tracking-[0.01em] text-[#9ca1af] dark:text-gray-400">
|
||||
{t("custody.viewAllArchive")}
|
||||
</span>
|
||||
<Image src="/component-125.svg" alt="" width={16} height={16} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user