A React-based frontend for the Geographic Database API, providing an intuitive interface to explore countries, states, and cities data.
From this directory (front/team-bemg-frontend):
make install # install npm dependencies
make test # run the full Jest suite once (CI=true, exits non-zero on failure)
make build # produce a production build in build/Or, without Make:
npm install
CI=true npm test
npm run buildNotes:
- The test suite is hermetic: every test file mocks
axiosor the local../apimodule (seejest.mock(...)calls), so the tests do not connect to a real backend, a real database, or the network. There are no DB-state assumptions to worry about. make testsetsCI=true, which makes Jest run once and exit with a non-zero status if any test fails. The GitHub Actions workflow (.github/workflows/ci.yml) uses the same command, and thebuildjob declaresneeds: test, so any failing test blocks the build.- Expected output:
Test Suites: 18 passed, 18 totalandTests: 114 passed, 114 total(counts may grow as the suite is extended).
- Multiple Dashboards: Browse countries, states, and cities with comprehensive data views
- Search & Filter: Dynamic filtering by name, location codes, and population ranges
- Statistics: Real-time aggregate metrics including total counts and populations
- Responsive Design: Clean, modern UI that works on all devices
- Error Handling: Graceful error states with retry functionality
- Role-aware UI controls: Create/Edit/Delete actions are shown only for
adminrole tokens - Developer Logs Viewer: Token-gated
/dev/logspage with auto-refresh, level color-coding, and error/critical count cards (see Developer Logs)
- React 19 with hooks
- React Router for navigation
- Axios for API calls
- CSS3 with modern styling
- Node.js (v14 or higher)
- Running instance of the Geographic Database API (default local: http://127.0.0.1:8000)
npm installUse Make targets (recommended):
make run-local- Starts the frontend in local mode
- Calls the local backend directly at
http://127.0.0.1:8000(fromrun-local.sh) - Open http://localhost:3000
make run-cloud- Starts the frontend against the hosted API configured in
run-cloud.sh - Useful when your local backend is not running
You can still run scripts directly if needed:
sh ./run-local.sh
sh ./run-cloud.shThe app defaults to the local API at http://127.0.0.1:8000/ if no env var is provided. If you prefer not to use make run-local / make run-cloud, you can set env vars manually and run:
npm startExamples:
# local (direct backend calls)
REACT_APP_API_BASE_URL=http://127.0.0.1:8000/
# cloud (direct API calls)
REACT_APP_API_BASE_URL=https://your-api.example.comCountries: Name search, continent selector, population range
States: Name search, country code, population range
Cities: Name search, country/state codes, population range
The app exposes a developer-only log viewer at /dev/logs that consumes the backend's GET /dev/logs endpoint.
- Auth: paste the backend's
DEV_LOGS_TOKENinto the Developer Token field. The token is held insessionStoragefor the tab and sent as theX-Dev-Tokenheader on every request — it is never written tolocalStorageand never embedded in URLs. - Limit: choose how many recent records to fetch (
20,50,100). - Auto-refresh: a styled toggle switch controls a 5-second polling loop. Disable it for static inspection.
- Stat cards: at-a-glance counts of Visible Logs, Errors, and Criticals across the current view.
- Level color-coding: each row is themed by the log level (
info,warn,error,critical) vialog-<level>CSS classes, so problems stand out without filtering. - Empty state: clear messaging for "no token entered" vs. "no logs available" so the page is never silently blank.
The page does not appear in the main navigation; deep-link to /dev/logs to reach it. See the backend README.md for how to set DEV_LOGS_TOKEN and mint a token locally.
This frontend reads the role claim from the access token in local storage and hides mutation controls for non-admin users:
adminrole: Create/Edit/Delete controls are visible on Countries/States/Cities list views.- non-admin or missing role: list views stay readable, but Create/Edit/Delete controls are hidden.
Important: this is UI-level gating for UX. Backend authorization must still enforce access.
From this frontend folder:
npm run token:admin
npm run token:user
npm run token:clearThese commands print copy/paste snippets for browser DevTools.
- Open your app in the browser.
- Open DevTools Console.
- Run the printed
localStorage.setItem(...)command. - Reload the page.
Run all tests:
npm testsrc/App.test.js: App shell — title, nav links, route navigation to Countries/States/Cities dashboards, theme toggle, and theme restoration fromlocalStorageandprefers-color-scheme.src/api.test.js: API client — token storage helpers (storeAccessToken,clearAccessToken,applyAccessToken), role extraction from JWT payload, and the country/state/cityget/deletecalls (including the cascade flag).src/ConfirmModal.test.js: Open/close behavior, overlay click cancels, confirm/cancel callbacks,confirmDisabled, and theDeleting...in-progress state.
src/components/CountryList.test.js: Loading, API error with retry UI, and successful country data rendering.src/components/StateList.test.js: List states, URL-query filter parsing, search/clear, retry flow, and row-click navigation to filtered cities.src/components/CityList.test.js: List states, URL-query filter parsing, search/clear, retry flow, and stats / empty-state rendering.src/components/CreateCountryForm.test.js: Validation, duplicate country code handling, timeout error messaging, success redirect.src/components/CreateStateForm.test.js: Validation, country selector population, error/success flows, and navigation back to the states list.src/components/CreateCityForm.test.js: Validation, cascading country/state selectors, latitude/longitude inputs, submit loading feedback, and success redirect.src/components/EditCountryForm.test.js: Preloads an existing country, validates dirty fields, submit success and error paths.src/components/EditStateForm.test.js: Preloads an existing state, validates fields, submit success and error paths.src/components/EditCityForm.test.js: Preloads an existing city (including coordinates), validates fields, submit success and error paths.src/components/ErrorBoundary.test.js: Fallback UI is shown when a child component throws.src/components/FilterBar.test.js: Renders text/number/select filters with the right types and defaultAlloption, propagates(name, value)changes, and wires Search/Clear buttons.src/components/Globe3D.test.js: Fallback preview rendering in the test environment, marker count display, and customclassNamepropagation to the fallback container.src/components/DevLogsPage.test.js: Token-required validation, session-storage token restore on mount, refresh button calls/dev/logswith the configured limit, and 5-second auto-refresh polling that stops when the toggle is disabled.
src/utils/urlFilters.test.js:parseFiltersFromSearchonly reads known keys and preserves defaults;buildSearchFromFiltersomits empty/null/undefined values and stringifies the rest.src/utils/query.test.js:normalizeQueryParamsdrops empty/null/undefined values, coerces configured numeric keys (with whitespace handling), and preserves original strings on parse failure.
src/setupTests.js: Loads@testing-library/jest-dom, applies aTextEncoderpolyfill for router tests, and filters known Reactact(...)warning noise in test output.
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify