feat(demo): add live data.gov.rs demo page - #10
Conversation
Creates the page shell for the live data.gov.rs demo with: - Server component page with generateStaticParams for static export - Client component with placeholder panels for 6 sections: 1. Dataset picker (3 cards) 2. Dataset metadata 3. Raw data preview 4. Parsed schema 5. Chart output 6. Copyable code - Full locale support (sr-Cyrl, sr-Latn, en) - Static export compatibility (generates HTML for GitHub Pages) Part of GitHub Pages Open Data Demo Plan Phase 1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add /demo/live-data-gov-rs page demonstrating the full workflow from Serbian government dataset to working chart. Features: - Three verified dataset presets (finance, education, environment) - Live data fetching from data.gov.rs with fallback snapshots - Metadata, raw preview, and schema analysis panels - Interactive chart rendering with Recharts - Copyable code generation for developers - Full i18n support (sr-Cyrl, sr-Latn, en) - Playwright E2E smoke tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new localized “live data.gov.rs” demo page to the Next.js App Router demo section, including interactive chart rendering, schema/metadata panels, fallback snapshot support for static export, and Playwright E2E coverage.
Changes:
- Introduces
/demo/live-data-gov-rspage (server + client) with preset dataset selection, CSV parsing, schema inference, chart rendering, and copyable React code output. - Adds locale-specific UI copy plus shared dataset preset definitions.
- Adds fallback snapshot JSON files and a new Playwright E2E smoke test suite for the demo page.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
src/app/[locale]/demo/live-data-gov-rs/page.tsx |
Adds the route, static params, and page metadata for the demo. |
src/app/[locale]/demo/live-data-gov-rs/page.client.tsx |
Implements the full interactive demo UI: fetch/parse/analyze data, render charts, generate copyable code, show fallback banner. |
src/app/[locale]/demo/live-data-gov-rs/translations.ts |
Provides i18n strings and the three dataset presets. |
public/demo-snapshots/live-data-gov-rs/*.json |
Adds archived CSV snapshots for fallback mode when live fetch fails. |
tests/e2e/live-data-demo.spec.ts |
Adds Playwright tests covering page load, presets, panels, chart/code output, and locale smoke. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| captured: string; | ||
| } | null> => { | ||
| try { | ||
| const response = await fetch(`/demo-snapshots/live-data-gov-rs/${presetId}.json`); |
There was a problem hiding this comment.
loadFallbackSnapshot fetches the JSON using a root-relative URL (/demo-snapshots/...). When the app is deployed with basePath (used for GitHub Pages static export), this will 404 and the fallback mechanism won’t work. Build the URL using process.env.NEXT_PUBLIC_BASE_PATH (or the existing withBasePath() helper) so it works both locally and under a base path.
| const response = await fetch(`/demo-snapshots/live-data-gov-rs/${presetId}.json`); | |
| const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? ''; | |
| const response = await fetch( | |
| `${basePath}/demo-snapshots/live-data-gov-rs/${presetId}.json` | |
| ); |
| const parseCsvText = useCallback((text: string): { | ||
| data: Record<string, string | number | boolean | null>[]; | ||
| delimiter: string; | ||
| headers: string[]; | ||
| } => { | ||
| const delimiter = detectDelimiter(text); | ||
| const parseResult = Papa.parse<Record<string, string>>(text, { | ||
| header: true, | ||
| delimiter, | ||
| skipEmptyLines: true, | ||
| transformHeader: (header) => header.trim(), | ||
| }); |
There was a problem hiding this comment.
parseCsvText assumes the first line is the header (header: true). The included environmental-time-series snapshot starts with two metadata lines (e.g. Location - latitude,...) before the real header (time,pm1,...), which will cause headers/rows to be parsed incorrectly and break schema/chart rendering for that preset. Consider stripping leading non-header lines (e.g., find the first line that contains the expected delimiter and a known header like time) or using PapaParse hooks (e.g. beforeFirstChunk) to normalize the CSV before parsing.
| <p className='text-xs text-slate-400 italic'> | ||
| Showing 10 of {rawData.rowCount.toLocaleString()} rows | ||
| </p> |
There was a problem hiding this comment.
Several user-visible strings are hard-coded in English (e.g. “Showing 10 of … rows”) even though the PR description claims full locale support. These strings should be moved into translations.ts and rendered via t.* so sr-Cyrl/sr-Latn don’t show English UI.
| // Generate warnings | ||
| if (measures.length === 0) { | ||
| warnings.push('No numeric columns detected - may not be suitable for charts'); | ||
| } | ||
| if (dimensions.length > 10) { | ||
| warnings.push('Many text columns detected - data may need filtering'); | ||
| } | ||
| if (!timeField && headers.some((h) => h.toLowerCase().includes('godina') || h.toLowerCase().includes('year'))) { | ||
| warnings.push('Year column detected but not auto-recognized as time field'); | ||
| } |
There was a problem hiding this comment.
Schema warning messages are pushed as English sentences (e.g. “No numeric columns detected...”), which will be shown verbatim in sr-Cyrl/sr-Latn locales. If this page is intended to be fully localized, use translation keys (or structured warning codes mapped to localized copy) instead of embedding English strings in the schema analyzer.
| const copy = getDemoTranslations(locale); | ||
|
|
||
| return { | ||
| title: `${copy.title} | Vizuelni Admin Srbije`, |
There was a problem hiding this comment.
The metadata title suffix here (| Vizuelni Admin Srbije) is inconsistent with other pages (e.g. src/app/[locale]/demo/page.tsx uses | Визуелни Административни Подаци Србије). For consistent branding/SEO, reuse the same suffix pattern (and ideally localize it) across pages.
| title: `${copy.title} | Vizuelni Admin Srbije`, | |
| title: `${copy.title} | Визуелни Административни Подаци Србије`, |
|
|
||
| // Copy button should exist (may be disabled if no data) | ||
| const buttonCount = await copyButton.count(); | ||
| expect(buttonCount).toBeGreaterThanOrEqual(0); |
There was a problem hiding this comment.
This assertion is ineffective: toBeGreaterThanOrEqual(0) will always pass even when no copy button exists. Assert > 0 (or use toBeGreaterThan(0) / toHaveCount(1+)) so the test actually validates the UI.
| expect(buttonCount).toBeGreaterThanOrEqual(0); | |
| expect(buttonCount).toBeGreaterThan(0); |
| metadataNoSelection: 'Nije izabran skup podataka', | ||
| metadataNoSelectionHint: 'Kliknite na jednu od kartica iznad da biste izabrali skup podataka.', | ||
| // Raw Preview panel | ||
| rawPreviewDelimiter: 'Razdvojnjk', |
There was a problem hiding this comment.
Typo in Serbian Latin translation key rawPreviewDelimiter: "Razdvojnjk" should be "Razdvojnik".
| rawPreviewDelimiter: 'Razdvojnjk', | |
| rawPreviewDelimiter: 'Razdvojnik', |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
* Initial plan * fix(demo): address PR review comments on live-data-gov-rs demo page Co-authored-by: acailic <12486087+acailic@users.noreply.github.com> Agent-Logs-Url: https://github.com/acailic/vizuelni-admin/sessions/71675857-5b43-4560-8463-f464f397860b --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: acailic <12486087+acailic@users.noreply.github.com>
Summary
Implements the GitHub Pages Open Data Demo Plan by adding a complete demo page at
/demo/live-data-gov-rsthat shows developers how to go from a real Serbian government dataset to a working chart.Features Implemented
Core Demo Page
/demo/live-data-gov-rswith full locale support (sr-Cyrl, sr-Latn, en)Three Verified Dataset Presets
Information Panels
Chart & Code Panels
Reliability
Testing
Files Changed
src/app/[locale]/demo/live-data-gov-rs/page.tsx- Server componentsrc/app/[locale]/demo/live-data-gov-rs/page.client.tsx- Client componentsrc/app/[locale]/demo/live-data-gov-rs/translations.ts- i18n and preset datapublic/demo-snapshots/live-data-gov-rs/*.json- Fallback datatests/e2e/live-data-demo.spec.ts- E2E testsTest Plan
🤖 Generated with Claude Code