61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
// ─── Quest System Types ───────────────────────────────────────────────────────
|
||
// Swap dummy data for API responses later — shape stays the same.
|
||
|
||
export type RequirementType =
|
||
| "questions"
|
||
| "accuracy"
|
||
| "streak"
|
||
| "sessions"
|
||
| "topics"
|
||
| "xp"
|
||
| "leaderboard";
|
||
|
||
export type NodeStatus = "locked" | "active" | "claimable" | "completed";
|
||
|
||
export type RewardItem = "streak_shield" | "xp_boost" | "title";
|
||
|
||
export interface QuestReward {
|
||
xp: number;
|
||
title?: string; // crew rank title, e.g. "Navigator"
|
||
item?: RewardItem;
|
||
itemLabel?: string; // human-readable, e.g. "Streak Shield ×1"
|
||
}
|
||
|
||
export interface QuestNode {
|
||
id: string;
|
||
title: string;
|
||
flavourText: string;
|
||
islandName: string; // displayed under the node
|
||
emoji: string; // island character emoji
|
||
requirement: {
|
||
type: RequirementType;
|
||
target: number;
|
||
label: string; // e.g. "questions answered"
|
||
};
|
||
progress: number; // 0 → requirement.target (API will fill this)
|
||
status: NodeStatus;
|
||
reward: QuestReward;
|
||
}
|
||
|
||
export interface QuestArc {
|
||
id: string;
|
||
name: string; // "East Blue", "Alabasta", "Skypiea"
|
||
subtitle: string; // short flavour line
|
||
emoji: string;
|
||
accentColor: string; // CSS color for this arc's theme
|
||
accentDark: string;
|
||
bgFrom: string; // gradient start for arc header
|
||
bgTo: string;
|
||
nodes: QuestNode[];
|
||
}
|
||
|
||
// ─── Crew Rank ladder (shown on profile / leaderboard) ───────────────────────
|
||
export const CREW_RANKS = [
|
||
{ id: "cabin_boy", label: "Cabin Boy", emoji: "⚓", xpRequired: 0 },
|
||
{ id: "navigator", label: "Navigator", emoji: "🗺️", xpRequired: 500 },
|
||
{ id: "first_mate", label: "First Mate", emoji: "⚔️", xpRequired: 1500 },
|
||
{ id: "warlord", label: "Warlord", emoji: "🔱", xpRequired: 3000 },
|
||
{ id: "emperor", label: "Emperor", emoji: "👑", xpRequired: 6000 },
|
||
{ id: "pirate_king", label: "Pirate King", emoji: "🏴☠️", xpRequired: 10000 },
|
||
] as const;
|