|
1 | 1 | "use client"; |
2 | 2 |
|
3 | 3 | import { useState } from "react"; |
4 | | -import { GlowButton, DashboardGrid, DashboardStat } from "@castquest/neo-ux-core"; |
5 | | -import { FrameCard, QuestCard, MediaCard } from "../components/Cards"; |
6 | | -import { useMockFrames, useMockQuests, useMockMedia, useMockStats } from "../hooks/useMockData"; |
7 | | -import { neo } from "@castquest/neo-ux-core"; |
| 4 | +import { |
| 5 | + Button, |
| 6 | + Card, |
| 7 | + Badge, |
| 8 | + Surface, |
| 9 | + Navbar, |
| 10 | +} from "@castquest/neo-ux-core"; |
| 11 | + |
| 12 | +import { |
| 13 | + FrameCard, |
| 14 | + QuestCard, |
| 15 | + MediaCard |
| 16 | +} from "../components/Cards"; |
| 17 | + |
| 18 | +import { |
| 19 | + useMockFrames, |
| 20 | + useMockQuests, |
| 21 | + useMockMedia, |
| 22 | + useMockStats |
| 23 | +} from "../hooks/useMockData"; |
8 | 24 |
|
9 | 25 | export default function WebFrontMega() { |
10 | 26 | const { frames, loading: framesLoading } = useMockFrames(); |
11 | 27 | const { quests, loading: questsLoading } = useMockQuests(); |
12 | 28 | const { media, loading: mediaLoading } = useMockMedia(); |
13 | 29 | const { stats } = useMockStats(); |
14 | | - const [activeTab, setActiveTab] = useState<"frames" | "quests" | "media">("frames"); |
| 30 | + |
| 31 | + const [activeTab, setActiveTab] = |
| 32 | + useState<"frames" | "quests" | "media">("frames"); |
15 | 33 |
|
16 | 34 | return ( |
17 | | - <div className="min-h-screen"> |
18 | | - {/* Hero Section */} |
| 35 | + <div className="min-h-screen bg-[var(--neo-bg)] text-[var(--neo-text-primary)]"> |
| 36 | + |
| 37 | + {/* NAVBAR */} |
| 38 | + <Navbar |
| 39 | + logo={<span style={{ fontWeight: 700 }}>CastQuest</span>} |
| 40 | + links={[ |
| 41 | + { label: "Home", href: "/", active: true }, |
| 42 | + { label: "Dashboard", href: "/dashboard" }, |
| 43 | + { label: "Agents", href: "/dashboard/agents" }, |
| 44 | + { label: "Frames", href: "/dashboard/frames" } |
| 45 | + ]} |
| 46 | + rightSlot={<Badge label="V3" tone="accent" />} |
| 47 | + /> |
| 48 | + |
| 49 | + {/* HERO */} |
19 | 50 | <section className="relative min-h-[80vh] flex items-center justify-center overflow-hidden"> |
20 | | - {/* Animated Background */} |
21 | | - <div className="absolute inset-0 bg-gradient-to-br from-black via-neutral-900 to-black"> |
22 | | - <div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(16,185,129,0.1),transparent_50%)]" /> |
23 | | - <div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_50%,rgba(139,92,246,0.1),transparent_50%)]" /> |
24 | | - </div> |
25 | 51 |
|
26 | | - {/* Grid Pattern Overlay */} |
27 | | - <div className="absolute inset-0 opacity-10" style={{ |
28 | | - backgroundImage: 'linear-gradient(rgba(16,185,129,0.1) 1px, transparent 1px), linear-gradient(90deg, rgba(16,185,129,0.1) 1px, transparent 1px)', |
29 | | - backgroundSize: '50px 50px' |
30 | | - }} /> |
| 52 | + {/* Background */} |
| 53 | + <div className="absolute inset-0 bg-gradient-to-br from-black via-neutral-900 to-black" /> |
| 54 | + <div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(16,185,129,0.1),transparent_50%)]" /> |
| 55 | + <div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_50%,rgba(139,92,246,0.1),transparent_50%)]" /> |
| 56 | + |
| 57 | + {/* Grid overlay */} |
| 58 | + <div |
| 59 | + className="absolute inset-0 opacity-10" |
| 60 | + style={{ |
| 61 | + backgroundImage: |
| 62 | + "linear-gradient(rgba(16,185,129,0.1) 1px, transparent 1px), linear-gradient(90deg, rgba(16,185,129,0.1) 1px, transparent 1px)", |
| 63 | + backgroundSize: "50px 50px", |
| 64 | + }} |
| 65 | + /> |
31 | 66 |
|
32 | | - {/* Hero Content */} |
| 67 | + {/* Content */} |
33 | 68 | <div className="relative z-10 max-w-5xl mx-auto px-6 text-center"> |
34 | | - <div className={`inline-block mb-6 px-4 py-2 rounded-full border ${neo.colors.border.glow} ${neo.glow.success} bg-emerald-500/10`}> |
35 | | - <span className={`text-sm font-bold ${neo.colors.text.accent} uppercase tracking-wide`}> |
| 69 | + |
| 70 | + <div className="inline-block mb-6 px-4 py-2 rounded-full border border-[var(--neo-accent)] bg-[rgba(0,245,255,0.1)]"> |
| 71 | + <span className="text-sm font-bold text-[var(--neo-accent)] uppercase tracking-wide"> |
36 | 72 | 🚀 Decentralized Protocol Universe |
37 | 73 | </span> |
38 | 74 | </div> |
39 | | - |
40 | | - <h1 className={`text-5xl md:text-7xl font-bold mb-6 bg-gradient-to-r from-emerald-400 via-cyan-400 to-purple-400 bg-clip-text text-transparent ${neo.animation.pulse}`}> |
| 75 | + |
| 76 | + <h1 className="text-5xl md:text-7xl font-bold mb-6 bg-gradient-to-r from-emerald-400 via-cyan-400 to-purple-400 bg-clip-text text-transparent"> |
41 | 77 | CastQuest |
42 | 78 | </h1> |
43 | | - |
44 | | - <p className={`text-xl md:text-2xl ${neo.colors.text.secondary} mb-4 max-w-3xl mx-auto`}> |
| 79 | + |
| 80 | + <p className="text-xl md:text-2xl text-[var(--neo-text-secondary)] mb-4 max-w-3xl mx-auto"> |
45 | 81 | Create, Cast, and Conquer in the Sovereign Web3 Media Hub |
46 | 82 | </p> |
47 | | - |
48 | | - <p className={`text-sm ${neo.colors.text.tertiary} mb-8 max-w-2xl mx-auto`}> |
49 | | - Powered by Farcaster, Zora, Solana, BASE, and the Neo Glow Protocol. |
50 | | - Build frames, complete quests, mint NFTs, and earn rewards in the decentralized ecosystem. |
| 83 | + |
| 84 | + <p className="text-sm text-[var(--neo-text-muted)] mb-8 max-w-2xl mx-auto"> |
| 85 | + Powered by Farcaster, Zora, Solana, BASE, and the Neo Glow Protocol. |
51 | 86 | </p> |
52 | 87 |
|
53 | 88 | <div className="flex gap-4 justify-center mb-12"> |
54 | | - <GlowButton onClick={() => window.location.href = "/dashboard"}> |
| 89 | + <Button variant="primary" onClick={() => window.location.href = "/dashboard"}> |
55 | 90 | 🎯 View Quests |
56 | | - </GlowButton> |
57 | | - <GlowButton onClick={() => window.location.href = "/admin/dashboard"}> |
| 91 | + </Button> |
| 92 | + <Button variant="outline" onClick={() => window.location.href = "/admin/dashboard"}> |
58 | 93 | ⚡ Operator Dashboard |
59 | | - </GlowButton> |
60 | | - </div> |
61 | | - |
62 | | - {/* Protocol Stats */} |
63 | | - <div className={`inline-block border ${neo.colors.border.glow} rounded-lg p-6 bg-black/40 backdrop-blur-sm ${neo.glow.idle}`}> |
64 | | - <DashboardGrid> |
65 | | - <DashboardStat |
66 | | - label="Total Frames" |
67 | | - value={stats?.totalFrames.toString() || "0"} |
68 | | - trend="up" |
69 | | - /> |
70 | | - <DashboardStat |
71 | | - label="Live Frames" |
72 | | - value={stats?.liveFrames.toString() || "0"} |
73 | | - trend="up" |
74 | | - /> |
75 | | - <DashboardStat |
76 | | - label="Active Quests" |
77 | | - value={stats?.activeQuests.toString() || "0"} |
78 | | - trend="neutral" |
79 | | - /> |
80 | | - <DashboardStat |
81 | | - label="Total Participants" |
82 | | - value={stats?.totalParticipants.toLocaleString() || "0"} |
83 | | - trend="up" |
84 | | - /> |
85 | | - </DashboardGrid> |
| 94 | + </Button> |
86 | 95 | </div> |
87 | | - </div> |
88 | 96 |
|
89 | | - {/* Scroll Indicator */} |
90 | | - <div className="absolute bottom-8 left-1/2 -translate-x-1/2"> |
91 | | - <div className={`${neo.animation.bounce} ${neo.colors.text.tertiary}`}> |
92 | | - <svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> |
93 | | - <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 14l-7 7m0 0l-7-7m7 7V3" /> |
94 | | - </svg> |
95 | | - </div> |
| 97 | + {/* Stats */} |
| 98 | + <Surface elevated glow style={{ display: "inline-block" }}> |
| 99 | + <div className="grid grid-cols-2 md:grid-cols-4 gap-6"> |
| 100 | + <Card title="Total Frames">{stats?.totalFrames ?? 0}</Card> |
| 101 | + <Card title="Live Frames">{stats?.liveFrames ?? 0}</Card> |
| 102 | + <Card title="Active Quests">{stats?.activeQuests ?? 0}</Card> |
| 103 | + <Card title="Participants">{stats?.totalParticipants?.toLocaleString() ?? 0}</Card> |
| 104 | + </div> |
| 105 | + </Surface> |
96 | 106 | </div> |
97 | 107 | </section> |
98 | 108 |
|
99 | | - {/* Content Sections */} |
| 109 | + {/* TABS */} |
100 | 110 | <section className="max-w-7xl mx-auto px-6 py-16"> |
101 | | - {/* Tab Navigation */} |
| 111 | + |
102 | 112 | <div className="flex justify-center gap-4 mb-12"> |
103 | 113 | {[ |
104 | 114 | { id: "frames", label: "🖼️ Frames", count: frames.length }, |
105 | 115 | { id: "quests", label: "🎯 Quests", count: quests.length }, |
106 | | - { id: "media", label: "📺 Media", count: media.length } |
| 116 | + { id: "media", label: "📺 Media", count: media.length }, |
107 | 117 | ].map((tab) => ( |
108 | | - <button |
| 118 | + <Button |
109 | 119 | key={tab.id} |
| 120 | + variant={activeTab === tab.id ? "primary" : "ghost"} |
110 | 121 | onClick={() => setActiveTab(tab.id as any)} |
111 | | - className={`px-6 py-3 rounded-lg font-semibold transition-all ${ |
112 | | - activeTab === tab.id |
113 | | - ? `${neo.colors.text.primary} bg-gradient-to-r from-purple-500/20 to-cyan-500/20 border ${neo.colors.border.glow} ${neo.glow.active}` |
114 | | - : `${neo.colors.text.tertiary} border border-neutral-800 hover:border-neutral-700` |
115 | | - }`} |
116 | 122 | > |
117 | 123 | {tab.label} |
118 | | - <span className={`ml-2 px-2 py-0.5 rounded-full text-xs ${ |
119 | | - activeTab === tab.id ? "bg-emerald-500/20 text-emerald-400" : "bg-neutral-800 text-neutral-500" |
120 | | - }`}> |
121 | | - {tab.count} |
122 | | - </span> |
123 | | - </button> |
| 124 | + <Badge |
| 125 | + label={String(tab.count)} |
| 126 | + tone={activeTab === tab.id ? "accent" : "neutral"} |
| 127 | + /> |
| 128 | + </Button> |
124 | 129 | ))} |
125 | 130 | </div> |
126 | 131 |
|
127 | | - {/* Frames Grid */} |
| 132 | + {/* FRAMES */} |
128 | 133 | {activeTab === "frames" && ( |
129 | 134 | <div> |
130 | | - <div className="flex items-center justify-between mb-6"> |
131 | | - <h2 className={`text-2xl font-bold ${neo.colors.text.primary}`}> |
132 | | - Featured Frames |
133 | | - </h2> |
134 | | - <span className={`text-sm ${neo.colors.text.tertiary}`}> |
135 | | - {framesLoading ? "Loading..." : `${frames.length} frames available`} |
136 | | - </span> |
137 | | - </div> |
| 135 | + <h2 className="text-2xl font-bold mb-6">Featured Frames</h2> |
138 | 136 | <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> |
139 | 137 | {frames.map((frame) => ( |
140 | | - <FrameCard |
141 | | - key={frame.id} |
142 | | - frame={frame} |
143 | | - onView={() => console.log("View frame:", frame.id)} |
144 | | - onCast={() => console.log("Cast frame:", frame.id)} |
145 | | - /> |
| 138 | + <FrameCard key={frame.id} frame={frame} /> |
146 | 139 | ))} |
147 | 140 | </div> |
148 | 141 | </div> |
149 | 142 | )} |
150 | 143 |
|
151 | | - {/* Quests Grid */} |
| 144 | + {/* QUESTS */} |
152 | 145 | {activeTab === "quests" && ( |
153 | 146 | <div> |
154 | | - <div className="flex items-center justify-between mb-6"> |
155 | | - <h2 className={`text-2xl font-bold ${neo.colors.text.primary}`}> |
156 | | - Active Quests |
157 | | - </h2> |
158 | | - <span className={`text-sm ${neo.colors.text.tertiary}`}> |
159 | | - {questsLoading ? "Loading..." : `${quests.filter(q => q.status === "active").length} active`} |
160 | | - </span> |
161 | | - </div> |
| 147 | + <h2 className="text-2xl font-bold mb-6">Active Quests</h2> |
162 | 148 | <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3"> |
163 | 149 | {quests.map((quest) => ( |
164 | | - <QuestCard |
165 | | - key={quest.id} |
166 | | - quest={quest} |
167 | | - onStart={() => console.log("Start quest:", quest.id)} |
168 | | - /> |
| 150 | + <QuestCard key={quest.id} quest={quest} /> |
169 | 151 | ))} |
170 | 152 | </div> |
171 | 153 | </div> |
172 | 154 | )} |
173 | 155 |
|
174 | | - {/* Media Grid */} |
| 156 | + {/* MEDIA */} |
175 | 157 | {activeTab === "media" && ( |
176 | 158 | <div> |
177 | | - <div className="flex items-center justify-between mb-6"> |
178 | | - <h2 className={`text-2xl font-bold ${neo.colors.text.primary}`}> |
179 | | - Protocol Media |
180 | | - </h2> |
181 | | - <span className={`text-sm ${neo.colors.text.tertiary}`}> |
182 | | - {mediaLoading ? "Loading..." : `${media.length} items`} |
183 | | - </span> |
184 | | - </div> |
| 159 | + <h2 className="text-2xl font-bold mb-6">Protocol Media</h2> |
185 | 160 | <div className="grid gap-6 md:grid-cols-3 lg:grid-cols-4"> |
186 | 161 | {media.map((item) => ( |
187 | | - <MediaCard |
188 | | - key={item.id} |
189 | | - media={item} |
190 | | - onPlay={() => console.log("Play media:", item.id)} |
191 | | - /> |
| 162 | + <MediaCard key={item.id} media={item} /> |
192 | 163 | ))} |
193 | 164 | </div> |
194 | 165 | </div> |
195 | 166 | )} |
196 | 167 | </section> |
197 | 168 |
|
198 | | - {/* CTA Section */} |
199 | | - <section className={`max-w-5xl mx-auto px-6 py-16 mb-16`}> |
200 | | - <div className={`border ${neo.colors.border.glow} rounded-2xl p-12 bg-gradient-to-br from-purple-500/10 to-cyan-500/10 ${neo.glow.active} text-center`}> |
201 | | - <h2 className={`text-3xl font-bold ${neo.colors.text.primary} mb-4`}> |
202 | | - Ready to Build on CastQuest? |
203 | | - </h2> |
204 | | - <p className={`text-lg ${neo.colors.text.secondary} mb-8 max-w-2xl mx-auto`}> |
205 | | - Join the decentralized protocol universe. Create frames, complete quests, |
206 | | - mint NFTs, and earn rewards across Farcaster, Zora, Solana, and BASE. |
| 169 | + {/* CTA */} |
| 170 | + <section className="max-w-5xl mx-auto px-6 py-16 mb-16"> |
| 171 | + <Surface elevated glow style={{ textAlign: "center", padding: "48px" }}> |
| 172 | + <h2 className="text-3xl font-bold mb-4">Ready to Build on CastQuest?</h2> |
| 173 | + <p className="text-lg text-[var(--neo-text-secondary)] mb-8 max-w-2xl mx-auto"> |
| 174 | + Join the decentralized protocol universe. |
207 | 175 | </p> |
208 | 176 | <div className="flex gap-4 justify-center"> |
209 | | - <GlowButton onClick={() => console.log("Get started")}> |
210 | | - 🚀 Get Started |
211 | | - </GlowButton> |
212 | | - <button className={`px-6 py-3 rounded-lg font-semibold border ${neo.colors.border.glow} ${neo.colors.text.secondary} hover:${neo.colors.text.primary} transition-all`}> |
213 | | - 📚 View Docs |
214 | | - </button> |
| 177 | + <Button variant="primary">🚀 Get Started</Button> |
| 178 | + <Button variant="outline">📚 View Docs</Button> |
215 | 179 | </div> |
216 | | - </div> |
| 180 | + </Surface> |
217 | 181 | </section> |
218 | 182 | </div> |
219 | 183 | ); |
|
0 commit comments