diff --git a/.gitignore b/.gitignore
index f650315..5ef6a52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,16 @@
# dependencies
/node_modules
+/.pnp
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/versions
+
+# testing
+/coverage
# next.js
/.next/
@@ -10,13 +20,17 @@
# production
/build
+# misc
+.DS_Store
+*.pem
+
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
-# env files
+# env files (can opt-in for committing if needed)
.env*
# vercel
@@ -24,4 +38,4 @@ yarn-error.log*
# typescript
*.tsbuildinfo
-next-env.d.ts
\ No newline at end of file
+next-env.d.ts
diff --git a/README.md b/README.md
index 8a836dc..e215bc4 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,36 @@
-Real-Time Sports Fan Staked Token Prediction Battles for the Chiliz Paris Hackathon 2025
+This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
-## Deployment
+## Getting Started
-Project is live at:
+First, run the development server:
-**[https://vercel.com/destefaniandrei2-5621s-projects/v0-matchmind-dapp-design](https://vercel.com/destefaniandrei2-5621s-projects/v0-matchmind-dapp-design)**
+```bash
+npm run dev
+# or
+yarn dev
+# or
+pnpm dev
+# or
+bun dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
+
+This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
diff --git a/app/admin/page.tsx b/app/admin/page.tsx
deleted file mode 100644
index a542468..0000000
--- a/app/admin/page.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Header } from "@/components/layout/header"
-import { AdminDashboard } from "@/components/admin/admin-dashboard"
-import { MatchManagement } from "@/components/admin/match-management"
-import { QuestionManagement } from "@/components/admin/question-management"
-import { PayoutManagement } from "@/components/admin/payout-management"
-
-export default function AdminPage() {
- return (
-
- )
-}
diff --git a/app/globals.css b/app/globals.css
deleted file mode 100644
index ac68442..0000000
--- a/app/globals.css
+++ /dev/null
@@ -1,94 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
-
-body {
- font-family: Arial, Helvetica, sans-serif;
-}
-
-@layer utilities {
- .text-balance {
- text-wrap: balance;
- }
-}
-
-@layer base {
- :root {
- --background: 0 0% 100%;
- --foreground: 0 0% 3.9%;
- --card: 0 0% 100%;
- --card-foreground: 0 0% 3.9%;
- --popover: 0 0% 100%;
- --popover-foreground: 0 0% 3.9%;
- --primary: 0 0% 9%;
- --primary-foreground: 0 0% 98%;
- --secondary: 0 0% 96.1%;
- --secondary-foreground: 0 0% 9%;
- --muted: 0 0% 96.1%;
- --muted-foreground: 0 0% 45.1%;
- --accent: 0 0% 96.1%;
- --accent-foreground: 0 0% 9%;
- --destructive: 0 84.2% 60.2%;
- --destructive-foreground: 0 0% 98%;
- --border: 0 0% 89.8%;
- --input: 0 0% 89.8%;
- --ring: 0 0% 3.9%;
- --chart-1: 12 76% 61%;
- --chart-2: 173 58% 39%;
- --chart-3: 197 37% 24%;
- --chart-4: 43 74% 66%;
- --chart-5: 27 87% 67%;
- --radius: 0.5rem;
- --sidebar-background: 0 0% 98%;
- --sidebar-foreground: 240 5.3% 26.1%;
- --sidebar-primary: 240 5.9% 10%;
- --sidebar-primary-foreground: 0 0% 98%;
- --sidebar-accent: 240 4.8% 95.9%;
- --sidebar-accent-foreground: 240 5.9% 10%;
- --sidebar-border: 220 13% 91%;
- --sidebar-ring: 217.2 91.2% 59.8%;
- }
- .dark {
- --background: 0 0% 3.9%;
- --foreground: 0 0% 98%;
- --card: 0 0% 3.9%;
- --card-foreground: 0 0% 98%;
- --popover: 0 0% 3.9%;
- --popover-foreground: 0 0% 98%;
- --primary: 0 0% 98%;
- --primary-foreground: 0 0% 9%;
- --secondary: 0 0% 14.9%;
- --secondary-foreground: 0 0% 98%;
- --muted: 0 0% 14.9%;
- --muted-foreground: 0 0% 63.9%;
- --accent: 0 0% 14.9%;
- --accent-foreground: 0 0% 98%;
- --destructive: 0 62.8% 30.6%;
- --destructive-foreground: 0 0% 98%;
- --border: 0 0% 14.9%;
- --input: 0 0% 14.9%;
- --ring: 0 0% 83.1%;
- --chart-1: 220 70% 50%;
- --chart-2: 160 60% 45%;
- --chart-3: 30 80% 55%;
- --chart-4: 280 65% 60%;
- --chart-5: 340 75% 55%;
- --sidebar-background: 240 5.9% 10%;
- --sidebar-foreground: 240 4.8% 95.9%;
- --sidebar-primary: 224.3 76.3% 48%;
- --sidebar-primary-foreground: 0 0% 100%;
- --sidebar-accent: 240 3.7% 15.9%;
- --sidebar-accent-foreground: 240 4.8% 95.9%;
- --sidebar-border: 240 3.7% 15.9%;
- --sidebar-ring: 217.2 91.2% 59.8%;
- }
-}
-
-@layer base {
- * {
- @apply border-border;
- }
- body {
- @apply bg-background text-foreground;
- }
-}
diff --git a/app/layout.tsx b/app/layout.tsx
deleted file mode 100644
index 162d3f6..0000000
--- a/app/layout.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import type React from "react"
-import type { Metadata } from "next"
-import { Inter } from "next/font/google"
-import "./globals.css"
-import { Toaster } from "@/components/ui/toaster"
-import { WalletProvider } from "@/contexts/wallet-context"
-import { ThemeProvider } from "@/components/theme-provider"
-
-const inter = Inter({ subsets: ["latin"] })
-
-export const metadata: Metadata = {
- title: "MatchMind - Football Prediction dApp",
- description: "Stake CHZ and predict football matches to earn dividend rewards",
- generator: 'v0.dev'
-}
-
-export default function RootLayout({
- children,
-}: {
- children: React.ReactNode
-}) {
- return (
-
-
-
-
- {children}
-
-
-
-
-
- )
-}
diff --git a/app/match/[id]/page.tsx b/app/match/[id]/page.tsx
deleted file mode 100644
index 53aab61..0000000
--- a/app/match/[id]/page.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Header } from "@/components/layout/header"
-import { LiveMatch } from "@/components/match/live-match"
-import { MatchLeaderboard } from "@/components/match/match-leaderboard"
-
-interface MatchPageProps {
- params: {
- id: string
- }
-}
-
-export default function MatchPage({ params }: MatchPageProps) {
- return (
-
- )
-}
diff --git a/app/page.tsx b/app/page.tsx
deleted file mode 100644
index 2cf176b..0000000
--- a/app/page.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Header } from "@/components/layout/header"
-import { MatchList } from "@/components/matches/match-list"
-import { HeroSection } from "@/components/landing/hero-section"
-import { StatsSection } from "@/components/landing/stats-section"
-
-export default function HomePage() {
- return (
-
-
-
-
-
-
- Live & Upcoming Matches
-
-
-
-
-
-
- )
-}
diff --git a/app/results/[id]/page.tsx b/app/results/[id]/page.tsx
deleted file mode 100644
index 6033026..0000000
--- a/app/results/[id]/page.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { Header } from "@/components/layout/header"
-import { MatchResults } from "@/components/results/match-results"
-import { FinalLeaderboard } from "@/components/results/final-leaderboard"
-import { RewardSummary } from "@/components/results/reward-summary"
-
-interface ResultsPageProps {
- params: {
- id: string
- }
-}
-
-export default function ResultsPage({ params }: ResultsPageProps) {
- return (
-
-
-
- Match Results
-
-
-
- )
-}
diff --git a/app/stake/page.tsx b/app/stake/page.tsx
deleted file mode 100644
index 03057fe..0000000
--- a/app/stake/page.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Header } from "@/components/layout/header"
-import { StakeForm } from "@/components/stake/stake-form"
-import { StakeInfo } from "@/components/stake/stake-info"
-
-export default function StakePage() {
- return (
-
- )
-}
diff --git a/components.json b/components.json
deleted file mode 100644
index d9ef0ae..0000000
--- a/components.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "$schema": "https://ui.shadcn.com/schema.json",
- "style": "default",
- "rsc": true,
- "tsx": true,
- "tailwind": {
- "config": "tailwind.config.ts",
- "css": "app/globals.css",
- "baseColor": "neutral",
- "cssVariables": true,
- "prefix": ""
- },
- "aliases": {
- "components": "@/components",
- "utils": "@/lib/utils",
- "ui": "@/components/ui",
- "lib": "@/lib",
- "hooks": "@/hooks"
- },
- "iconLibrary": "lucide"
-}
\ No newline at end of file
diff --git a/components/admin/admin-dashboard.tsx b/components/admin/admin-dashboard.tsx
deleted file mode 100644
index bc0b407..0000000
--- a/components/admin/admin-dashboard.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Users, Trophy, Coins, Activity } from "lucide-react"
-
-export function AdminDashboard() {
- const stats = [
- {
- title: "Active Matches",
- value: "3",
- description: "Currently running",
- icon: Activity,
- color: "text-blue-500",
- },
- {
- title: "Total Players",
- value: "2,847",
- description: "Registered users",
- icon: Users,
- color: "text-green-500",
- },
- {
- title: "Total Staked",
- value: "125,000 CHZ",
- description: "Across all matches",
- icon: Coins,
- color: "text-yellow-500",
- },
- {
- title: "Completed Matches",
- value: "156",
- description: "Since launch",
- icon: Trophy,
- color: "text-purple-500",
- },
- ]
-
- return (
-
- {stats.map((stat, index) => (
-
-
- {stat.title}
-
-
-
- {stat.value}
- {stat.description}
-
-
- ))}
-
- )
-}
diff --git a/components/admin/match-management.tsx b/components/admin/match-management.tsx
deleted file mode 100644
index 74a79db..0000000
--- a/components/admin/match-management.tsx
+++ /dev/null
@@ -1,97 +0,0 @@
-"use client"
-
-import { useState } from "react"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Button } from "@/components/ui/button"
-import { Badge } from "@/components/ui/badge"
-import { useToast } from "@/hooks/use-toast"
-import { Play, Square, Lock } from "lucide-react"
-import { mockMatches } from "@/lib/mock-data"
-
-export function MatchManagement() {
- const [matches, setMatches] = useState(mockMatches)
- const { toast } = useToast()
-
- const handleStartMatch = (matchId: string) => {
- setMatches((prev) => prev.map((match) => (match.id === matchId ? { ...match, status: "live" as const } : match)))
- toast({
- title: "Match Started",
- description: "Match is now live and accepting predictions",
- })
- }
-
- const handleLockMatch = (matchId: string) => {
- setMatches((prev) =>
- prev.map((match) => (match.id === matchId ? { ...match, status: "completed" as const } : match)),
- )
- toast({
- title: "Match Locked",
- description: "Match has been completed and locked",
- })
- }
-
- const getStatusColor = (status: string) => {
- switch (status) {
- case "live":
- return "bg-red-500"
- case "upcoming":
- return "bg-blue-500"
- case "completed":
- return "bg-green-500"
- default:
- return "bg-gray-500"
- }
- }
-
- return (
-
-
- Match Management
-
-
-
- {matches.slice(0, 4).map((match) => (
-
-
-
-
- {match.homeTeam} vs {match.awayTeam}
-
- {match.status.toUpperCase()}
-
-
- {match.participants} players • {match.totalStake} CHZ staked
-
-
-
- {match.status === "upcoming" && (
-
handleStartMatch(match.id)} className="flex items-center gap-1">
-
- Start
-
- )}
- {match.status === "live" && (
-
handleLockMatch(match.id)}
- className="flex items-center gap-1"
- >
-
- Lock
-
- )}
- {match.status === "completed" && (
-
-
- Completed
-
- )}
-
-
- ))}
-
-
-
- )
-}
diff --git a/components/admin/payout-management.tsx b/components/admin/payout-management.tsx
deleted file mode 100644
index a487fe6..0000000
--- a/components/admin/payout-management.tsx
+++ /dev/null
@@ -1,156 +0,0 @@
-"use client"
-
-import { useState } from "react"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Button } from "@/components/ui/button"
-import { Badge } from "@/components/ui/badge"
-import { useToast } from "@/hooks/use-toast"
-import { Coins, Send, Clock } from "lucide-react"
-
-interface PayoutMatch {
- id: string
- homeTeam: string
- awayTeam: string
- totalStake: number
- totalRewards: number
- status: "pending" | "processing" | "completed"
- completedAt: string
-}
-
-export function PayoutManagement() {
- const [payoutMatches, setPayoutMatches] = useState([
- {
- id: "3",
- homeTeam: "Chelsea",
- awayTeam: "Arsenal",
- totalStake: 18750,
- totalRewards: 1875,
- status: "pending",
- completedAt: "2024-01-14T19:30:00Z",
- },
- {
- id: "6",
- homeTeam: "Juventus",
- awayTeam: "AC Milan",
- totalStake: 13670,
- totalRewards: 1367,
- status: "completed",
- completedAt: "2024-01-13T21:45:00Z",
- },
- ])
-
- const { toast } = useToast()
-
- const handleTriggerPayout = (matchId: string) => {
- setPayoutMatches((prev) =>
- prev.map((match) => (match.id === matchId ? { ...match, status: "processing" as const } : match)),
- )
-
- toast({
- title: "Payout Initiated",
- description: "Dividend distribution has been started for this match",
- })
-
- // Simulate payout completion
- setTimeout(() => {
- setPayoutMatches((prev) =>
- prev.map((match) => (match.id === matchId ? { ...match, status: "completed" as const } : match)),
- )
-
- toast({
- title: "Payout Completed",
- description: "All dividends have been successfully distributed",
- })
- }, 3000)
- }
-
- const getStatusColor = (status: string) => {
- switch (status) {
- case "pending":
- return "bg-yellow-500"
- case "processing":
- return "bg-blue-500"
- case "completed":
- return "bg-green-500"
- default:
- return "bg-gray-500"
- }
- }
-
- const getStatusIcon = (status: string) => {
- switch (status) {
- case "pending":
- return
- case "processing":
- return
- case "completed":
- return
- default:
- return null
- }
- }
-
- return (
-
-
- Payout Management
-
-
-
- {payoutMatches.map((match) => (
-
-
-
-
- {match.homeTeam} vs {match.awayTeam}
-
-
-
- {getStatusIcon(match.status)}
- {match.status.toUpperCase()}
-
-
-
-
-
Total Stake: {match.totalStake.toLocaleString()} CHZ
-
Dividend Pool: {match.totalRewards.toLocaleString()} CHZ
-
Completed: {new Date(match.completedAt).toLocaleString()}
-
-
-
- {match.status === "pending" && (
-
handleTriggerPayout(match.id)} className="flex items-center gap-1">
-
- Trigger Payout
-
- )}
- {match.status === "processing" && (
-
-
- Processing...
-
- )}
- {match.status === "completed" && (
-
-
- Completed
-
- )}
-
-
- ))}
-
-
-
-
Payout Information
-
- • Payouts are triggered manually after match completion
- • Dividends are distributed based on final leaderboard rankings
- • Principal stakes are always returned to users
- • Processing typically takes 2-5 minutes to complete
-
-
-
-
- )
-}
diff --git a/components/admin/question-management.tsx b/components/admin/question-management.tsx
deleted file mode 100644
index 142cb03..0000000
--- a/components/admin/question-management.tsx
+++ /dev/null
@@ -1,176 +0,0 @@
-"use client"
-
-import { useState } from "react"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Button } from "@/components/ui/button"
-import { Input } from "@/components/ui/input"
-import { Label } from "@/components/ui/label"
-import { Textarea } from "@/components/ui/textarea"
-import { useToast } from "@/hooks/use-toast"
-import { Plus, Check, X } from "lucide-react"
-
-interface PendingQuestion {
- id: string
- matchId: string
- text: string
- options: string[]
- submittedAt: string
-}
-
-export function QuestionManagement() {
- const [pendingQuestions] = useState([
- {
- id: "1",
- matchId: "1",
- text: "Will there be a red card in the next 10 minutes?",
- options: ["Yes", "No"],
- submittedAt: "2024-01-15T14:30:00Z",
- },
- {
- id: "2",
- matchId: "1",
- text: "Which player will touch the ball next?",
- options: ["Midfielder", "Defender", "Forward"],
- submittedAt: "2024-01-15T14:25:00Z",
- },
- ])
-
- const [newQuestion, setNewQuestion] = useState("")
- const [newOptions, setNewOptions] = useState(["", ""])
- const { toast } = useToast()
-
- const handleApproveQuestion = (questionId: string) => {
- toast({
- title: "Question Approved",
- description: "Question has been approved and will be used in the match",
- })
- }
-
- const handleRejectQuestion = (questionId: string) => {
- toast({
- title: "Question Rejected",
- description: "Question has been rejected and removed from queue",
- variant: "destructive",
- })
- }
-
- const handleAddOption = () => {
- setNewOptions([...newOptions, ""])
- }
-
- const handleOptionChange = (index: number, value: string) => {
- const updated = [...newOptions]
- updated[index] = value
- setNewOptions(updated)
- }
-
- const handleSubmitQuestion = () => {
- if (!newQuestion.trim() || newOptions.some((opt) => !opt.trim())) {
- toast({
- title: "Invalid Question",
- description: "Please fill in all fields",
- variant: "destructive",
- })
- return
- }
-
- toast({
- title: "Question Submitted",
- description: "New question has been added to the approval queue",
- })
-
- setNewQuestion("")
- setNewOptions(["", ""])
- }
-
- return (
-
-
- Question Management
-
-
- {/* Pending Questions */}
-
-
Pending Approval
-
- {pendingQuestions.map((question) => (
-
-
{question.text}
-
- {question.options.map((option, index) => (
-
- {option}
-
- ))}
-
-
- handleApproveQuestion(question.id)}
- className="flex items-center gap-1"
- >
-
- Approve
-
- handleRejectQuestion(question.id)}
- className="flex items-center gap-1"
- >
-
- Reject
-
-
-
- ))}
-
-
-
- {/* Add New Question */}
-
-
Add New Question
-
-
- Question Text
-
-
-
-
Answer Options
-
- {newOptions.map((option, index) => (
-
handleOptionChange(index, e.target.value)}
- />
- ))}
-
-
- Add Option
-
-
-
-
-
- Submit Question
-
-
-
-
-
- )
-}
diff --git a/components/landing/hero-section.tsx b/components/landing/hero-section.tsx
deleted file mode 100644
index b00b28a..0000000
--- a/components/landing/hero-section.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { Button } from "@/components/ui/button"
-import Link from "next/link"
-import { Trophy, Shield, Zap } from "lucide-react"
-
-export function HeroSection() {
- return (
-
-
-
- MatchMind
-
-
- Stake CHZ, predict football matches, and earn dividend rewards. Your principal is always safe—only generated
- dividends are distributed.
-
-
-
-
- Start Staking
-
-
- View Matches
-
-
-
-
-
-
-
Safe Staking
-
Your principal is always protected. Only dividends are at risk.
-
-
-
-
Real-time Predictions
-
Answer questions every minute during live matches.
-
-
-
-
Earn Rewards
-
Top performers share the dividend pool based on accuracy.
-
-
-
-
- )
-}
diff --git a/components/landing/stats-section.tsx b/components/landing/stats-section.tsx
deleted file mode 100644
index e1805de..0000000
--- a/components/landing/stats-section.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-
-export function StatsSection() {
- const stats = [
- { title: "Total Staked", value: "125,000 CHZ", description: "Across all matches" },
- { title: "Active Players", value: "2,847", description: "Currently participating" },
- { title: "Matches Completed", value: "156", description: "Since launch" },
- { title: "Rewards Distributed", value: "45,230 CHZ", description: "In dividends" },
- ]
-
- return (
-
- Platform Statistics
-
- {stats.map((stat, index) => (
-
-
- {stat.title}
-
-
- {stat.value}
- {stat.description}
-
-
- ))}
-
-
- )
-}
diff --git a/components/layout/header.tsx b/components/layout/header.tsx
deleted file mode 100644
index 29b9825..0000000
--- a/components/layout/header.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-"use client"
-
-import Link from "next/link"
-import { Button } from "@/components/ui/button"
-import { WalletButton } from "@/components/wallet/wallet-button"
-import { Menu, X } from "lucide-react"
-import { useState } from "react"
-
-export function Header() {
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
-
- return (
-
- )
-}
diff --git a/components/match/live-match.tsx b/components/match/live-match.tsx
deleted file mode 100644
index 7a909e8..0000000
--- a/components/match/live-match.tsx
+++ /dev/null
@@ -1,171 +0,0 @@
-"use client"
-
-import { useState, useEffect } from "react"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Button } from "@/components/ui/button"
-import { Progress } from "@/components/ui/progress"
-import { Badge } from "@/components/ui/badge"
-import { useToast } from "@/hooks/use-toast"
-import { Clock, Users } from "lucide-react"
-
-interface LiveMatchProps {
- matchId: string
-}
-
-interface Question {
- id: string
- text: string
- options: string[]
- timeLeft: number
- answered: boolean
-}
-
-export function LiveMatch({ matchId }: LiveMatchProps) {
- const [currentQuestion, setCurrentQuestion] = useState(null)
- const [timeLeft, setTimeLeft] = useState(60)
- const [selectedAnswer, setSelectedAnswer] = useState(null)
- const [score, setScore] = useState(0)
- const { toast } = useToast()
-
- // Mock questions for demonstration
- const mockQuestions = [
- {
- id: "1",
- text: "Who will score the next goal?",
- options: ["Home Team", "Away Team", "No Goal"],
- timeLeft: 60,
- answered: false,
- },
- {
- id: "2",
- text: "Will there be a corner kick in the next 5 minutes?",
- options: ["Yes", "No"],
- timeLeft: 60,
- answered: false,
- },
- {
- id: "3",
- text: "Which team will have more possession in this period?",
- options: ["Home Team", "Away Team", "Equal"],
- timeLeft: 60,
- answered: false,
- },
- ]
-
- useEffect(() => {
- // Simulate new question every minute
- const questionInterval = setInterval(() => {
- const randomQuestion = mockQuestions[Math.floor(Math.random() * mockQuestions.length)]
- setCurrentQuestion({ ...randomQuestion, answered: false })
- setTimeLeft(60)
- setSelectedAnswer(null)
- }, 60000)
-
- // Initialize with first question
- setCurrentQuestion({ ...mockQuestions[0], answered: false })
-
- return () => clearInterval(questionInterval)
- }, [])
-
- useEffect(() => {
- // Countdown timer
- if (timeLeft > 0 && currentQuestion && !currentQuestion.answered) {
- const timer = setTimeout(() => setTimeLeft(timeLeft - 1), 1000)
- return () => clearTimeout(timer)
- }
- }, [timeLeft, currentQuestion])
-
- const handleAnswerSubmit = () => {
- if (!selectedAnswer || !currentQuestion) return
-
- setCurrentQuestion({ ...currentQuestion, answered: true })
- setScore(score + 10) // Mock scoring
-
- toast({
- title: "Answer Submitted!",
- description: `You selected: ${selectedAnswer}`,
- })
- }
-
- const isTimeUp = timeLeft === 0
- const canAnswer = currentQuestion && !currentQuestion.answered && !isTimeUp && selectedAnswer
-
- return (
-
- {/* Match Info */}
-
-
-
- Manchester United vs Liverpool
- LIVE
-
-
-
-
- 45' + 2
-
-
-
- 1,247 players
-
-
-
-
-
-
2 - 1
-
Your Score: {score} points
-
-
-
-
- {/* Current Question */}
- {currentQuestion && (
-
-
-
-
Current Question
-
-
-
- {Math.floor(timeLeft / 60)}:{(timeLeft % 60).toString().padStart(2, "0")}
-
-
-
-
-
-
- {currentQuestion.text}
-
-
- {currentQuestion.options.map((option, index) => (
- setSelectedAnswer(option)}
- disabled={currentQuestion.answered || isTimeUp}
- >
- {option}
-
- ))}
-
-
-
- {currentQuestion.answered
- ? "Answer Submitted"
- : isTimeUp
- ? "Time Up!"
- : !selectedAnswer
- ? "Select an Answer"
- : "Submit Answer"}
-
-
- {isTimeUp && !currentQuestion.answered && (
- Time expired! Wait for the next question.
- )}
-
-
- )}
-
- )
-}
diff --git a/components/match/match-leaderboard.tsx b/components/match/match-leaderboard.tsx
deleted file mode 100644
index aaf8d5b..0000000
--- a/components/match/match-leaderboard.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-"use client"
-
-import { useState, useEffect } from "react"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
-import { Trophy, Medal, Award } from "lucide-react"
-
-interface LeaderboardEntry {
- rank: number
- username: string
- score: number
- isCurrentUser: boolean
-}
-
-interface MatchLeaderboardProps {
- matchId: string
-}
-
-export function MatchLeaderboard({ matchId }: MatchLeaderboardProps) {
- const [leaderboard, setLeaderboard] = useState([])
-
- useEffect(() => {
- // Mock leaderboard data - in real app, fetch from API
- const mockLeaderboard: LeaderboardEntry[] = [
- { rank: 1, username: "PredictorPro", score: 850, isCurrentUser: false },
- { rank: 2, username: "FootballFan99", score: 820, isCurrentUser: false },
- { rank: 3, username: "You", score: 780, isCurrentUser: true },
- { rank: 4, username: "MatchMaster", score: 750, isCurrentUser: false },
- { rank: 5, username: "GoalGuesser", score: 720, isCurrentUser: false },
- { rank: 6, username: "ScoreSeeker", score: 690, isCurrentUser: false },
- { rank: 7, username: "WinPredictor", score: 660, isCurrentUser: false },
- { rank: 8, username: "ChampChaser", score: 630, isCurrentUser: false },
- ]
-
- setLeaderboard(mockLeaderboard)
-
- // Simulate real-time updates
- const interval = setInterval(() => {
- setLeaderboard((prev) =>
- prev
- .map((entry) => ({
- ...entry,
- score: entry.score + Math.floor(Math.random() * 20),
- }))
- .sort((a, b) => b.score - a.score)
- .map((entry, index) => ({
- ...entry,
- rank: index + 1,
- })),
- )
- }, 10000)
-
- return () => clearInterval(interval)
- }, [matchId])
-
- const getRankIcon = (rank: number) => {
- switch (rank) {
- case 1:
- return
- case 2:
- return
- case 3:
- return
- default:
- return {rank}
- }
- }
-
- return (
-
-
-
-
- Live Leaderboard
-
-
-
-
- {leaderboard.map((entry) => (
-
-
- {getRankIcon(entry.rank)}
-
-
- {entry.username}
- {entry.isCurrentUser && (
-
- You
-
- )}
-
-
-
-
-
{entry.score}
-
points
-
-
- ))}
-
-
-
-
Leaderboard updates in real-time during the match
-
-
-
- )
-}
diff --git a/components/matches/match-card.tsx b/components/matches/match-card.tsx
deleted file mode 100644
index 60c9e35..0000000
--- a/components/matches/match-card.tsx
+++ /dev/null
@@ -1,81 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Button } from "@/components/ui/button"
-import { Badge } from "@/components/ui/badge"
-import Link from "next/link"
-import { Calendar, Users, Trophy } from "lucide-react"
-import type { Match } from "@/lib/types"
-
-interface MatchCardProps {
- match: Match
-}
-
-export function MatchCard({ match }: MatchCardProps) {
- const getStatusColor = (status: string) => {
- switch (status) {
- case "live":
- return "bg-red-500"
- case "upcoming":
- return "bg-blue-500"
- case "completed":
- return "bg-green-500"
- default:
- return "bg-gray-500"
- }
- }
-
- const formatDate = (date: string) => {
- return new Date(date).toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- hour: "2-digit",
- minute: "2-digit",
- })
- }
-
- return (
-
-
-
-
{match.status.toUpperCase()}
-
-
- {formatDate(match.startTime)}
-
-
-
- {match.homeTeam} vs {match.awayTeam}
-
-
-
-
-
-
- {match.participants} players
-
-
-
- {match.totalStake} CHZ
-
-
-
-
- {match.status === "live" && (
-
- Join Live
-
- )}
- {match.status === "upcoming" && (
-
- Stake Now
-
- )}
- {match.status === "completed" && (
-
- View Results
-
- )}
-
-
-
- )
-}
diff --git a/components/matches/match-list.tsx b/components/matches/match-list.tsx
deleted file mode 100644
index 66bd833..0000000
--- a/components/matches/match-list.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-"use client"
-
-import { useState, useEffect } from "react"
-import { MatchCard } from "./match-card"
-import { mockMatches } from "@/lib/mock-data"
-import type { Match } from "@/lib/types"
-
-export function MatchList() {
- const [matches, setMatches] = useState([])
- const [loading, setLoading] = useState(true)
-
- useEffect(() => {
- // Simulate API call to fetch matches
- const fetchMatches = async () => {
- await new Promise((resolve) => setTimeout(resolve, 1000))
- setMatches(mockMatches)
- setLoading(false)
- }
-
- fetchMatches()
- }, [])
-
- if (loading) {
- return (
-
- {[...Array(6)].map((_, i) => (
-
- ))}
-
- )
- }
-
- return (
-
- {matches.map((match) => (
-
- ))}
-
- )
-}
diff --git a/components/results/final-leaderboard.tsx b/components/results/final-leaderboard.tsx
deleted file mode 100644
index dbdda8d..0000000
--- a/components/results/final-leaderboard.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
-import { Trophy, Medal, Award, Coins } from "lucide-react"
-
-interface FinalLeaderboardProps {
- matchId: string
-}
-
-interface FinalLeaderboardEntry {
- rank: number
- username: string
- score: number
- reward: number
- isCurrentUser: boolean
-}
-
-export function FinalLeaderboard({ matchId }: FinalLeaderboardProps) {
- // Mock final leaderboard data
- const finalLeaderboard: FinalLeaderboardEntry[] = [
- { rank: 1, username: "PredictorPro", score: 950, reward: 45.2, isCurrentUser: false },
- { rank: 2, username: "FootballFan99", score: 920, reward: 32.15, isCurrentUser: false },
- { rank: 3, username: "You", score: 880, reward: 15.75, isCurrentUser: true },
- { rank: 4, username: "MatchMaster", score: 850, reward: 12.3, isCurrentUser: false },
- { rank: 5, username: "GoalGuesser", score: 820, reward: 8.9, isCurrentUser: false },
- { rank: 6, username: "ScoreSeeker", score: 790, reward: 6.45, isCurrentUser: false },
- { rank: 7, username: "WinPredictor", score: 760, reward: 4.2, isCurrentUser: false },
- { rank: 8, username: "ChampChaser", score: 730, reward: 2.85, isCurrentUser: false },
- ]
-
- const getRankIcon = (rank: number) => {
- switch (rank) {
- case 1:
- return
- case 2:
- return
- case 3:
- return
- default:
- return {rank}
- }
- }
-
- return (
-
-
-
-
- Final Leaderboard
-
-
-
-
- {finalLeaderboard.map((entry) => (
-
-
- {getRankIcon(entry.rank)}
-
-
- {entry.username}
- {entry.isCurrentUser && (
-
- You
-
- )}
-
-
{entry.score} points
-
-
-
-
-
- {entry.reward} CHZ
-
-
reward
-
-
- ))}
-
-
-
-
- Rewards distributed based on prediction accuracy and final ranking
-
-
-
-
- )
-}
diff --git a/components/results/match-results.tsx b/components/results/match-results.tsx
deleted file mode 100644
index f6fb977..0000000
--- a/components/results/match-results.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
-import { mockMatches } from "@/lib/mock-data"
-
-interface MatchResultsProps {
- matchId: string
-}
-
-export function MatchResults({ matchId }: MatchResultsProps) {
- // In a real app, fetch match data from API
- const match = mockMatches.find((m) => m.id === matchId)
-
- if (!match) {
- return Match not found
- }
-
- return (
-
-
-
- Match Result
- COMPLETED
-
-
-
-
-
- {match.homeTeam} vs {match.awayTeam}
-
-
- {match.homeScore} - {match.awayScore}
-
-
Final Score
-
-
-
- )
-}
diff --git a/components/results/reward-summary.tsx b/components/results/reward-summary.tsx
deleted file mode 100644
index dbf4f03..0000000
--- a/components/results/reward-summary.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-"use client"
-
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Badge } from "@/components/ui/badge"
-import { TrendingUp, Shield } from "lucide-react"
-
-interface RewardSummaryProps {
- matchId: string
-}
-
-export function RewardSummary({ matchId }: RewardSummaryProps) {
- // Mock data - in real app, fetch from API based on user and match
- const userStake = 100
- const userReward = 15.75
- const userRank = 3
-
- return (
-
-
-
-
- Your Reward Summary
-
-
-
-
-
-
{userStake} CHZ
-
Your Stake
-
-
- Protected
-
-
-
-
{userReward} CHZ
-
Your Reward
-
Dividend Share
-
-
-
-
-
- Rank #{userRank}
-
-
You finished in the top 10% of players!
-
-
-
-
Summary:
-
-
- • Your principal stake: {userStake} CHZ (always safe)
-
-
- • Your dividend reward: {userReward} CHZ
-
-
- • Total return: {userStake + userReward} CHZ
-
-
- • ROI: {((userReward / userStake) * 100).toFixed(1)}%
-
-
-
-
-
- )
-}
diff --git a/components/stake/stake-form.tsx b/components/stake/stake-form.tsx
deleted file mode 100644
index b56e7ff..0000000
--- a/components/stake/stake-form.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-"use client"
-
-import { useState } from "react"
-import { Button } from "@/components/ui/button"
-import { Input } from "@/components/ui/input"
-import { Label } from "@/components/ui/label"
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
-import { useWallet } from "@/contexts/wallet-context"
-import { useToast } from "@/hooks/use-toast"
-import { mockMatches } from "@/lib/mock-data"
-
-export function StakeForm() {
- const [selectedMatch, setSelectedMatch] = useState("")
- const [stakeAmount, setStakeAmount] = useState("")
- const [loading, setLoading] = useState(false)
- const { isConnected, chzBalance } = useWallet()
- const { toast } = useToast()
-
- const handleStake = async () => {
- if (!isConnected) {
- toast({
- title: "Wallet Not Connected",
- description: "Please connect your wallet to stake CHZ",
- variant: "destructive",
- })
- return
- }
-
- if (!selectedMatch || !stakeAmount) {
- toast({
- title: "Missing Information",
- description: "Please select a match and enter stake amount",
- variant: "destructive",
- })
- return
- }
-
- const amount = Number.parseFloat(stakeAmount)
- if (amount <= 0 || amount > chzBalance) {
- toast({
- title: "Invalid Amount",
- description: "Please enter a valid stake amount within your balance",
- variant: "destructive",
- })
- return
- }
-
- setLoading(true)
- try {
- // Simulate smart contract interaction
- await new Promise((resolve) => setTimeout(resolve, 2000))
-
- toast({
- title: "Stake Successful!",
- description: `Successfully staked ${amount} CHZ. Your principal is safe—only dividends are at risk.`,
- })
-
- setStakeAmount("")
- setSelectedMatch("")
- } catch (error) {
- toast({
- title: "Stake Failed",
- description: "Failed to process stake. Please try again.",
- variant: "destructive",
- })
- } finally {
- setLoading(false)
- }
- }
-
- const upcomingMatches = mockMatches.filter((match) => match.status === "upcoming")
-
- return (
-
-
- Stake CHZ
-
-
-
- Select Match
-
-
-
-
-
- {upcomingMatches.map((match) => (
-
- {match.homeTeam} vs {match.awayTeam}
-
- ))}
-
-
-
-
-
-
Stake Amount (CHZ)
-
setStakeAmount(e.target.value)}
- max={chzBalance}
- step="0.01"
- />
- {isConnected &&
Available: {chzBalance.toFixed(2)} CHZ
}
-
-
-
- {loading ? "Processing..." : "Stake CHZ"}
-
-
- {!isConnected && (
- Connect your wallet to start staking
- )}
-
-
- )
-}
diff --git a/components/stake/stake-info.tsx b/components/stake/stake-info.tsx
deleted file mode 100644
index 7529651..0000000
--- a/components/stake/stake-info.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
-import { Shield, Info, TrendingUp } from "lucide-react"
-
-export function StakeInfo() {
- return (
-
-
-
-
- How Staking Works
-
-
-
-
-
-
-
Your Principal is Safe
-
- Your staked CHZ is always protected. Only the generated dividend is distributed as rewards.
-
-
-
-
-
-
-
-
Earn Dividends
-
- Predict match outcomes correctly to earn a share of the dividend pool generated from all stakes.
-
-
-
-
-
-
Example:
-
- • You stake: 100 CHZ
- • Dividend generated: 10 CHZ
- • Your share: Based on prediction accuracy
- • Your principal: Always remains 100 CHZ
-
-
-
-
- )
-}
diff --git a/components/theme-provider.tsx b/components/theme-provider.tsx
deleted file mode 100644
index 55c2f6e..0000000
--- a/components/theme-provider.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-'use client'
-
-import * as React from 'react'
-import {
- ThemeProvider as NextThemesProvider,
- type ThemeProviderProps,
-} from 'next-themes'
-
-export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
- return {children}
-}
diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx
deleted file mode 100644
index 24c788c..0000000
--- a/components/ui/accordion.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as AccordionPrimitive from "@radix-ui/react-accordion"
-import { ChevronDown } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-
-const Accordion = AccordionPrimitive.Root
-
-const AccordionItem = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AccordionItem.displayName = "AccordionItem"
-
-const AccordionTrigger = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
- svg]:rotate-180",
- className
- )}
- {...props}
- >
- {children}
-
-
-
-))
-AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
-
-const AccordionContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, children, ...props }, ref) => (
-
- {children}
-
-))
-
-AccordionContent.displayName = AccordionPrimitive.Content.displayName
-
-export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx
deleted file mode 100644
index 25e7b47..0000000
--- a/components/ui/alert-dialog.tsx
+++ /dev/null
@@ -1,141 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
-
-import { cn } from "@/lib/utils"
-import { buttonVariants } from "@/components/ui/button"
-
-const AlertDialog = AlertDialogPrimitive.Root
-
-const AlertDialogTrigger = AlertDialogPrimitive.Trigger
-
-const AlertDialogPortal = AlertDialogPrimitive.Portal
-
-const AlertDialogOverlay = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
-
-const AlertDialogContent = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-
-
-
-))
-AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
-
-const AlertDialogHeader = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-AlertDialogHeader.displayName = "AlertDialogHeader"
-
-const AlertDialogFooter = ({
- className,
- ...props
-}: React.HTMLAttributes) => (
-
-)
-AlertDialogFooter.displayName = "AlertDialogFooter"
-
-const AlertDialogTitle = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
-
-const AlertDialogDescription = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AlertDialogDescription.displayName =
- AlertDialogPrimitive.Description.displayName
-
-const AlertDialogAction = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
-
-const AlertDialogCancel = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
-
-export {
- AlertDialog,
- AlertDialogPortal,
- AlertDialogOverlay,
- AlertDialogTrigger,
- AlertDialogContent,
- AlertDialogHeader,
- AlertDialogFooter,
- AlertDialogTitle,
- AlertDialogDescription,
- AlertDialogAction,
- AlertDialogCancel,
-}
diff --git a/components/ui/alert.tsx b/components/ui/alert.tsx
deleted file mode 100644
index 41fa7e0..0000000
--- a/components/ui/alert.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const alertVariants = cva(
- "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
- {
- variants: {
- variant: {
- default: "bg-background text-foreground",
- destructive:
- "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-const Alert = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes & VariantProps
->(({ className, variant, ...props }, ref) => (
-
-))
-Alert.displayName = "Alert"
-
-const AlertTitle = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-AlertTitle.displayName = "AlertTitle"
-
-const AlertDescription = React.forwardRef<
- HTMLParagraphElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-AlertDescription.displayName = "AlertDescription"
-
-export { Alert, AlertTitle, AlertDescription }
diff --git a/components/ui/aspect-ratio.tsx b/components/ui/aspect-ratio.tsx
deleted file mode 100644
index d6a5226..0000000
--- a/components/ui/aspect-ratio.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-"use client"
-
-import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
-
-const AspectRatio = AspectRatioPrimitive.Root
-
-export { AspectRatio }
diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx
deleted file mode 100644
index 51e507b..0000000
--- a/components/ui/avatar.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as AvatarPrimitive from "@radix-ui/react-avatar"
-
-import { cn } from "@/lib/utils"
-
-const Avatar = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-Avatar.displayName = AvatarPrimitive.Root.displayName
-
-const AvatarImage = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AvatarImage.displayName = AvatarPrimitive.Image.displayName
-
-const AvatarFallback = React.forwardRef<
- React.ElementRef,
- React.ComponentPropsWithoutRef
->(({ className, ...props }, ref) => (
-
-))
-AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
-
-export { Avatar, AvatarImage, AvatarFallback }
diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx
deleted file mode 100644
index f000e3e..0000000
--- a/components/ui/badge.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as React from "react"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const badgeVariants = cva(
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
- {
- variants: {
- variant: {
- default:
- "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
- secondary:
- "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
- destructive:
- "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
- outline: "text-foreground",
- },
- },
- defaultVariants: {
- variant: "default",
- },
- }
-)
-
-export interface BadgeProps
- extends React.HTMLAttributes,
- VariantProps {}
-
-function Badge({ className, variant, ...props }: BadgeProps) {
- return (
-
- )
-}
-
-export { Badge, badgeVariants }
diff --git a/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx
deleted file mode 100644
index 60e6c96..0000000
--- a/components/ui/breadcrumb.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { ChevronRight, MoreHorizontal } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-
-const Breadcrumb = React.forwardRef<
- HTMLElement,
- React.ComponentPropsWithoutRef<"nav"> & {
- separator?: React.ReactNode
- }
->(({ ...props }, ref) => )
-Breadcrumb.displayName = "Breadcrumb"
-
-const BreadcrumbList = React.forwardRef<
- HTMLOListElement,
- React.ComponentPropsWithoutRef<"ol">
->(({ className, ...props }, ref) => (
-
-))
-BreadcrumbList.displayName = "BreadcrumbList"
-
-const BreadcrumbItem = React.forwardRef<
- HTMLLIElement,
- React.ComponentPropsWithoutRef<"li">
->(({ className, ...props }, ref) => (
-
-))
-BreadcrumbItem.displayName = "BreadcrumbItem"
-
-const BreadcrumbLink = React.forwardRef<
- HTMLAnchorElement,
- React.ComponentPropsWithoutRef<"a"> & {
- asChild?: boolean
- }
->(({ asChild, className, ...props }, ref) => {
- const Comp = asChild ? Slot : "a"
-
- return (
-
- )
-})
-BreadcrumbLink.displayName = "BreadcrumbLink"
-
-const BreadcrumbPage = React.forwardRef<
- HTMLSpanElement,
- React.ComponentPropsWithoutRef<"span">
->(({ className, ...props }, ref) => (
-
-))
-BreadcrumbPage.displayName = "BreadcrumbPage"
-
-const BreadcrumbSeparator = ({
- children,
- className,
- ...props
-}: React.ComponentProps<"li">) => (
- svg]:w-3.5 [&>svg]:h-3.5", className)}
- {...props}
- >
- {children ?? }
-
-)
-BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
-
-const BreadcrumbEllipsis = ({
- className,
- ...props
-}: React.ComponentProps<"span">) => (
-
-
- More
-
-)
-BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
-
-export {
- Breadcrumb,
- BreadcrumbList,
- BreadcrumbItem,
- BreadcrumbLink,
- BreadcrumbPage,
- BreadcrumbSeparator,
- BreadcrumbEllipsis,
-}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
deleted file mode 100644
index 36496a2..0000000
--- a/components/ui/button.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import * as React from "react"
-import { Slot } from "@radix-ui/react-slot"
-import { cva, type VariantProps } from "class-variance-authority"
-
-import { cn } from "@/lib/utils"
-
-const buttonVariants = cva(
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
- {
- variants: {
- variant: {
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
- destructive:
- "bg-destructive text-destructive-foreground hover:bg-destructive/90",
- outline:
- "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
- secondary:
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
- ghost: "hover:bg-accent hover:text-accent-foreground",
- link: "text-primary underline-offset-4 hover:underline",
- },
- size: {
- default: "h-10 px-4 py-2",
- sm: "h-9 rounded-md px-3",
- lg: "h-11 rounded-md px-8",
- icon: "h-10 w-10",
- },
- },
- defaultVariants: {
- variant: "default",
- size: "default",
- },
- }
-)
-
-export interface ButtonProps
- extends React.ButtonHTMLAttributes,
- VariantProps {
- asChild?: boolean
-}
-
-const Button = React.forwardRef(
- ({ className, variant, size, asChild = false, ...props }, ref) => {
- const Comp = asChild ? Slot : "button"
- return (
-
- )
- }
-)
-Button.displayName = "Button"
-
-export { Button, buttonVariants }
diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx
deleted file mode 100644
index 61d2b45..0000000
--- a/components/ui/calendar.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-"use client"
-
-import * as React from "react"
-import { ChevronLeft, ChevronRight } from "lucide-react"
-import { DayPicker } from "react-day-picker"
-
-import { cn } from "@/lib/utils"
-import { buttonVariants } from "@/components/ui/button"
-
-export type CalendarProps = React.ComponentProps
-
-function Calendar({
- className,
- classNames,
- showOutsideDays = true,
- ...props
-}: CalendarProps) {
- return (
- ,
- IconRight: ({ ...props }) => ,
- }}
- {...props}
- />
- )
-}
-Calendar.displayName = "Calendar"
-
-export { Calendar }
diff --git a/components/ui/card.tsx b/components/ui/card.tsx
deleted file mode 100644
index f62edea..0000000
--- a/components/ui/card.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import * as React from "react"
-
-import { cn } from "@/lib/utils"
-
-const Card = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-Card.displayName = "Card"
-
-const CardHeader = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-CardHeader.displayName = "CardHeader"
-
-const CardTitle = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-CardTitle.displayName = "CardTitle"
-
-const CardDescription = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-CardDescription.displayName = "CardDescription"
-
-const CardContent = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-CardContent.displayName = "CardContent"
-
-const CardFooter = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => (
-
-))
-CardFooter.displayName = "CardFooter"
-
-export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
diff --git a/components/ui/carousel.tsx b/components/ui/carousel.tsx
deleted file mode 100644
index ec505d0..0000000
--- a/components/ui/carousel.tsx
+++ /dev/null
@@ -1,262 +0,0 @@
-"use client"
-
-import * as React from "react"
-import useEmblaCarousel, {
- type UseEmblaCarouselType,
-} from "embla-carousel-react"
-import { ArrowLeft, ArrowRight } from "lucide-react"
-
-import { cn } from "@/lib/utils"
-import { Button } from "@/components/ui/button"
-
-type CarouselApi = UseEmblaCarouselType[1]
-type UseCarouselParameters = Parameters
-type CarouselOptions = UseCarouselParameters[0]
-type CarouselPlugin = UseCarouselParameters[1]
-
-type CarouselProps = {
- opts?: CarouselOptions
- plugins?: CarouselPlugin
- orientation?: "horizontal" | "vertical"
- setApi?: (api: CarouselApi) => void
-}
-
-type CarouselContextProps = {
- carouselRef: ReturnType[0]
- api: ReturnType[1]
- scrollPrev: () => void
- scrollNext: () => void
- canScrollPrev: boolean
- canScrollNext: boolean
-} & CarouselProps
-
-const CarouselContext = React.createContext(null)
-
-function useCarousel() {
- const context = React.useContext(CarouselContext)
-
- if (!context) {
- throw new Error("useCarousel must be used within a ")
- }
-
- return context
-}
-
-const Carousel = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes & CarouselProps
->(
- (
- {
- orientation = "horizontal",
- opts,
- setApi,
- plugins,
- className,
- children,
- ...props
- },
- ref
- ) => {
- const [carouselRef, api] = useEmblaCarousel(
- {
- ...opts,
- axis: orientation === "horizontal" ? "x" : "y",
- },
- plugins
- )
- const [canScrollPrev, setCanScrollPrev] = React.useState(false)
- const [canScrollNext, setCanScrollNext] = React.useState(false)
-
- const onSelect = React.useCallback((api: CarouselApi) => {
- if (!api) {
- return
- }
-
- setCanScrollPrev(api.canScrollPrev())
- setCanScrollNext(api.canScrollNext())
- }, [])
-
- const scrollPrev = React.useCallback(() => {
- api?.scrollPrev()
- }, [api])
-
- const scrollNext = React.useCallback(() => {
- api?.scrollNext()
- }, [api])
-
- const handleKeyDown = React.useCallback(
- (event: React.KeyboardEvent) => {
- if (event.key === "ArrowLeft") {
- event.preventDefault()
- scrollPrev()
- } else if (event.key === "ArrowRight") {
- event.preventDefault()
- scrollNext()
- }
- },
- [scrollPrev, scrollNext]
- )
-
- React.useEffect(() => {
- if (!api || !setApi) {
- return
- }
-
- setApi(api)
- }, [api, setApi])
-
- React.useEffect(() => {
- if (!api) {
- return
- }
-
- onSelect(api)
- api.on("reInit", onSelect)
- api.on("select", onSelect)
-
- return () => {
- api?.off("select", onSelect)
- }
- }, [api, onSelect])
-
- return (
-
-
- {children}
-
-
- )
- }
-)
-Carousel.displayName = "Carousel"
-
-const CarouselContent = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => {
- const { carouselRef, orientation } = useCarousel()
-
- return (
-
- )
-})
-CarouselContent.displayName = "CarouselContent"
-
-const CarouselItem = React.forwardRef<
- HTMLDivElement,
- React.HTMLAttributes
->(({ className, ...props }, ref) => {
- const { orientation } = useCarousel()
-
- return (
-
- )
-})
-CarouselItem.displayName = "CarouselItem"
-
-const CarouselPrevious = React.forwardRef<
- HTMLButtonElement,
- React.ComponentProps
->(({ className, variant = "outline", size = "icon", ...props }, ref) => {
- const { orientation, scrollPrev, canScrollPrev } = useCarousel()
-
- return (
-
-
- Previous slide
-
- )
-})
-CarouselPrevious.displayName = "CarouselPrevious"
-
-const CarouselNext = React.forwardRef<
- HTMLButtonElement,
- React.ComponentProps
->(({ className, variant = "outline", size = "icon", ...props }, ref) => {
- const { orientation, scrollNext, canScrollNext } = useCarousel()
-
- return (
-
-
- Next slide
-
- )
-})
-CarouselNext.displayName = "CarouselNext"
-
-export {
- type CarouselApi,
- Carousel,
- CarouselContent,
- CarouselItem,
- CarouselPrevious,
- CarouselNext,
-}
diff --git a/components/ui/chart.tsx b/components/ui/chart.tsx
deleted file mode 100644
index 8620baa..0000000
--- a/components/ui/chart.tsx
+++ /dev/null
@@ -1,365 +0,0 @@
-"use client"
-
-import * as React from "react"
-import * as RechartsPrimitive from "recharts"
-
-import { cn } from "@/lib/utils"
-
-// Format: { THEME_NAME: CSS_SELECTOR }
-const THEMES = { light: "", dark: ".dark" } as const
-
-export type ChartConfig = {
- [k in string]: {
- label?: React.ReactNode
- icon?: React.ComponentType
- } & (
- | { color?: string; theme?: never }
- | { color?: never; theme: Record }
- )
-}
-
-type ChartContextProps = {
- config: ChartConfig
-}
-
-const ChartContext = React.createContext(null)
-
-function useChart() {
- const context = React.useContext(ChartContext)
-
- if (!context) {
- throw new Error("useChart must be used within a ")
- }
-
- return context
-}
-
-const ChartContainer = React.forwardRef<
- HTMLDivElement,
- React.ComponentProps<"div"> & {
- config: ChartConfig
- children: React.ComponentProps<
- typeof RechartsPrimitive.ResponsiveContainer
- >["children"]
- }
->(({ id, className, children, config, ...props }, ref) => {
- const uniqueId = React.useId()
- const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
-
- return (
-
-
-
-
- {children}
-
-
-
- )
-})
-ChartContainer.displayName = "Chart"
-
-const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
- const colorConfig = Object.entries(config).filter(
- ([_, config]) => config.theme || config.color
- )
-
- if (!colorConfig.length) {
- return null
- }
-
- return (
-