### 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.