From c5a992455bcc5b79372b97f007d0226f722e43b6 Mon Sep 17 00:00:00 2001 From: Edvin Gunic Date: Thu, 17 Sep 2026 16:01:31 +0200 Subject: [PATCH 1/4] docs: improve project documentation and setup instructions Add the live app link, setup steps and documentation links to README. Document testing, Git workflow and weekly meetings while preserving PR approval rules.@ --- country-explorer/README.md | 107 ++++--------------------------------- 1 file changed, 9 insertions(+), 98 deletions(-) diff --git a/country-explorer/README.md b/country-explorer/README.md index 089a035..0185ef2 100644 --- a/country-explorer/README.md +++ b/country-explorer/README.md @@ -1,101 +1,12 @@ -# Country Explorer +# Country Explorer application -React + TypeScript + Vite app that fetches and displays country data from a REST API. +See the [project README](../README.md) for requirements, installation, development, +testing and deployment instructions. -## Project structure +The application source lives in `src/`: `components/` contains the UI, `hooks/` +contains reusable React logic, `api/` handles HTTP requests, `types/` defines shared +models, and `utils/` contains storage and sorting helpers. Tests sit beside the +code they cover, with shared setup and fixtures in `src/test/`. -``` -src/ -├── api/ # Functions for calling the external REST API (one file per resource) -├── components/ # Reusable UI components, e.g. App.tsx (one file per component) -├── hooks/ # Custom React hooks -├── types/ # Shared TypeScript types and interfaces -├── utils/ # Small, framework-agnostic helper functions -├── assets/ # Images, icons, and other static assets -├── index.css # Global stylesheet -└── main.tsx # Application entry point -``` - -`api/`, `hooks/`, `types/`, and `utils/` are created once there is real code to put in them. See [`src/api/README.md`](./src/api/README.md) for which REST API is used, the selected countries, data fields, and error handling. - -Naming conventions: - -- Components: PascalCase file names matching the default export (e.g. `CountryCard.tsx`), colocated with their own CSS file when they have one (e.g. `App.tsx` + `App.css`). -- Hooks: camelCase file names prefixed with `use` (e.g. `useFetch.ts`). -- API functions & utilities: camelCase file names describing what they do (e.g. `getCountries.ts`, `formatNumber.ts`). -- Types: camelCase file names matching the domain they describe (e.g. `country.ts`). -- Tests are colocated with the file they test (e.g. `CountryCard.test.tsx` next to `CountryCard.tsx`), rather than kept in a separate top-level test folder. - -## About this template - -This project was scaffolded with the React + TypeScript + Vite template, which provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) - -### React Compiler - -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). - -### Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, - - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]); -``` - -You can also install [eslint-plugin-react-x](https://npmx.dev/package/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://npmx.dev/package/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x'; -import reactDom from 'eslint-plugin-react-dom'; - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]); -``` +See [component structure](../docs/component-structure.md) and +[API documentation](src/api/README.md) for details. From 23482a834e04cacf7faaffb45629853472516fc5 Mon Sep 17 00:00:00 2001 From: Edvin Gunic Date: Thu, 17 Sep 2026 16:07:00 +0200 Subject: [PATCH 2/4] docs: improve project documentation and setup instructions Add the live app link, setup steps and documentation links to README. Document testing, Git workflow and weekly meetings while preserving PR approval rules. --- README.md | 68 +++++++++++++++++++++-- country-explorer/README.md | 107 +++++++++++++++++++++++++++++++++--- docs/api-performance.md | 5 +- docs/component-structure.md | 26 ++++++--- docs/git-workflow.md | 32 +++++++++++ docs/sprint-process.md | 8 +++ docs/testing.md | 32 +++++++++++ 7 files changed, 257 insertions(+), 21 deletions(-) create mode 100644 docs/git-workflow.md create mode 100644 docs/sprint-process.md create mode 100644 docs/testing.md diff --git a/README.md b/README.md index 774775b..ebbaee9 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,70 @@ -# T23-Project-1 +# T23-Project-1 — Country Explorer -Repository for team IT2810-H26-T23 in IT2810-H26. +**[Open the web app on the group VM](http://it2810-23.idi.ntnu.no/project1/)** -## Use of AI tools +Country Explorer lets you browse European countries, filter by subregion, sort by +name or population, and save favorites. Built with React, TypeScript and Vite by +team IT2810-H26-T23. -See [AI usage documentation](docs/ai-usage.md). +## Requirements + +- Git and access to this repository. +- Node.js **22.20.0** and npm **10.9.3** (the versions used for local verification). +- Internet access to install dependencies and load country data and flags. + +No API key or environment file is needed. Check your installed versions with +`node --version` and `npm --version`. + +## Run locally + +1. Clone the repository and enter the application folder: + + ```bash + git clone https://git.ntnu.no/IT2810-H26/T23-Project-1.git + cd T23-Project-1/country-explorer + ``` + +2. Install the locked dependencies: + + ```bash + npm ci + ``` + +3. Start the development server: + + ```bash + npm run dev + ``` + +4. Open [the local app](http://localhost:5173/project1/). If Vite reports a + different port, use that port instead. Stop the server with `Ctrl+C`. + +## Test and build + +Run these commands from `country-explorer/`: + +```bash +npm test # Run automated tests +npm run lint # Check code with ESLint +npm run format:check # Check formatting +npm run build # Type-check and generate dist/ +npm run preview # Preview the production build locally +``` + +The preview normally runs at `http://localhost:4173/project1/`. +See the deployment document below for serving the build on the VM. + +## Documentation + +- [Component structure](docs/component-structure.md): components, props, state ownership and initial wireframes. +- [API performance](docs/api-performance.md): observed network requests and TanStack Query caching. +- [Testing](docs/testing.md): automated checks, PC/iPhone testing and coverage limitations. +- [Deployment](docs/deployment.md): production build, VM setup and deployment verification. +- [Usability evaluation](docs/usability-evaluation.md): the group's assessment and possible mobile improvements. +- [AI usage](docs/ai-usage.md): tools used, their role and the group's review of suggestions. +- [Git workflow](docs/git-workflow.md): branch and commit templates, pull requests and review rules. +- [Sprint process](docs/sprint-process.md): weekly meetings, issue allocation and progress discussions. +- [REST API details](country-explorer/src/api/README.md): data source, country fields and error handling. ## Working in this repository diff --git a/country-explorer/README.md b/country-explorer/README.md index 0185ef2..089a035 100644 --- a/country-explorer/README.md +++ b/country-explorer/README.md @@ -1,12 +1,101 @@ -# Country Explorer application +# Country Explorer -See the [project README](../README.md) for requirements, installation, development, -testing and deployment instructions. +React + TypeScript + Vite app that fetches and displays country data from a REST API. -The application source lives in `src/`: `components/` contains the UI, `hooks/` -contains reusable React logic, `api/` handles HTTP requests, `types/` defines shared -models, and `utils/` contains storage and sorting helpers. Tests sit beside the -code they cover, with shared setup and fixtures in `src/test/`. +## Project structure -See [component structure](../docs/component-structure.md) and -[API documentation](src/api/README.md) for details. +``` +src/ +├── api/ # Functions for calling the external REST API (one file per resource) +├── components/ # Reusable UI components, e.g. App.tsx (one file per component) +├── hooks/ # Custom React hooks +├── types/ # Shared TypeScript types and interfaces +├── utils/ # Small, framework-agnostic helper functions +├── assets/ # Images, icons, and other static assets +├── index.css # Global stylesheet +└── main.tsx # Application entry point +``` + +`api/`, `hooks/`, `types/`, and `utils/` are created once there is real code to put in them. See [`src/api/README.md`](./src/api/README.md) for which REST API is used, the selected countries, data fields, and error handling. + +Naming conventions: + +- Components: PascalCase file names matching the default export (e.g. `CountryCard.tsx`), colocated with their own CSS file when they have one (e.g. `App.tsx` + `App.css`). +- Hooks: camelCase file names prefixed with `use` (e.g. `useFetch.ts`). +- API functions & utilities: camelCase file names describing what they do (e.g. `getCountries.ts`, `formatNumber.ts`). +- Types: camelCase file names matching the domain they describe (e.g. `country.ts`). +- Tests are colocated with the file they test (e.g. `CountryCard.test.tsx` next to `CountryCard.tsx`), rather than kept in a separate top-level test folder. + +## About this template + +This project was scaffolded with the React + TypeScript + Vite template, which provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs) +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) + +### React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +### Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]); +``` + +You can also install [eslint-plugin-react-x](https://npmx.dev/package/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://npmx.dev/package/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x'; +import reactDom from 'eslint-plugin-react-dom'; + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]); +``` diff --git a/docs/api-performance.md b/docs/api-performance.md index 139be6e..4a6c208 100644 --- a/docs/api-performance.md +++ b/docs/api-performance.md @@ -20,7 +20,7 @@ We checked requests to the REST API (`countries.dev`) at each stage: ## Findings -The application makes exactly **one** request to the REST API per session: +During the recorded test sequence, we observed **one** request to the REST API: ``` GET https://countries.dev/region/europe @@ -47,3 +47,6 @@ already supports this: Since there is only one query in the app (`useCountries`, keyed by region) and the UI never changes the region it's called with, there is only ever one active query, and it is never invalidated during normal use. + +This observation is not a one-request-per-session guarantee. Reloading the page, +retrying a failure, or remounting/reconnecting with stale data can fetch again. diff --git a/docs/component-structure.md b/docs/component-structure.md index 76b3d28..ad0991a 100644 --- a/docs/component-structure.md +++ b/docs/component-structure.md @@ -3,6 +3,18 @@ This document describes the planned user interface, component hierarchy, component responsibilities, props, and state for Country Explorer. +## Current implementation + +`App` coordinates query results and UI state. `RegionFilter`, `SortSelector`, and +`CountrySelector` reuse `Dropdown`. `CountryCard` contains `FavoriteButton`; +`NavigationControls` and `FavoritesList` receive data and callbacks from `App`. +`Loading` and `ErrorMessage` handle request states. Header, footer, and the controls +section are markup inside `App`, not separate components. `useFavorites` owns +favorite state, while `useCountries` wraps TanStack Query. + +The wireframes and planned hierarchy below describe the initial design; the +current implementation above is the reference for actual component boundaries. + ## Wireframes ### Desktop @@ -164,12 +176,12 @@ Displays brief information about the REST API used by the application. The main application state will initially be stored in `App`. -| State | Purpose | Storage | -|---|---|---| -| Selected country | Determines which single country is displayed | React state | -| Selected region | Determines which countries are included | React state and sessionStorage | -| Sorting option | Determines the order of countries | React state and sessionStorage | -| Favorite countries | Stores the user's favorite selections | React state and localStorage | +| State | Purpose | Storage | +| ------------------ | -------------------------------------------- | ------------------------------ | +| Selected country | Determines which single country is displayed | React state | +| Selected region | Determines which countries are included | React state and sessionStorage | +| Sorting option | Determines the order of countries | React state and sessionStorage | +| Favorite countries | Stores the user's favorite selections | React state and localStorage | The country data itself will be fetched from the REST API with TanStack Query. API data will not be stored in localStorage or sessionStorage. @@ -191,4 +203,4 @@ The user can change the displayed country by: Filtering or sorting may change the available countries and their order. If the selected country is no longer included after filtering, the first -available country will be selected. \ No newline at end of file +available country will be selected. diff --git a/docs/git-workflow.md b/docs/git-workflow.md new file mode 100644 index 0000000..4302846 --- /dev/null +++ b/docs/git-workflow.md @@ -0,0 +1,32 @@ +# Git workflow + +Work on an issue branch and open a pull request into protected `main`. +Use the branch template `-`. Replace all +placeholders below before running the commands. + +```bash +git switch main +git pull --ff-only +git switch -c "-" +# Make changes, run relevant checks, and stage the intended files. +git commit -m ": " -m "" -m "Closes #" +git push -u origin "-" +``` + +Commit template: `: `. Use `feat`, `fix`, `style`, `test`, +`docs`, or `refactor` as appropriate. Add `Closes #` only when the change +completes that issue. + +## Pull requests + +Keep the description short: + +```text +Summary: What changed. +Verification: Commands run, results, and any manual checks or limitations. +Closes # +``` + +A different member of IT2810-H26-T23 must approve the PR; approvals from staff do +not count. Resolve every review conversation before merging. New commits dismiss +previous approval, so request another review after making changes. diff --git a/docs/sprint-process.md b/docs/sprint-process.md new file mode 100644 index 0000000..e523b50 --- /dev/null +++ b/docs/sprint-process.md @@ -0,0 +1,8 @@ +# Weekly meetings and sprint planning + +We held one main meeting each week. We split the work into issues, agreed on who +would take each task, and discussed progress and problems we were struggling with. +The meetings helped us clarify tasks and decide what to focus on next. + +Issues described the work and acceptance criteria. Changes were submitted through +pull requests so another group member could review them before merging. diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 0000000..584b96a --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,32 @@ +# Testing + +From `country-explorer/`, run `npm test`, `npm run lint`, and `npm run build`. +Use `npm run format:check` to check formatting. Tests use fixed country fixtures +and mock API calls; storage is cleared between tests. + +The tests cover country rendering, loading/error states, filtering, sorting, +navigation, dropdown selection, and storage/restoration, including invalid data. +The current checkout has no committed snapshot test or `.snap` file; snapshot +coverage is therefore not claimed here. + +## Browser and device coverage + +The group's [usability evaluation](usability-evaluation.md) reports that the app +worked as expected and identifies scrolling on mobile as an improvement area. +The [deployment report](deployment.md) also records functional browser checks. +The group confirms testing on a PC and an iPhone. Browser names/versions, the +PC operating system, and the iPhone model/iOS version were not recorded. +Portrait and landscape coverage was not specified. jsdom tests do not establish +cross-browser coverage. + +| Device | Reported result | +| ------ | ---------------------------------------------------------- | +| PC | Functionality worked as expected in the group's evaluation | +| iPhone | Functionality worked; navigation required some scrolling | + +For future checks, record browser/version, device/OS, orientation, and results. + +Check filtering, sorting, favorites after reload, navigation, keyboard focus and +selection, and layout without horizontal scrolling. Test both portrait and +landscape on small screens. This is a checklist for future records, not a claim +that every combination has already been verified. From 92cd689d8e0daff6894cc4a82647806088aef951 Mon Sep 17 00:00:00 2001 From: Edvin Gunic Date: Thu, 17 Sep 2026 16:12:46 +0200 Subject: [PATCH 3/4] Update git-workflow.md --- docs/git-workflow.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/git-workflow.md b/docs/git-workflow.md index 4302846..f96251d 100644 --- a/docs/git-workflow.md +++ b/docs/git-workflow.md @@ -1,11 +1,11 @@ # Git workflow -Work on an issue branch and open a pull request into protected `main`. +Work on an issue branch and open a pull request into protected `dev`. Use the branch template `-`. Replace all placeholders below before running the commands. ```bash -git switch main +git switch dev git pull --ff-only git switch -c "-" # Make changes, run relevant checks, and stage the intended files. From 84d45a0de28877bf5e5ab5f6fa481a01ffc514af Mon Sep 17 00:00:00 2001 From: Edvin Gunic Date: Thu, 17 Sep 2026 16:13:32 +0200 Subject: [PATCH 4/4] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ebbaee9..578426b 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ No API key or environment file is needed. Check your installed versions with 2. Install the locked dependencies: ```bash + npm install npm ci ```