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:
2026-01-30 03:49:53 +00:00
parent 098a91f2ac
commit 9e0dd1d278
27 changed files with 11184 additions and 7928 deletions

View File

@@ -1,101 +1,101 @@
"use client";
import { useState } from "react";
import { useApp } from "@/contexts/AppContext";
export default function APYHistoryCard() {
const { t } = useApp();
const [activeTab, setActiveTab] = useState<"apy" | "price">("apy");
// 橙色渐变条形图数据
const chartData = [
{ height: 85, color: "#ffe9dc" },
{ height: 93, color: "#ffc9ad" },
{ height: 100, color: "#ffc9ad" },
{ height: 105, color: "#ffba96" },
{ height: 108, color: "#ffa67e" },
{ height: 116, color: "#f48d5f" },
{ height: 124, color: "#ff6900" },
{ height: 127, color: "#f35b00" },
{ height: 139, color: "#d64700" },
];
return (
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-6 flex flex-col gap-6">
{/* Tabs */}
<div className="flex gap-6 border-b border-border-gray dark:border-gray-700">
<button
onClick={() => setActiveTab("apy")}
className={`pb-3 px-1 text-body-small font-bold transition-colors ${
activeTab === "apy"
? "text-text-primary dark:text-white border-b-2 border-text-primary dark:border-white -mb-[1px]"
: "text-text-tertiary dark:text-gray-400"
}`}
>
{t("apy.apyHistory")}
</button>
<button
onClick={() => setActiveTab("price")}
className={`pb-3 px-1 text-body-small font-bold transition-colors ${
activeTab === "price"
? "text-text-primary dark:text-white border-b-2 border-text-primary dark:border-white -mb-[1px]"
: "text-text-tertiary dark:text-gray-400"
}`}
>
{t("apy.priceHistory")}
</button>
</div>
{/* Chart Area */}
<div className="flex flex-col gap-4">
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.lastDays")}
</span>
</div>
{/* Orange Gradient Chart */}
<div
className="flex items-end gap-4 w-full border-b border-border-gray dark:border-gray-700"
style={{
height: "140px",
background:
"linear-gradient(0deg, rgba(255, 247, 237, 0.5) 0%, rgba(255, 247, 237, 0) 100%)",
}}
>
{chartData.map((bar, index) => (
<div
key={index}
className="flex-1"
style={{
height: `${bar.height}px`,
backgroundColor: bar.color,
borderRadius: "2px 2px 0px 0px",
}}
/>
))}
</div>
{/* Stats */}
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.highest")}
</span>
<span className="text-body-small font-bold text-text-primary dark:text-white">
24.8%
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.lowest")}
</span>
<span className="text-body-small font-bold text-text-primary dark:text-white">
18.2%
</span>
</div>
</div>
</div>
</div>
);
}
"use client";
import { useState } from "react";
import { useApp } from "@/contexts/AppContext";
export default function APYHistoryCard() {
const { t } = useApp();
const [activeTab, setActiveTab] = useState<"apy" | "price">("apy");
// 橙色渐变条形图数据
const chartData = [
{ height: 85, color: "#ffe9dc" },
{ height: 93, color: "#ffc9ad" },
{ height: 100, color: "#ffc9ad" },
{ height: 105, color: "#ffba96" },
{ height: 108, color: "#ffa67e" },
{ height: 116, color: "#f48d5f" },
{ height: 124, color: "#ff6900" },
{ height: 127, color: "#f35b00" },
{ height: 139, color: "#d64700" },
];
return (
<div className="bg-bg-surface dark:bg-gray-800 rounded-3xl border border-border-gray dark:border-gray-700 p-6 flex flex-col gap-6">
{/* Tabs */}
<div className="flex gap-6 border-b border-border-gray dark:border-gray-700">
<button
onClick={() => setActiveTab("apy")}
className={`pb-3 px-1 text-body-small font-bold transition-colors ${
activeTab === "apy"
? "text-text-primary dark:text-white border-b-2 border-text-primary dark:border-white -mb-[1px]"
: "text-text-tertiary dark:text-gray-400"
}`}
>
{t("apy.apyHistory")}
</button>
<button
onClick={() => setActiveTab("price")}
className={`pb-3 px-1 text-body-small font-bold transition-colors ${
activeTab === "price"
? "text-text-primary dark:text-white border-b-2 border-text-primary dark:border-white -mb-[1px]"
: "text-text-tertiary dark:text-gray-400"
}`}
>
{t("apy.priceHistory")}
</button>
</div>
{/* Chart Area */}
<div className="flex flex-col gap-4">
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.lastDays")}
</span>
</div>
{/* Orange Gradient Chart */}
<div
className="flex items-end gap-4 w-full border-b border-border-gray dark:border-gray-700"
style={{
height: "140px",
background:
"linear-gradient(0deg, rgba(255, 247, 237, 0.5) 0%, rgba(255, 247, 237, 0) 100%)",
}}
>
{chartData.map((bar, index) => (
<div
key={index}
className="flex-1"
style={{
height: `${bar.height}px`,
backgroundColor: bar.color,
borderRadius: "2px 2px 0px 0px",
}}
/>
))}
</div>
{/* Stats */}
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.highest")}
</span>
<span className="text-body-small font-bold text-text-primary dark:text-white">
24.8%
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-caption-tiny font-medium text-text-tertiary dark:text-gray-400">
{t("apy.lowest")}
</span>
<span className="text-body-small font-bold text-text-primary dark:text-white">
18.2%
</span>
</div>
</div>
</div>
</div>
);
}