feat: Implement Phase 5 match detail tabs with charts and data visualization
This commit implements significant portions of Phase 5 (Feature Delivery) including: Chart Components (src/lib/components/charts/): - LineChart.svelte: Line charts with Chart.js integration - BarChart.svelte: Vertical/horizontal bar charts with stacking - PieChart.svelte: Pie/Doughnut charts with legend - All charts use Svelte 5 runes ($effect) for reactivity - Responsive design with customizable options Data Display Components (src/lib/components/data-display/): - DataTable.svelte: Generic sortable, filterable table component - TypeScript generics support for type safety - Custom formatters and renderers - Sort indicators and column alignment options Match Detail Pages: - Match layout with header, tabs, and score display - Economy tab: Equipment value charts, buy type classification, round-by-round table - Details tab: Multi-kill distribution charts, team performance, top performers - Chat tab: Chronological messages with filtering, search, and round grouping Additional Components: - SearchBar, ThemeToggle (layout components) - MatchCard, PlayerCard (domain components) - Modal, Skeleton, Tabs, Tooltip (UI components) - Player profile page with stats and recent matches Dependencies: - Installed chart.js for data visualization - Created Svelte 5 compatible chart wrappers Phase 4 marked as complete, Phase 5 at 50% completion. Flashes and Damage tabs deferred for future implementation. Note: Minor linting warnings to be addressed in follow-up commit. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
31
src/routes/player/[id]/+page.ts
Normal file
31
src/routes/player/[id]/+page.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { error } from '@sveltejs/kit';
|
||||
import { api } from '$lib/api';
|
||||
import type { PageLoad } from './$types';
|
||||
|
||||
export const load: PageLoad = async ({ params }) => {
|
||||
const playerId = Number(params.id);
|
||||
|
||||
if (isNaN(playerId) || playerId <= 0) {
|
||||
throw error(400, 'Invalid player ID');
|
||||
}
|
||||
|
||||
try {
|
||||
// Fetch player profile and recent matches in parallel
|
||||
const [profile, matchesData] = await Promise.all([
|
||||
api.players.getPlayerMeta(playerId),
|
||||
api.matches.getMatches({ player_id: playerId, limit: 10 })
|
||||
]);
|
||||
|
||||
return {
|
||||
profile,
|
||||
recentMatches: matchesData.matches,
|
||||
meta: {
|
||||
title: `${profile.name} - Player Profile | CS2.WTF`,
|
||||
description: `View ${profile.name}'s CS2 statistics, match history, and performance metrics.`
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(`Failed to load player ${playerId}:`, err);
|
||||
throw error(404, `Player ${playerId} not found`);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user