File size: 3,814 Bytes
c95a333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import React, { useState, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { Medal, Star, Shield, Award } from "lucide-react";

interface ReputationSystemProps {
    actionCount: number; // Trigger updates based on actions
}

const ReputationSystem: React.FC<ReputationSystemProps> = ({ actionCount }) => {
    // Persist XP in local storage for demo purposes
    const [xp, setXp] = useState(() => parseInt(localStorage.getItem("ride_xp") || "0"));
    const [level, setLevel] = useState(1);
    const [showLevelUp, setShowLevelUp] = useState(false);

    useEffect(() => {
        // Calculate Level: Level 1 = 0-100xp, Level 2 = 101-300xp, etc.
        const newLevel = Math.floor(Math.sqrt(xp / 100)) + 1;
        if (newLevel > level) {
            setShowLevelUp(true);
            setTimeout(() => setShowLevelUp(false), 3000);
        }
        setLevel(newLevel);
    }, [xp]);

    // Update XP when actionCount increments (parent tells us something happened)
    useEffect(() => {
        if (actionCount > 0) {
            const gain = Math.floor(Math.random() * 20) + 10;
            const newXp = xp + gain;
            setXp(newXp);
            localStorage.setItem("ride_xp", newXp.toString());
        }
    }, [actionCount]);

    const getRankTitle = (lvl: number) => {
        if (lvl < 2) return "Novice Observer";
        if (lvl < 5) return "Data Scout";
        if (lvl < 10) return "Pattern Analyst";
        return "Neural Architect";
    };

    return (
        <div className="relative group cursor-default">
            {/* Level Up Notification */}
            <AnimatePresence>
                {showLevelUp && (
                    <motion.div
                        initial={{ opacity: 0, scale: 0.5, y: 50 }}
                        animate={{ opacity: 1, scale: 1, y: 0 }}
                        exit={{ opacity: 0, scale: 0.5, y: -50 }}
                        className="fixed inset-0 z-50 flex items-center justify-center pointer-events-none"
                    >
                        <div className="bg-deep-bg/90 border-2 border-yellow-400 p-8 rounded-2xl flex flex-col items-center shadow-[0_0_50px_rgba(250,204,21,0.5)] backdrop-blur-xl">
                            <Award size={64} className="text-yellow-400 mb-4 animate-bounce" />
                            <h2 className="text-3xl font-bold text-white mb-2">LEVEL UP!</h2>
                            <p className="text-yellow-400 font-mono text-xl">Level {level}</p>
                            <p className="text-gray-400 mt-2">New privileges accessing...</p>
                        </div>
                    </motion.div>
                )}
            </AnimatePresence>

            <div className="flex items-center gap-3 bg-deep-card/50 px-3 py-1.5 rounded-lg border border-white/5 hover:border-neon-blue/30 transition-colors">
                <div className="relative">
                    <Shield className="w-8 h-8 text-neon-blue" />
                    <span className="absolute inset-0 flex items-center justify-center text-[10px] font-bold text-black">{level}</span>
                </div>
                <div>
                    <div className="text-xs text-gray-400 font-mono uppercase tracking-wider">{getRankTitle(level)}</div>
                    <div className="w-24 h-1.5 bg-gray-700 rounded-full mt-1 overflow-hidden">
                        <motion.div
                            className="h-full bg-gradient-to-r from-neon-blue to-neon-purple"
                            initial={{ width: 0 }}
                            animate={{ width: `${(xp % 100)}%` }} // Simplified progress
                        />
                    </div>
                </div>
            </div>
        </div>
    );
};

export default ReputationSystem;