Skip to content

feat(demo): add live data.gov.rs demo page - #10

Open
acailic wants to merge 3 commits into
mainfrom
feature/live-data-demo
Open

feat(demo): add live data.gov.rs demo page#10
acailic wants to merge 3 commits into
mainfrom
feature/live-data-demo

Conversation

@acailic

@acailic acailic commented Mar 23, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the GitHub Pages Open Data Demo Plan by adding a complete demo page at /demo/live-data-gov-rs that shows developers how to go from a real Serbian government dataset to a working chart.

Features Implemented

Core Demo Page

  • Route: /demo/live-data-gov-rs with full locale support (sr-Cyrl, sr-Latn, en)
  • Static-export compatible: Works on GitHub Pages

Three Verified Dataset Presets

  1. Public Finance - Budget share from domestic taxes (line chart)
  2. Education Comparison - High school data (bar chart)
  3. Environmental Time Series - Air quality in Pančevo (multi-line chart)

Information Panels

  • Metadata Panel: Dataset title, ID, organization, format, source URL
  • Raw Preview Panel: First 10 rows, detected delimiter, resource host
  • Schema Analysis Panel: Detected dimensions, measures, time/geo fields, warnings

Chart & Code Panels

  • Chart Output: Renders interactive charts using Recharts
  • Copyable Code: Complete, runnable React code for developers

Reliability

  • Fallback Snapshots: JSON snapshots for when live data.gov.rs fetches fail
  • Graceful Degradation: Clear UI when using archived data

Testing

  • E2E Smoke Tests: 20 Playwright tests covering all major flows

Files Changed

  • src/app/[locale]/demo/live-data-gov-rs/page.tsx - Server component
  • src/app/[locale]/demo/live-data-gov-rs/page.client.tsx - Client component
  • src/app/[locale]/demo/live-data-gov-rs/translations.ts - i18n and preset data
  • public/demo-snapshots/live-data-gov-rs/*.json - Fallback data
  • tests/e2e/live-data-demo.spec.ts - E2E tests

Test Plan

  • TypeScript compilation passes
  • ESLint passes
  • Page loads in all three locales
  • Preset selection works
  • Charts render with real/fallback data
  • Code generation is copyable
  • E2E tests pass

🤖 Generated with Claude Code

openhands-agent and others added 2 commits March 23, 2026 10:53
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>
Copilot AI review requested due to automatic review settings March 23, 2026 11:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-rs page (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`);

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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`
);

Copilot uses AI. Check for mistakes.
Comment on lines +323 to +334
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(),
});

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +1302 to +1304
<p className='text-xs text-slate-400 italic'>
Showing 10 of {rawData.rowCount.toLocaleString()} rows
</p>

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +239 to +248
// 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');
}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
const copy = getDemoTranslations(locale);

return {
title: `${copy.title} | Vizuelni Admin Srbije`,

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
title: `${copy.title} | Vizuelni Admin Srbije`,
title: `${copy.title} | Визуелни Административни Подаци Србије`,

Copilot uses AI. Check for mistakes.
Comment thread tests/e2e/live-data-demo.spec.ts Outdated

// Copy button should exist (may be disabled if no data)
const buttonCount = await copyButton.count();
expect(buttonCount).toBeGreaterThanOrEqual(0);

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
expect(buttonCount).toBeGreaterThanOrEqual(0);
expect(buttonCount).toBeGreaterThan(0);

Copilot uses AI. Check for mistakes.
metadataNoSelection: 'Nije izabran skup podataka',
metadataNoSelectionHint: 'Kliknite na jednu od kartica iznad da biste izabrali skup podataka.',
// Raw Preview panel
rawPreviewDelimiter: 'Razdvojnjk',

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in Serbian Latin translation key rawPreviewDelimiter: "Razdvojnjk" should be "Razdvojnik".

Suggested change
rawPreviewDelimiter: 'Razdvojnjk',
rawPreviewDelimiter: 'Razdvojnik',

Copilot uses AI. Check for mistakes.
@acailic

acailic commented Mar 23, 2026

Copy link
Copy Markdown
Owner Author

@copilot open a new pull request to apply changes based on the comments in this thread

Copilot AI commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

@acailic I've opened a new pull request, #11, to work on those changes. Once the pull request is ready, I'll request review from you.

* 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants