fix(api): fix api integration for quest map and adjacent components
This commit is contained in:
@ -2,53 +2,59 @@
|
||||
// Swap dummy data for API responses later — shape stays the same.
|
||||
|
||||
export type RequirementType =
|
||||
| "questions"
|
||||
| "accuracy"
|
||||
| "streak"
|
||||
| "sessions"
|
||||
| "topics"
|
||||
| "xp"
|
||||
| "leaderboard";
|
||||
| "QUESTIONS_ANSWERED"
|
||||
| "SESSIONS_COMPLETED"
|
||||
| "MIN_ACCURACY"
|
||||
| "DAILY_STREAK"
|
||||
| "LIFETIME_XP"
|
||||
| "LEADERBOARD_RANK";
|
||||
|
||||
export type NodeStatus = "locked" | "active" | "claimable" | "completed";
|
||||
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"
|
||||
node_id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
sequence_order: number;
|
||||
req_type: RequirementType;
|
||||
req_target: number;
|
||||
reward_coins: number;
|
||||
reward_xp: number;
|
||||
reward_title: {
|
||||
name: string;
|
||||
description: string;
|
||||
id: string;
|
||||
};
|
||||
progress: number; // 0 → requirement.target (API will fill this)
|
||||
status: NodeStatus;
|
||||
reward: QuestReward;
|
||||
reward_items: InventoryItem[];
|
||||
status: string;
|
||||
current_value: 0;
|
||||
}
|
||||
|
||||
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;
|
||||
name: string;
|
||||
description: string;
|
||||
image_url: string;
|
||||
sequence_order: number;
|
||||
nodes: QuestNode[];
|
||||
}
|
||||
|
||||
export type Title = {
|
||||
name: string;
|
||||
description: string;
|
||||
id: string;
|
||||
};
|
||||
|
||||
export interface ClaimedRewardResponse {
|
||||
message: string;
|
||||
xp_awarded: 0;
|
||||
coins_awarded: 0;
|
||||
title_unlocked: Title[];
|
||||
items_awarded: InventoryItem[];
|
||||
}
|
||||
|
||||
// ─── Crew Rank ladder (shown on profile / leaderboard) ───────────────────────
|
||||
export const CREW_RANKS = [
|
||||
{ id: "cabin_boy", label: "Cabin Boy", emoji: "⚓", xpRequired: 0 },
|
||||
@ -58,3 +64,44 @@ export const CREW_RANKS = [
|
||||
{ id: "emperor", label: "Emperor", emoji: "👑", xpRequired: 6000 },
|
||||
{ id: "pirate_king", label: "Pirate King", emoji: "🏴☠️", xpRequired: 10000 },
|
||||
] as const;
|
||||
|
||||
export type UserTitle = {
|
||||
title_id: string;
|
||||
title: {
|
||||
name: string;
|
||||
description: string;
|
||||
id: string;
|
||||
};
|
||||
unlocked_at: string;
|
||||
is_active: false;
|
||||
};
|
||||
|
||||
export type InventoryItem = {
|
||||
id: string;
|
||||
item: {
|
||||
name: string;
|
||||
description: string;
|
||||
type: string;
|
||||
effect_type: string;
|
||||
effect_value: number;
|
||||
id: string;
|
||||
};
|
||||
quantity: number;
|
||||
};
|
||||
export type ActiveEffect = {
|
||||
id: string;
|
||||
item: {
|
||||
name: string;
|
||||
description: string;
|
||||
type: string;
|
||||
effect_type: string;
|
||||
effect_value: number;
|
||||
id: string;
|
||||
};
|
||||
expires_at: string;
|
||||
};
|
||||
|
||||
export interface UserInventory {
|
||||
items: InventoryItem[];
|
||||
active_effects: ActiveEffect[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user