+
+
+
+ {isClaimed ? : isCompleted ? : }
+ {quest.name}
+ {quest.repeatable && répétable}
+
+
{quest.description}
+
+
+
+ {/* Objectif */}
+
+ {OBJ_LABELS[quest.objectiveType] ?? quest.objectiveType} — {mode === 'active' ? `${progress}/${quest.objectiveCount}` : `×${quest.objectiveCount}`}
+
+
+ {/* Progress bar (active quests only) */}
+ {mode === 'active' && (
+
+ )}
+
+ {/* Rewards */}
+
+ {quest.rewardXp} XP
+ {quest.rewardGold} or
+ {quest.rewardTitle && 🏅 {quest.rewardTitle}}
+ {quest.minLevel > 1 && Niv. {quest.minLevel}+}
+
+
+ {/* Actions */}
+ {mode === 'available' && (
+
+ )}
+ {mode === 'active' && isCompleted && (
+
+ )}
+ {acceptMut.isError &&
{(acceptMut.error as Error).message}
}
+ {claimMut.isError &&
{(claimMut.error as Error).message}
}
+
+ );
+}
+
+function ArcSection({ arc }: { arc: any }) {
+ const [open, setOpen] = useState(true);
+ const { completed, total } = arc.progress;
+
+ return (
+
+
setOpen(!open)}
+ >
+ {open ? : }
+
+ {arc.name}
+ {completed}/{total}
+ {arc.completed && }
+
+ {open && (
+ <>
+
{arc.description}
+
+ {arc.quests.map((q: any) => (
+
+ {q.playerStatus === 'claimed'
+ ?
+ : q.playerStatus === 'completed'
+ ?
+ : q.playerStatus === 'active'
+ ?
+ :
+ }
+ {q.name}
+ {q.rewardXp} XP
+ {q.minLevel > 1 && Niv.{q.minLevel}+}
+
+ ))}
+
+ >
+ )}
+
+ );
+}
+
+export function QuestPage() {
+ const { data: active, isLoading: loadActive } = useQuery({ queryKey: ['questsActive'], queryFn: questApi.active });
+ const { data: available, isLoading: loadAvail } = useQuery({ queryKey: ['questsAvailable'], queryFn: questApi.available });
+ const { data: arcs } = useQuery({ queryKey: ['questArcs'], queryFn: questApi.arcs });
+
+ if (loadActive || loadAvail) return
+
📜 Quêtes
+
+
+ {/* Active quests */}
+
+
+ Quêtes actives ({activeCount}/3)
+
+ {active && active.length > 0 ? (
+
+ {active.map((pq: any) => )}
+
+ ) : (
+
+ Aucune quête active — acceptez-en dans le panneau de droite
+
+ )}
+
+
+ {/* Available quests */}
+
+
+ Quêtes disponibles
+
+ {available && available.length > 0 ? (
+
+ {available.map((q: any) => )}
+
+ ) : (
+
+ Toutes les quêtes sont acceptées ou complétées
+
+ )}
+
+
+
+ {/* Arcs narratifs */}
+ {arcs && arcs.length > 0 && (
+
+
+ 📖 Arcs narratifs
+
+ {arcs.map((arc: any) =>
)}
+
+ )}
+
+ );
+}