import React, { useState, useEffect, useRef } from 'react';
import {
Trophy,
Settings,
Users,
CheckCircle,
XCircle,
LogOut,
Star,
Camera,
QrCode,
User,
Lock,
Download,
Trash2,
ChevronRight,
Palette,
Percent,
Plus,
Sparkles,
History,
ShieldCheck,
Bell,
LayoutDashboard,
Gift,
Smartphone
} from 'lucide-react';
const App = () => {
// --- ÉTATS GLOBAUX ---
const [view, setView] = useState('landing');
const [user, setUser] = useState(null);
const [shopConfig, setShopConfig] = useState({
name: "Lojy Demo Shop",
primaryColor: "#f59e0b",
rewards: [
{ id: 1, label: "-10% REMISE", color: "#f59e0b", weight: 40, highlighted: false },
{ id: 2, label: "CADEAU", color: "#1e293b", weight: 20, highlighted: false },
{ id: 3, label: "PERDU", color: "#334155", weight: 20, highlighted: false },
{ id: 4, label: "-50% ARTICLE", color: "#f59e0b", weight: 10, highlighted: true },
{ id: 5, label: "SURPRISE", color: "#1e293b", weight: 5, highlighted: false },
{ id: 6, label: "BOISSON", color: "#334155", weight: 5, highlighted: false },
]
});
// --- ÉTATS CLIENT ---
const [wonReward, setWonReward] = useState(null);
const [isSpinning, setIsSpinning] = useState(false);
const [rotation, setRotation] = useState(0);
const [proofSubmitted, setProofSubmitted] = useState(false);
const [showQR, setShowQR] = useState(false);
const [clientHistory, setClientHistory] = useState([
{ id: 101, reward: "-10% REMISE", date: "2024-01-20", status: "utilisé" },
{ id: 102, reward: "BOISSON OFFERTE", date: "2024-01-25", status: "validé" },
]);
// --- ÉTATS ADMIN ---
const [submissions, setSubmissions] = useState([
{ id: 1, userName: "Alice Martin", reward: "CADEAU", platform: "Google", status: "pending", date: "2024-01-27" },
{ id: 2, userName: "Julien Roux", reward: "-10% REMISE", platform: "Instagram", status: "pending", date: "2024-01-27" },
]);
const canvasRef = useRef(null);
// --- LOGIQUE ADMIN ---
const handleAdminAction = (id, action) => {
setSubmissions(prev => prev.filter(s => s.id !== id));
};
const addReward = () => {
const newId = Date.now();
setShopConfig({
...shopConfig,
rewards: [...shopConfig.rewards, { id: newId, label: "NOUVEAU LOT", color: "#1e293b", weight: 10, highlighted: false }]
});
};
const removeReward = (id) => {
if (shopConfig.rewards.length <= 2) return;
setShopConfig({
...shopConfig,
rewards: shopConfig.rewards.filter(r => r.id !== id)
});
};
const toggleHighlight = (id) => {
setShopConfig({
...shopConfig,
rewards: shopConfig.rewards.map(r =>
r.id === id ? { ...r, highlighted: !r.highlighted, color: !r.highlighted ? "#f59e0b" : "#1e293b" } : r
)
});
};
// --- DESSIN DE LA ROUE ---
useEffect(() => {
if ((view === 'wheel' || view === 'admin') && canvasRef.current) {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const radius = canvas.width / 2 - 10;
const arcSize = (2 * Math.PI) / shopConfig.rewards.length;
ctx.clearRect(0, 0, canvas.width, canvas.height);
shopConfig.rewards.forEach((reward, i) => {
const angle = i * arcSize;
ctx.beginPath();
ctx.fillStyle = reward.highlighted ? "#f59e0b" : reward.color;
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius, angle, angle + arcSize);
ctx.fill();
if (reward.highlighted) {
ctx.strokeStyle = "#fff";
ctx.lineWidth = 3;
ctx.stroke();
} else {
ctx.strokeStyle = "rgba(255,255,255,0.1)";
ctx.lineWidth = 1;
ctx.stroke();
}
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(angle + arcSize / 2);
ctx.fillStyle = reward.highlighted ? "#000" : "white";
ctx.font = "bold 11px sans-serif";
ctx.textAlign = "right";
ctx.fillText(reward.label, radius - 25, 5);
ctx.restore();
});
}
}, [view, shopConfig]);
// --- JEU ---
const spinWheel = () => {
if (isSpinning) return;
setIsSpinning(true);
const extraDegrees = Math.floor(Math.random() * 360) + 1800;
const newRotation = rotation + extraDegrees;
setRotation(newRotation);
setTimeout(() => {
setIsSpinning(false);
const actualDegree = newRotation % 360;
const index = Math.floor((360 - actualDegree) / (360 / shopConfig.rewards.length)) % shopConfig.rewards.length;
const result = shopConfig.rewards[index];
if (result.label === "PERDU") {
setWonReward(null);
setView('client_dashboard');
} else {
setWonReward(result);
setView('claim_reward');
}
}, 4000);
};
// --- NAVBAR ---
const Navbar = () => (
);
return (
{/* LANDING */}
{view === 'landing' && (
BOOSTEZ VOTRE
)}
{/* AUTH */}
{view === 'auth' && (
)}
{/* CLIENT DASHBOARD */}
{view === 'client_dashboard' && user && (
VIP Pass
PROMO
)}
{/* CLIENT PROFILE */}
{view === 'client_profile' && (
)}
{/* WHEEL GAME */}
{view === 'wheel' && (
)}
{/* CLAIM REWARD */}
{view === 'claim_reward' && (
Solutions de fidélité 2.0
BOOSTEZ VOTRE
VISIBILITÉ.
Offrez des cadeaux à vos clients en échange d'avis positifs sur Google et les réseaux sociaux.
Rejoindre Lojy
Inscrivez-vous pour gagner des récompenses
Salut, {user.name.split(' ')[0]} !
Vous avez 1 tirage disponible
Historique des lots
{clientHistory.map(item => (
{item.status}
))}
{item.reward}
{item.date}
PROMO
EXCLUSIVE
Valable sur tout le shop
VIP2026
Mon Profil
Sécurité
Données & Vie Privée
Zone de danger
La suppression de votre compte est irréversible. Toutes vos récompenses non utilisées seront perdues.
Tentez votre chance !
Lots garantis par {shopConfig.name}
{wonReward?.label}
Débloquez votre lot maintenant !
{!proofSubmitted ? (
{['Google Maps', 'Instagram'].map(p => (