import React, { useState, useEffect } from 'react'; import { StorageService } from '../services/storageService'; import { UserProfile, Transaction } from '../types'; import { Button } from '../components/ui/Button'; import { User, Mail, Briefcase, GraduationCap, Upload, Check, Loader2, CheckCircle, X, Sparkles, Palette, Frame as FrameIcon, Image as ImageIcon, ImagePlus, AtSign, Compass, Lock, History, Coins, ArrowUpRight, ArrowDownLeft, ChevronRight, PenTool, PlayCircle, Lightbulb, Wallet, Shield, Camera, ShoppingBag } from 'lucide-react'; import { useNavigate, Link, useLocation } from 'react-router-dom'; import confetti from 'canvas-confetti'; const AVATAR_PRESETS = [ { id: 'unicorn', name: 'Unicorn', seed: 'unicorn', bg: 'bg-pink-100', border: 'border-pink-300' }, { id: 'bunny', name: 'Bunny', seed: 'bunny', bg: 'bg-rose-100', border: 'border-rose-300' }, { id: 'royal', name: 'Royal', seed: 'king', bg: 'bg-amber-100', border: 'border-amber-300' }, { id: 'dreamy', name: 'Dreamy', seed: 'sky', bg: 'bg-sky-100', border: 'border-sky-300' }, { id: 'witch', name: 'Witch', seed: 'witch', bg: 'bg-purple-100', border: 'border-purple-300' }, { id: 'fox', name: 'Fox', seed: 'fox', bg: 'bg-orange-100', border: 'border-orange-300' }, { id: 'fairy', name: 'Fairy', seed: 'butterfly', bg: 'bg-indigo-100', border: 'border-indigo-300' }, { id: 'nature', name: 'Nature', seed: 'garden', bg: 'bg-emerald-100', border: 'border-emerald-300' }, { id: 'dark', name: 'Dark', seed: 'demon', bg: 'bg-slate-800', border: 'border-slate-600' }, { id: 'moon', name: 'Moon', seed: 'luna', bg: 'bg-blue-900', border: 'border-blue-700' }, { id: 'bear', name: 'Bear', seed: 'bear', bg: 'bg-stone-100', border: 'border-stone-300' }, { id: 'cat', name: 'Cat', seed: 'cat', bg: 'bg-orange-50', border: 'border-orange-200' }, { id: 'dog', name: 'Dog', seed: 'dog', bg: 'bg-yellow-50', border: 'border-yellow-200' }, { id: 'panda', name: 'Panda', seed: 'panda', bg: 'bg-gray-100', border: 'border-gray-300' }, { id: 'lion', name: 'Lion', seed: 'lion', bg: 'bg-amber-200', border: 'border-amber-400' }, { id: 'tiger', name: 'Tiger', seed: 'tiger', bg: 'bg-orange-200', border: 'border-orange-400' }, { id: 'koala', name: 'Koala', seed: 'koala', bg: 'bg-slate-200', border: 'border-slate-400' }, ]; const ADVENTURER_PRESETS = [ { id: 'hero', name: 'Hero', seed: 'hero', bg: 'bg-blue-100', border: 'border-blue-300' }, { id: 'scout', name: 'Scout', seed: 'scout', bg: 'bg-green-100', border: 'border-green-300' }, { id: 'mage', name: 'Mage', seed: 'mage', bg: 'bg-purple-100', border: 'border-purple-300' }, { id: 'rogue', name: 'Rogue', seed: 'rogue', bg: 'bg-gray-100', border: 'border-gray-300' }, { id: 'paladin', name: 'Paladin', seed: 'paladin', bg: 'bg-yellow-100', border: 'border-yellow-300' }, { id: 'hunter', name: 'Hunter', seed: 'hunter', bg: 'bg-orange-100', border: 'border-orange-300' }, { id: 'cleric', name: 'Cleric', seed: 'cleric', bg: 'bg-teal-100', border: 'border-teal-300' }, { id: 'bard', name: 'Bard', seed: 'bard', bg: 'bg-pink-100', border: 'border-pink-300' }, { id: 'warrior', name: 'Warrior', seed: 'warrior', bg: 'bg-red-100', border: 'border-red-300' }, { id: 'druid', name: 'Druid', seed: 'druid', bg: 'bg-emerald-200', border: 'border-emerald-400' }, { id: 'necromancer', name: 'Necro', seed: 'necromancer', bg: 'bg-slate-800', border: 'border-slate-600' }, { id: 'monk', name: 'Monk', seed: 'monk', bg: 'bg-orange-50', border: 'border-orange-200' }, ]; const SCIFI_PRESETS = [ { id: 'robot1', name: 'Unit 01', seed: 'robot1', bg: 'bg-slate-100', border: 'border-slate-300' }, { id: 'robot2', name: 'Unit 02', seed: 'robot2', bg: 'bg-cyan-100', border: 'border-cyan-300' }, { id: 'robot3', name: 'Unit 03', seed: 'robot3', bg: 'bg-emerald-100', border: 'border-emerald-300' }, { id: 'robot4', name: 'Unit 04', seed: 'robot4', bg: 'bg-red-100', border: 'border-red-300' }, { id: 'robot5', name: 'Unit 05', seed: 'robot5', bg: 'bg-purple-100', border: 'border-purple-300' }, { id: 'robot6', name: 'Unit 06', seed: 'robot6', bg: 'bg-orange-100', border: 'border-orange-300' }, { id: 'robot7', name: 'Unit 07', seed: 'robot7', bg: 'bg-indigo-100', border: 'border-indigo-300' }, { id: 'robot8', name: 'Unit 08', seed: 'robot8', bg: 'bg-lime-100', border: 'border-lime-300' }, { id: 'cyborg1', name: 'Cyborg A', seed: 'cyborg1', bg: 'bg-gray-800', border: 'border-gray-600' }, { id: 'cyborg2', name: 'Cyborg B', seed: 'cyborg2', bg: 'bg-blue-900', border: 'border-blue-700' }, { id: 'droid', name: 'Droid', seed: 'droid', bg: 'bg-yellow-100', border: 'border-yellow-400' }, { id: 'mecha', name: 'Mecha', seed: 'mecha', bg: 'bg-red-50', border: 'border-red-200' }, ]; const FRAMES = [ { id: 'none', name: 'No Frame', css: 'border-4 border-transparent' }, { id: 'unicorn', name: 'Unicorn', css: 'border-4 border-pink-400 ring-4 ring-pink-200 shadow-[0_0_15px_#f472b6]' }, { id: 'bunny', name: 'Bunny', css: 'border-4 border-white ring-4 ring-rose-300 shadow-lg' }, { id: 'royal', name: 'Royal', css: 'border-4 border-yellow-500 ring-4 ring-yellow-200 shadow-[0_0_20px_#eab308]' }, { id: 'dreamy', name: 'Dreamy', css: 'border-4 border-sky-300 ring-4 ring-indigo-200 shadow-[0_0_15px_#7dd3fc] border-dashed' }, { id: 'witch', name: 'Witch', css: 'border-4 border-purple-600 ring-4 ring-purple-900 shadow-[0_0_15px_#9333ea]' }, { id: 'fox', name: 'Fox', css: 'border-4 border-orange-500 ring-4 ring-orange-200 shadow-md' }, { id: 'fairy', name: 'Fairy', css: 'border-4 border-teal-300 ring-4 ring-emerald-100 shadow-[0_0_15px_#5eead4]' }, { id: 'nature', name: 'Nature', css: 'border-8 border-green-500 border-double shadow-sm' }, { id: 'dark', name: 'Dark', css: 'border-4 border-gray-800 ring-4 ring-red-900 shadow-[0_0_20px_#000]' }, { id: 'moon', name: 'Moon', css: 'border-4 border-slate-300 ring-4 ring-blue-900 shadow-[0_0_15px_#cbd5e1]' }, { id: 'cyber', name: 'Cyber', css: 'border-4 border-cyan-400 ring-4 ring-cyan-900 shadow-[0_0_20px_#22d3ee]' }, { id: 'vintage', name: 'Vintage', css: 'border-8 border-amber-700 border-double shadow-inner' }, { id: 'neon', name: 'Neon', css: 'border-4 border-lime-400 ring-4 ring-lime-900 shadow-[0_0_20px_#a3e635] animate-pulse' }, ]; const TIPS = [ "Drink a glass of warm water every morning to boost metabolism.", "Take a 5-minute break for every 25 minutes of study.", "Meditation for 10 minutes can reduce daily stress by 40%.", "Eating seasonal fruits supports local farmers and your health.", "A clutter-free workspace leads to a clutter-free mind.", "Kindness is the highest form of wisdom.", "Consistent sleep schedules improve memory retention.", ]; const Profile: React.FC = () => { const navigate = useNavigate(); const location = useLocation(); const [activeTab, setActiveTab] = useState<'info' | 'ledger'>('info'); const [profile, setProfile] = useState(null); const [transactions, setTransactions] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [showSuccess, setShowSuccess] = useState(false); // Avatar Studio State const [showAvatarMenu, setShowAvatarMenu] = useState(false); const [studioTab, setStudioTab] = useState<'avatars' | 'frames'>('avatars'); const [activeCollection, setActiveCollection] = useState<'avataaars' | 'adventurer' | 'scifi'>('avataaars'); // Ad Simulation const [isWatchingAd, setIsWatchingAd] = useState(false); const [showTipModal, setShowTipModal] = useState(false); const [currentTip, setCurrentTip] = useState(''); // Temporary State for Studio const [tempAvatar, setTempAvatar] = useState(''); const [tempFrame, setTempFrame] = useState('none'); // Edit State const [name, setName] = useState(''); const [username, setUsername] = useState(''); const [bio, setBio] = useState(''); const [avatarUrl, setAvatarUrl] = useState(''); const [bannerUrl, setBannerUrl] = useState(''); const [previewUrl, setPreviewUrl] = useState(''); const [previewBannerUrl, setPreviewBannerUrl] = useState(''); const [frameId, setFrameId] = useState('none'); const [profession, setProfession] = useState(''); const [school, setSchool] = useState(''); useEffect(() => { const fetchProfile = async () => { setLoading(true); const p = await StorageService.getProfile(); setProfile(p); if (p) { setName(p.name); setUsername(p.username || ''); setBio(p.bio || ''); setAvatarUrl(p.avatarUrl || ''); setBannerUrl(p.bannerUrl || ''); setFrameId(p.frameId || 'none'); setProfession(p.profession || ''); setSchool(p.schoolName || ''); if (p.avatarUrl && p.avatarUrl.includes('/adventurer/')) { setActiveCollection('adventurer'); } else if (p.avatarUrl && p.avatarUrl.includes('/bottts/')) { setActiveCollection('scifi'); } const txs = await StorageService.getTransactions(p.id); setTransactions(txs); } setLoading(false); }; fetchProfile(); }, []); // Handle Intent from Navigation useEffect(() => { if (location.state && !loading && profile) { const { action } = location.state as any; if (action === 'ledger') { setActiveTab('ledger'); } else if (action === 'avatar') { openStudio(); } else if (action === 'edit') { setActiveTab('info'); } } }, [location.state, loading, profile]); const handleSave = async (e: React.FormEvent) => { e.preventDefault(); setSaving(true); if (username !== profile?.username) { const existing = await StorageService.searchUsers(username); const taken = existing.find(u => u.username === username && u.id !== profile?.id); if (taken) { alert("Username already taken!"); setSaving(false); return; } } const finalAvatarUrl = previewUrl || avatarUrl; const finalBannerUrl = previewBannerUrl || bannerUrl; const updated = await StorageService.updateProfile({ name, username, bio, avatarUrl: finalAvatarUrl, bannerUrl: finalBannerUrl, frameId, profession: profile?.role === 'student' ? 'Student' : profession, schoolName: school }); setProfile(updated || null); if (updated) { setAvatarUrl(updated.avatarUrl || ''); setBannerUrl(updated.bannerUrl || ''); setPreviewUrl(''); setPreviewBannerUrl(''); setShowSuccess(true); window.dispatchEvent(new Event('rudraksha-profile-update')); setTimeout(() => { setShowSuccess(false); }, 3000); } setSaving(false); }; const handleFileChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (ev) => setPreviewUrl(ev.target?.result as string); reader.readAsDataURL(file); } }; const handleBannerChange = async (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = (ev) => setPreviewBannerUrl(ev.target?.result as string); reader.readAsDataURL(file); } }; const openStudio = () => { setTempAvatar(previewUrl || avatarUrl || `https://api.dicebear.com/7.x/initials/svg?seed=${name}`); setTempFrame(frameId); setShowAvatarMenu(true); }; const closeStudio = (apply: boolean) => { if (apply) { setPreviewUrl(tempAvatar); setFrameId(tempFrame); } setShowAvatarMenu(false); }; const selectPresetAvatar = (seed: string) => { let url = ''; if (activeCollection === 'adventurer') { url = `https://api.dicebear.com/9.x/adventurer/svg?seed=${seed}&backgroundColor=transparent`; } else if (activeCollection === 'scifi') { url = `https://api.dicebear.com/7.x/bottts/svg?seed=${seed}&backgroundColor=transparent`; } else { url = `https://api.dicebear.com/7.x/avataaars/svg?seed=${seed}&backgroundColor=transparent`; } setTempAvatar(url); }; const getFrameStyle = (id: string) => { return FRAMES.find(f => f.id === id)?.css || 'border-4 border-transparent'; }; const isAvatarSelected = (seed: string) => { return tempAvatar.includes(`seed=${seed}`); }; // --- KARMA EARNING SIMULATIONS --- const handleWatchAd = () => { setIsWatchingAd(true); setTimeout(async () => { setIsWatchingAd(false); await StorageService.addPoints(50, 0, 'ad_reward', 'Watched Advertisement'); confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 }, colors: ['#facc15', '#eab308'] }); // Refresh profile const p = await StorageService.getProfile(); setProfile(p); if (p) { const txs = await StorageService.getTransactions(p.id); setTransactions(txs); } }, 3000); // 3 second simulation }; const handleGetTip = () => { const STORAGE_KEY_START = 'rudraksha_wisdom_start'; const STORAGE_KEY_AMOUNT = 'rudraksha_wisdom_amount'; const LIMIT = 100; const REWARD = 10; const DURATION = 24 * 60 * 60 * 1000; const now = Date.now(); let startTime = parseInt(localStorage.getItem(STORAGE_KEY_START) || '0'); let amount = parseInt(localStorage.getItem(STORAGE_KEY_AMOUNT) || '0'); // Check if 24 hours have passed since the start of the current cycle // If startTime is 0, it means it's the first time ever, so we start a cycle if (now - startTime > DURATION || startTime === 0) { startTime = now; amount = 0; localStorage.setItem(STORAGE_KEY_START, startTime.toString()); localStorage.setItem(STORAGE_KEY_AMOUNT, '0'); } if (amount >= LIMIT) { const timeLeft = DURATION - (now - startTime); const hours = Math.floor(timeLeft / (1000 * 60 * 60)); const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60)); alert(`Daily Wisdom limit reached (${LIMIT} Karma). Timer resets in ${hours}h ${minutes}m.`); return; } const tip = TIPS[Math.floor(Math.random() * TIPS.length)]; setCurrentTip(tip); setShowTipModal(true); StorageService.addPoints(REWARD, 0, 'tip_reward', 'Daily Wisdom'); amount += REWARD; localStorage.setItem(STORAGE_KEY_AMOUNT, amount.toString()); // Refresh profile background StorageService.getProfile().then(p => { setProfile(p); if (p) StorageService.getTransactions(p.id).then(setTransactions); }); }; const isAdventurerLocked = !profile?.unlockedItems?.includes('pack_adventurer'); if (loading) return
; if (!profile) return null; const currentBanner = previewBannerUrl || bannerUrl; const isStudent = profile.role === 'student'; return (
{showSuccess && (
Changes Saved Successfully!
)} {/* Modern Header Switcher */}
{activeTab === 'info' ? (
{/* Banner Area */}
{currentBanner ? ( Banner ) : (
)}
{/* Avatar & Key Info Overlay */}
Profile {/* Custom Avatar Upload Overlay */}

{name}

@{username}

setName(e.target.value)} className="w-full pl-14 pr-6 py-4 border-2 border-gray-100 dark:border-gray-700 rounded-2xl bg-gray-50 dark:bg-gray-800/50 text-gray-900 dark:text-white focus:border-indigo-500 focus:bg-white dark:focus:bg-gray-800 outline-none transition-all font-bold text-lg" />
setUsername(e.target.value)} className="w-full pl-14 pr-6 py-4 border-2 border-gray-100 dark:border-gray-700 rounded-2xl bg-gray-50 dark:bg-gray-800/50 text-gray-900 dark:text-white focus:border-indigo-500 focus:bg-white dark:focus:bg-gray-800 outline-none transition-all font-bold text-lg" />