Untitled

 avatar
unknown
plain_text
a month ago
4.5 kB
3
Indexable
import { useState } from 'react';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card';
import { Progress } from '@/components/ui/progress';
import { Switch } from '@/components/ui/switch';
import { Badge } from '@/components/ui/badge';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import * as icons from 'lucide-react';
import achievementsData from '@/data/achievements.json';
import './App.css';

type Achievement = {
  id: string;
  title: string;
  description: string;
  progress: number;
  target: number;
  completed: boolean;
  icon: keyof typeof icons;
  category: string;
  archived: boolean;
};

function App() {
  const [showArchived, setShowArchived] = useState(false);
  const achievements = achievementsData.achievements as Achievement[];
  const categories = [...new Set(achievements.map((a) => 
    a.category.charAt(0).toUpperCase() + a.category.slice(1)
  ))];

  const filteredAchievements = achievements.filter(
    (achievement) => achievement.archived === showArchived
  );

  return (
    <div className="min-h-screen bg-background p-8">
      <div className="max-w-4xl mx-auto space-y-8">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-4xl font-bold text-foreground mb-2">EcoBot Achievements</h1>
            <p className="text-muted-foreground">Track your recycling journey</p>
          </div>
          <div className="flex items-center space-x-2">
            <span className="text-sm text-muted-foreground">Show Archived</span>
            <Switch
              checked={showArchived}
              onCheckedChange={setShowArchived}
            />
          </div>
        </div>

        <Tabs defaultValue={categories[0].toLowerCase()} className="space-y-4">
          <TabsList>
            {categories.map((category) => (
              <TabsTrigger
                key={category}
                value={category.toLowerCase()}
                className="capitalize"
              >
                {category}
              </TabsTrigger>
            ))}
          </TabsList>

          {categories.map((category) => (
            <TabsContent
              key={category}
              value={category.toLowerCase()}
              className="grid gap-6 md:grid-cols-2"
            >
              {filteredAchievements
                .filter((a) => a.category === category.toLowerCase())
                .map((achievement) => {
                  const Icon = icons[achievement.icon];
                  return (
                    <Card key={achievement.id}>
                      <CardHeader className="flex flex-row items-center gap-4">
                        <div className="p-2 bg-primary/10 rounded-lg">
                          {Icon && <Icon className="h-6 w-6 text-primary" />}
                        </div>
                        <div className="flex-1">
                          <CardTitle className="flex items-center gap-2">
                            {achievement.title}
                            {achievement.completed && (
                              <Badge variant="default" className="bg-green-600">
                                Completed
                              </Badge>
                            )}
                          </CardTitle>
                          <CardDescription>{achievement.description}</CardDescription>
                        </div>
                      </CardHeader>
                      <CardContent>
                        <div className="flex items-center justify-between mb-2">
                          <span className="text-sm text-muted-foreground">
                            Progress: {achievement.progress}/{achievement.target}
                          </span>
                          <span className="text-sm text-muted-foreground">
                            {Math.round((achievement.progress / achievement.target) * 100)}%
                          </span>
                        </div>
                        <Progress
                          value={(achievement.progress / achievement.target) * 100}
                          className="h-2"
                        />
                      </CardContent>
                    </Card>
                  );
                })}
            </TabsContent>
          ))}
        </Tabs>
      </div>
    </div>
  );
}

export default App;
Leave a Comment