feat(treasure): add treasure quest, quest modal, island node, quest widget

This commit is contained in:
shafin-r
2026-02-26 01:31:48 +06:00
parent 894863c196
commit f64d2cac4a
12 changed files with 4018 additions and 19 deletions

60
src/types/quest.ts Normal file
View File

@ -0,0 +1,60 @@
// ─── 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;