### Start Development Server
Source: https://github.com/guysuvijak/fireball-tl/blob/main/README.md
Run this command to start the local development server. The application will be accessible at http://localhost:3000.
```bash
npm run dev
```
--------------------------------
### Install Project Dependencies
Source: https://github.com/guysuvijak/fireball-tl/blob/main/README.md
Install all necessary Node.js dependencies for the project using npm.
```bash
npm install
```
--------------------------------
### Clone Fireball TL Repository
Source: https://github.com/guysuvijak/fireball-tl/blob/main/README.md
Use this command to clone the project repository locally. Ensure you have Git installed.
```bash
git clone https://github.com/guysuvijak/fireball-tl.git
```
--------------------------------
### TanStack React Query Setup
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Sets up the QueryClientProvider at the root of the application to enable global data fetching with useQuery and useMutation. Ensure this provider wraps your entire application to manage server state effectively.
```tsx
// src/app/QueryProvider.tsx
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
export function QueryProvider({ children }: { children: ReactNode }) {
return (
{children}
);
}
// src/app/layout.tsx — wraps all pages:
const LocaleLayout = ({ children }) => (
{children}
);
```
--------------------------------
### Get Popular Bosses (`getPopularBosses`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Identifies the top 5 most-queued bosses based on the total number of reservations. It maps bosses to their queue counts, filters out bosses with no queues, sorts them by count, and slices the top 5.
```typescript
// Get top 5 most-queued bosses (for the sidebar leaderboard):
const getPopularBosses = (bosses: BossQueueProps[]) => {
return bosses
.map(boss => ({
name: boss.name,
queueCount: boss.items.reduce((t, item) => t + item.queues.length, 0)
}))
.filter(boss => boss.queueCount > 0)
.sort((a, b) => b.queueCount - a.queueCount)
.slice(0, 5);
};
// Example output: [{ name: 'Adentus', queueCount: 8 }, { name: 'Junobote', queueCount: 7 }, ...]
```
--------------------------------
### Navigate to Project Directory
Source: https://github.com/guysuvijak/fireball-tl/blob/main/README.md
After cloning, change your current directory to the project's root folder.
```bash
cd fireball-tl
```
--------------------------------
### Homepage Data Fetching Pattern (`useEffect`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Demonstrates a pattern for fetching initial data (update.json and member.json) in parallel using `useEffect` and `Promise.all`. Handles potential errors and updates component state.
```typescript
// Homepage fetching pattern (no React Query — plain useEffect):
useEffect(() => {
const fetchData = async () => {
try {
const [updatesRes, membersRes] = await Promise.all([
fetch('/data/update.json'),
fetch('/data/member.json')
]);
const updatesData = await updatesRes.json();
const membersData = await membersRes.json();
setUpdates(updatesData.updates);
setMemberCount(membersData.members.length);
} catch (error) {
console.error('Error loading data:', error);
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
```
--------------------------------
### Format Queue Date for Tooltip (`formatQueueDate`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Formats a reservation date string into a human-readable string for tooltips, including the date and time elapsed since reservation. It uses `date-fns` for parsing and formatting, with Thai locale support.
```typescript
// Format a reservation date string for tooltip display:
const formatQueueDate = (dateStr: string) => {
const date = parseISO(dateStr); // 'date-fns/parseISO'
const formattedDate = format(date, 'dd/MM/yyyy');
const timeAgo = formatDistanceToNow(date, { locale: th, addSuffix: true });
return `จองเมื่อ ${formattedDate}\n(${timeAgo})`;
// e.g. "จองเมื่อ 13/12/2024\n(3 เดือนที่แล้ว)"
};
```
--------------------------------
### Guild War Position Configuration (`positionMemberData`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the guild's three-line formation for Guild War, including member names and weapon loadouts. Edit this file to update the formation.
```typescript
// src/configs/(app)/position.ts — edit to update war formation
export const positionMemberData = {
frontLine: {
title: 'Front Line',
members: [
{ name: 'MeteorVIIx', w1: 'sns', w2: 'gs' },
// w1/w2 weapon abbreviations:
// 'gs'=Greatsword, 'sns'=Sword&Shield, 'wand'=Wand,
// 'staff'=Staff, 'dagger'=Dagger, 'xbow'=Crossbow, 'bow'=Longbow
{ name: 'Penzilgon', w1: 'sns', w2: 'wand' },
]
},
midLine: {
title: 'Mid Line',
members: [
{ name: 'Marshiez', w1: 'xbow', w2: 'gs' },
{ name: 'LanaNewerth', w1: 'dagger', w2: 'xbow' },
]
},
backLine: {
title: 'Back Line',
members: [
{ name: 'Kypriz', w1: 'bow', w2: 'staff' },
{ name: 'RaggaeWiz', w1: 'wand', w2: 'staff' },
]
}
};
```
--------------------------------
### Raid Schedule Configuration (`scheduleData`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the days and times for scheduled raids. Edit this file to change raid days and times.
```typescript
import { ScheduleProps } from '@/types/(app)';
export const scheduleData: ScheduleProps[] = [
{ day: 'วันเสาร์', dayInWeek: 6, time: '20:30', bosses: 3 },
// dayInWeek: 0=Sunday, 1=Monday, ..., 6=Saturday
{ day: 'วันอาทิตย์', dayInWeek: 0, time: '20:30', bosses: 4 },
];
```
--------------------------------
### Configure Member Grades and Display
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines mappings for member grades to UI elements like colors, icons, and tooltips. Use this to customize how member ranks are visually represented.
```tsx
// src/configs/(app)/member.ts
import { memberGradeColorData, memberGradeIconData, memberGradeTooltipData, memberWeaponData } from '@/configs/(app)/member';
// memberGradeColorData: grade → Tailwind text color
// { 3: 'text-yellow-400', 2: 'text-purple-400', 1: 'text-cyan-500', 0: 'text-slate-400' }
// memberGradeIconData: grade → React Icon component
// { 3: FaChessKing, 2: FaChessBishop, 1: FaChessKnight, 0: FaChessPawn }
// memberGradeTooltipData: grade → display label
// { 3: 'Guild Leader', 2: 'Guild Advisor', 1: 'Guild Guardian', 0: 'Guild Member' }
// memberWeaponData: weapon slug → display name
// { swordshield: 'Sword & Shield', greatsword: 'Greatsword', ... }
// Render a grade icon with correct color and tooltip:
const GradeIcon = memberGradeIconData[member.grade];
```
--------------------------------
### Client-side Sortable Member Table Hook (`useMemberSort`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Accepts raw member data and returns a sorted copy, sort state, and a toggle handler. Sorting logic for specific fields like 'weapons' and 'style' is delegated to underlying comparisons.
```tsx
// src/hooks/useMemberSort.ts
import { useMemberSort } from '@/hooks/useMemberSort';
const Member = () => {
const { data: members = [] } = useMember();
const { sortedMembers, sortConfig, handleSort } = useMemberSort(members);
// sortConfig: { key: keyof MemberProps | null, direction: 'asc' | 'desc' }
// handleSort toggles direction when called with the same key twice
return (
);
};
// Sorting by grade (ascending):
handleSort('grade'); // sortConfig → { key: 'grade', direction: 'asc' }
handleSort('grade'); // sortConfig → { key: 'grade', direction: 'desc' }
// Sorting by play-style (uses pve % under the hood):
handleSort('style');
```
--------------------------------
### Homepage Static Configuration (`page.tsx`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines static configuration data for the homepage, including stats cards and quick links. The `pageStatsData` function generates stat cards based on loading state and member count.
```typescript
// src/configs/(app)/page.tsx — static config for homepage stats and links
import { pageStatsData, pageQuickLinksData } from '@/configs/(app)/page';
// pageStatsData(loading, count) returns an array of stat cards:
// [
// { icon: , label: 'Members', value: '62' },
// { icon: , label: 'Guild Level', value: '22' },
// { icon: , label: 'Active Player', value: '20-30' },
// { icon: , label: 'Server', value: 'Taion' }
// ]
// pageQuickLinksData — navigation shortcuts rendered as buttons:
// [
// { name: 'Member List', path: '/member' },
// { name: 'Guild War', path: '/position' },
// { name: 'Schedule', path: '/schedule' },
// { name: 'Discord', path: 'https://discord.gg/mYREQ3kdus' }
// ]
```
--------------------------------
### Calculate Total Queues (`getTotalQueues`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Calculates the total number of reservations across all bosses and their items by summing up the lengths of individual item queues. This function is useful for displaying an overall queue count.
```typescript
// Count total reservations across all bosses and items:
const getTotalQueues = (bosses: BossQueueProps[]): number => {
return bosses.reduce((total, boss) => {
const bossQueues = boss.items.reduce((itemTotal, item) => {
return itemTotal + item.queues.length;
}, 0);
return total + bossQueues;
}, 0);
};
// Example: getTotalQueues(bosses) → 27
```
--------------------------------
### TypeScript Interface for Schedule
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the structure for daily schedule entries, including the display name of the day, its numerical representation, the raid time, and the number of bosses scheduled. This interface is used for organizing and displaying raid timings.
```typescript
// src/types/(app)/schedule.d.ts
interface ScheduleProps {
day: string; // Display name e.g. 'วันเสาร์'
dayInWeek: number; // 0=Sunday … 6=Saturday
time: string; // 'HH:MM' 24-hour format
bosses: number; // How many bosses are raided that day
}
```
--------------------------------
### Toggle Boss Card Expansion (`useState`, `toggleBoss`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Manages the expanded/collapsed state of boss cards using `useState`. The `toggleBoss` function updates the state to either expand a specific boss card or collapse it if it's already expanded.
```typescript
// Toggle expand/collapse of a boss card:
const [expandedBoss, setExpandedBoss] = useState(null);
const toggleBoss = (bossId: number) => {
setExpandedBoss(prev => prev === bossId ? null : bossId);
};
```
--------------------------------
### Homepage News Feed Data Structure
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
A chronological list of guild announcements for the homepage. Each update requires a unique ID and a date string.
```json
// public/data/update.json
{
"updates": [
{ "id": 4, "title": "Updated Queue System", "date": "2024-11-08" },
{ "id": 3, "title": "New Guild War Strategy", "date": "2024-11-02" },
{ "id": 2, "title": "Weekly Event Schedule", "date": "2024-10-14" },
{ "id": 1, "title": "Member Recruitment Open", "date": "2024-10-13" }
]
}
```
--------------------------------
### Guild Member Roster Data Structure
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the structure for guild members, including rank, status, PVE/PVP focus, character details, weapons, and role. Edit this JSON file directly to manage guild members.
```json
// public/data/member.json
{
"members": [
{
"grade": 3, // 3=Guild Leader, 2=Advisor, 1=Guardian, 0=Member
"status": 1, // 1=Verified, 0=Unverified
"pve": 40, // PVE focus percentage (0-100)
"pvp": 60, // PVP focus percentage (0-100)
"character": "MeteorVIIx",
"discord": "meteorviix",
"nickname": "กาย",
"weapons": ["swordshield", "greatsword"],
// Valid weapon slugs: swordshield, greatsword, longbow, staff, dagger, wand, crossbow
"role": "Tank" // Tank | DPS | Support
},
{
"grade": 0,
"status": 0, // Unverified — discord/nickname intentionally empty
"pve": 50,
"pvp": 50,
"character": "SomeMember",
"discord": "",
"nickname": "",
"weapons": ["longbow", "crossbow"],
"role": "DPS"
}
]
}
```
--------------------------------
### Weapon Icon Mapping Function (`getWeaponIcon`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
A utility function to map weapon abbreviations to corresponding React icons. Used for displaying weapon icons in the position layout.
```typescript
// Weapon icon mapping inside Position page:
const getWeaponIcon = (weapon: string) => {
switch (weapon?.toLowerCase()) {
case 'gs': return ;
case 'sns': return ;
case 'wand': return ;
case 'staff': return ;
case 'dagger':return ;
case 'xbow': return ;
case 'bow': return ;
default: return null;
}
};
```
--------------------------------
### Next Date Calculation Utility (`getNextDateTime`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Calculates the next upcoming date and time for a given day of the week and time string. Used for scheduling.
```typescript
// Utility: compute the next Date for a given day-of-week and time string
const getNextDateTime = (dayInWeek: number, timeStr: string): Date => {
const [hours, minutes] = timeStr.split(':').map(Number);
const now = new Date();
const result = new Date(now);
result.setHours(hours, minutes, 0, 0);
const daysUntilNext = (dayInWeek - now.getDay() + 7) % 7;
result.setDate(result.getDate() + daysUntilNext);
if (daysUntilNext === 0 && now > result) result.setDate(result.getDate() + 7);
return result;
};
```
--------------------------------
### Framer Motion Animation Variants
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Provides reusable animation configurations for staggering container elements and sliding up list items. Use these variants to create consistent page transitions and element animations.
```tsx
// src/configs/(app)/variant.ts
import { containerVariant, itemVariant } from '@/configs/(app)/variant';
// containerVariant: parent — fades in and staggers children by 0.1s
// itemVariant: child — fades in and slides up from y=20
// Usage with Framer Motion:
import { motion } from 'framer-motion';
{items.map((item) => (
{item.name}
))}
// Page-level variants (slower, ease-out transitions):
import { pageContainerVariant, pageItemVariant, pageLogoVariant } from '@/configs/(app)/page';
{/* Logo with bounce-on-hover and scale animation */}
Subtitle text
```
--------------------------------
### Boss Loot Reservation Queue Data Structure
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines bosses, their dropped items, and the reservation queue for each item. The `queues` array orders members by priority, with index 0 being the highest.
```json
// public/data/queue.json
{
"bosses": [
{
"id": 10,
"name": "Adentus",
"items": [
{
"id": "10-0",
"name": "Adentus' Gargantuan Greatsword",
"queues": [
{
"character": "MeteorVIIx (สิทธิ์ 1)",
// "สิทธิ์ N" indicates which reservation slot (tier) this uses
"note": "2-0/10-2", // optional: cross-item notes
"date": "2024-12-13" // ISO date of reservation
},
{
"character": "Boboniwa (สิทธิ์ 1)",
"date": "2024-12-17"
}
]
},
{
"id": "10-1",
"name": "Shadow Harvester Mask",
"queues": [] // Empty queue — no reservations yet
}
]
}
]
}
```
--------------------------------
### Fetch and Cache Member List with useMember Hook
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
A custom React hook utilizing TanStack React Query to fetch and cache the guild member list from `member.json`. It returns data, loading state, and error information.
```tsx
// src/hooks/useMember.ts
import { useQuery } from '@tanstack/react-query';
import { MemberProps } from '@/types/(app)';
export const useMember = () => {
return useQuery({
queryKey: ['members'],
queryFn: async () => {
const response = await fetch('/data/member.json');
if (!response.ok) throw new Error('Failed to fetch members');
const data = await response.json();
return data.members;
}
});
};
// Usage in /member page:
const Member = () => {
const { data: members = [], isLoading, error } = useMember();
if (isLoading) return ;
if (error) return ;
// members is MemberProps[] — ready to render
};
```
--------------------------------
### Countdown Timer Hook (`useCountdown`)
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
A React hook that provides live countdown state, updating every second. Requires a target date as input.
```typescript
// Hook: live countdown state, updates every second
const useCountdown = (targetDate: Date) => {
const [countdown, setCountdown] = useState({ days: 0, hours: 0, minutes: 0, seconds: 0 });
useEffect(() => {
const interval = setInterval(() => {
const distance = targetDate.getTime() - Date.now();
if (distance > 0) {
setCountdown({
days: Math.floor(distance / 86400000),
hours: Math.floor((distance % 86400000) / 3600000),
minutes: Math.floor((distance % 3600000) / 60000),
seconds: Math.floor((distance % 60000) / 1000),
});
}
}, 1000);
return () => clearInterval(interval);
}, [targetDate]);
return countdown; // { days: 2, hours: 5, minutes: 43, seconds: 12 }
};
```
--------------------------------
### TypeScript Interfaces for Boss Queue
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the data structures for boss queue items, including character names, optional notes, dates, and detailed drop information with associated queues. Use these interfaces for managing boss raid schedules and loot distribution.
```typescript
// src/types/(app)/boss-queue.d.ts
interface BossQueueItemProps {
character: string; // e.g. "MeteorVIIx (สิทธิ์ 1)"
note?: string; // Optional cross-item notes e.g. "2-0/10-2"
date: string; // ISO date string "YYYY-MM-DD"
}
interface BossItemDropProps {
id: string; // e.g. "10-0" (bossId-itemIndex)
name: string; // Full item display name
queues: BossQueueItemProps[];
}
interface BossQueueProps {
id: number; // Boss ID (1–15)
name: string; // Boss display name
items: BossItemDropProps[];
}
```
--------------------------------
### TypeScript Interface for Position Members
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the structure for members within a position, including their character name and abbreviations for their primary and secondary weapons. This interface is used for displaying member loadouts or roles.
```typescript
// src/types/(app)/position.d.ts
interface PositionMemberProps {
name: string; // Character name
w1: string; // Primary weapon abbreviation
w2: string; // Secondary weapon abbreviation
}
```
--------------------------------
### TypeScript Interface for Member Properties
Source: https://context7.com/guysuvijak/fireball-tl/llms.txt
Defines the structure for member data, including grade, character details, weapons, role, status, and performance metrics. This interface ensures type safety for member-related objects.
```typescript
// src/types/(app)/member.d.ts
interface MemberProps {
grade: number; // 0–3
character: string; // In-game character name
nickname: string; // Real/Discord nickname
discord: string; // Discord username
weapons: string[]; // Array of weapon slugs (max 2)
role: string; // 'Tank' | 'DPS' | 'Support'
status: number; // 1=Verified, 0=Unverified
pve: number; // 0–100
pvp: number; // 0–100
style?: number; // Optional derived field
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.