import React, { useState, useEffect } from 'react';
import {
Dumbbell, Heart, Star, Brain,
Plus, CheckCircle2, Trophy,
ShoppingBag, Zap, User,
TrendingUp, Award, Trash2,
Settings, LayoutDashboard, PlusCircle,
Sparkles, Gift, Package, BarChart3, PieChart, Activity,
Music, Palette, Book, Coffee, Smile, Edit3, X, Save,
Bell, BellRing, AlertTriangle, ChevronRight, List,
CalendarDays, ChevronLeft, Target
} from 'lucide-react';
const MyLifeProApp = () => {
// --- PERSISTENCIA Y ESTADO ---
const [view, setView] = useState('dashboard');
const [editingItem, setEditingItem] = useState(null);
const [showFullLog, setShowFullLog] = useState(false);
const [selectedDetail, setSelectedDetail] = useState(null); // { type: 'area'|'skill'|'task', id: string }
const [notificationsEnabled, setNotificationsEnabled] = useState(false);
const [data, setData] = useState(() => {
const saved = localStorage.getItem('mylifepro_final_data');
if (saved) return JSON.parse(saved);
return {
user: { xp: 0, coins: 0, level: 1 },
inventory: [],
areas: [
{ id: 'ar_fis', label: 'Física', icon: 'Dumbbell', color: 'blue', xp: 0, level: 1 },
{ id: 'ar_soc', label: 'Socio-emocional', icon: 'Heart', color: 'red', xp: 0, level: 1 },
{ id: 'ar_esp', label: 'Espiritual', icon: 'Star', color: 'yellow', xp: 0, level: 1 },
{ id: 'ar_cog', label: 'Cognitiva', icon: 'Brain', color: 'purple', xp: 0, level: 1 },
],
skills: [
{ id: 'sk_hig', areaId: 'ar_fis', label: 'Higiene', xp: 0, level: 1 },
{ id: 'sk_lec', areaId: 'ar_cog', label: 'Lectura', xp: 0, level: 1 }
],
tasks: [
{
id: 't_1',
skillId: 'sk_hig',
label: 'Ducha y limpieza',
xpReward: 20, coinReward: 10,
xpPenalty: 5, coinPenalty: 2,
frequency: 'diario',
customDays: [],
completed: false,
totalCompletions: 0,
totalFailures: 0
}
],
shop: [
{ id: 'sh_1', label: '30 min extra de Juegos', price: 100 }
]
};
});
useEffect(() => {
localStorage.setItem('mylifepro_final_data', JSON.stringify(data));
}, [data]);
// --- LÓGICA RPG ---
const calculateLevel = (xp) => Math.max(1, Math.floor(Math.sqrt(xp / 25)) + 1);
const xpForNextLevel = (level) => Math.pow(level, 2) * 25;
const handleAction = (taskId, isSuccess) => {
const task = data.tasks.find(t => t.id === taskId);
if (!task || task.completed) return;
const skill = data.skills.find(s => s.id === task.skillId);
const areaId = skill.areaId;
setData(prev => {
const xpChange = isSuccess ? (parseInt(task.xpReward) || 0) : -(parseInt(task.xpPenalty) || 0);
const coinChange = isSuccess ? (parseInt(task.coinReward) || 0) : -(parseInt(task.coinPenalty) || 0);
const newSkills = prev.skills.map(s => {
if (s.id === skill.id) {
const nx = Math.max(0, s.xp + xpChange);
return { ...s, xp: nx, level: calculateLevel(nx) };
}
return s;
});
const newAreas = prev.areas.map(a => {
if (a.id === areaId) {
const ax = Math.max(0, a.xp + Math.floor(xpChange * 0.8));
return { ...a, xp: ax, level: calculateLevel(ax) };
}
return a;
});
const newUserXp = Math.max(0, prev.user.xp + xpChange);
const newUserCoins = Math.max(0, prev.user.coins + coinChange);
return {
...prev,
user: { xp: newUserXp, coins: newUserCoins, level: calculateLevel(newUserXp) },
skills: newSkills,
areas: newAreas,
tasks: prev.tasks.map(t => t.id === taskId ? {
...t,
completed: true,
totalCompletions: isSuccess ? t.totalCompletions + 1 : t.totalCompletions,
totalFailures: !isSuccess ? t.totalFailures + 1 : t.totalFailures
} : t)
};
});
};
const addNew = (type) => {
const id = `${type}_${Date.now()}`;
const item = { id, ...form[type] };
if (type === 'task') { item.completed = false; item.totalCompletions = 0; item.totalFailures = 0; }
if (type === 'area' || type === 'skill') { item.xp = 0; item.level = 1; }
setData(prev => ({ ...prev, [type === 'reward' ? 'shop' : type + 's']: [...prev[type === 'reward' ? 'shop' : type + 's'], item] }));
};
const deleteItem = (type, id) => {
setData(prev => ({ ...prev, [type]: prev[type].filter(item => item.id !== id) }));
};
const [form, setForm] = useState({
area: { label: '', icon: 'Brain', color: 'blue' },
skill: { label: '', areaId: '' },
task: { label: '', skillId: '', xpReward: 20, coinReward: 10, xpPenalty: 5, coinPenalty: 2, frequency: 'diario', customDays: [] },
reward: { label: '', price: 50 }
});
// --- UI COMPONENTS ---
const IconSelector = ({ name, size = 20, className = "" }) => {
const icons = { Dumbbell, Heart, Star, Brain, Music, Palette, Book, Coffee, Smile };
const IconComp = icons[name] || Trophy;
return ;
};
const ProgressBar = ({ current, total, color = "indigo" }) => (
);
return (
{/* HEADER My Life PRO */}
My Life PRO
Master Level {data.user.level}
{data.user.coins}
{/* VISTA: MUNDO (DASHBOARD) */}
{view === 'dashboard' && (
{data.areas.map((area) => (
{area.label}
NIVEL {area.level}
))}
)}
{/* VISTA: MISIONES */}
{view === 'tasks' && (
Panel de Control
{data.tasks.map(task => (
{task.label}
{data.skills.find(s => s.id === task.skillId)?.label}
{task.frequency}
))}
)}
{/* VISTA: ANALIZAR (RANKINGS E INTERACCIÓN) */}
{view === 'analytics' && !selectedDetail && (
Inteligencia PRO
{/* TOP ÁREAS */}
Top Áreas de Dominio
{[...data.areas].sort((a,b) => b.xp - a.xp).slice(0, 3).map((area, idx) => (
setSelectedDetail({ type: 'area', id: area.id })}
className="bg-white p-5 rounded-[2rem] shadow-sm border border-slate-100 flex items-center justify-between active:scale-95 transition-all"
>
{area.label}
XP Total: {area.xp}
))}
{/* TOP HABILIDADES */}
Top 5 Habilidades
{[...data.skills].sort((a,b) => b.xp - a.xp).slice(0, 5).map((skill, idx) => (
setSelectedDetail({ type: 'skill', id: skill.id })}
className="flex items-center gap-4 group cursor-pointer"
>
{idx + 1}
{skill.label}
Lv {skill.level}
))}
{/* TOP TAREAS / MISIONES */}
Misiones Legendarias
{[...data.tasks].sort((a,b) => b.totalCompletions - a.totalCompletions).slice(0, 5).map((task) => (
setSelectedDetail({ type: 'task', id: task.id })}
className="bg-slate-900 p-4 rounded-2xl flex items-center justify-between text-white active:bg-slate-800"
>
Logros:
{task.totalCompletions}
))}
)}
{/* VISTA DETALLE DINÁMICA */}
{selectedDetail && (
{/* DETALLE ÁREA */}
{selectedDetail.type === 'area' && (() => {
const area = data.areas.find(a => a.id === selectedDetail.id);
const areaSkills = data.skills.filter(s => s.areaId === area.id);
return (
{area.label}
Área Maestra Nivel {area.level}
Skills
{areaSkills.length}
Habilidades Vinculadas
{areaSkills.map(s => (
setSelectedDetail({type: 'skill', id: s.id})} className="bg-white p-4 rounded-2xl shadow-sm border border-slate-100 flex justify-between items-center active:bg-slate-50">
{s.label}
LVL {s.level}
))}
);
})()}
{/* DETALLE HABILIDAD */}
{selectedDetail.type === 'skill' && (() => {
const skill = data.skills.find(s => s.id === selectedDetail.id);
const parentArea = data.areas.find(a => a.id === skill.areaId);
const skillTasks = data.tasks.filter(t => t.skillId === skill.id);
return (
{parentArea.label}
{skill.label}
Progreso de Nivel {skill.level}
{skill.xp % 100}%
Misiones que la alimentan
{skillTasks.map(t => (
setSelectedDetail({type: 'task', id: t.id})} className="bg-slate-900 p-4 rounded-2xl flex justify-between items-center group active:scale-95 transition-all cursor-pointer">
{t.label}
✔ {t.totalCompletions}
✖ {t.totalFailures}
))}
);
})()}
{/* DETALLE TAREA */}
{selectedDetail.type === 'task' && (() => {
const task = data.tasks.find(t => t.id === selectedDetail.id);
const total = (task.totalCompletions || 0) + (task.totalFailures || 0);
const successRate = total === 0 ? 0 : Math.round((task.totalCompletions / total) * 100);
return (
{task.label}
{task.frequency}
Éxitos
{task.totalCompletions}
Fallos
{task.totalFailures}
Ratio de Disciplina
{successRate}%
);
})()}
)}
{/* MODAL: REGISTRO MAESTRO (DATA LOG) */}
{showFullLog && (
DATA LOGBOOK
{data.areas.map(area => (
{area.label}
Lvl {area.level}
{data.skills.filter(s => s.areaId === area.id).map(skill => (
{skill.label}
Lv {skill.level}
{data.tasks.filter(t => t.skillId === skill.id).map(task => (
{task.label}
✔ {task.totalCompletions}
✖ {task.totalFailures}
))}
))}
))}
)}
{/* VISTA: TIENDA */}
{view === 'shop' && (
PRO SHOP
Mercado de Recompensas
{data.shop.map(item => (
))}
)}
{/* VISTA: ADMIN (CONFIGURACIÓN) */}
{view === 'admin' && (
Notificaciones PRO
Nueva Área
setForm({...form, area: {...form.area, label: e.target.value}})} />
Elige Icono
{['Brain', 'Dumbbell', 'Heart', 'Star', 'Music', 'Palette', 'Book', 'Coffee', 'Smile'].map(ic => (
))}
Gestión de Tareas
{data.tasks.map(t => (
{t.label}
))}
)}
{/* NAVEGACIÓN INFERIOR (ESTILO DINÁMICO) */}
);
};
export default MyLifeProApp;