diff --git a/t20-project-2/README.md b/t20-project-2/README.md index 4ba7a40..cb6a215 100644 --- a/t20-project-2/README.md +++ b/t20-project-2/README.md @@ -1,93 +1,164 @@ -# React + TypeScript + Vite +# Country Boys – Prosjekt 2 -## GraphQL connection +> En søkbar katalog over byer med filtre, sortering, anmeldelser og lokale bokmerker. +> Utviklet i emnet IT2810 Webutvikling ved NTNU. -The city explorer uses the Apollo API at `http://it2810-20.idi.ntnu.no:3001/` through a same-origin `/api/graphql` route. The Vite development server proxies that route to Apollo, so the browser does not need direct cross-origin access. +![React](https://img.shields.io/badge/React-20232A?logo=react&logoColor=61DAFB) +![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) +![Vite](https://img.shields.io/badge/Vite-646CFF?logo=vite&logoColor=white) +![GraphQL](https://img.shields.io/badge/GraphQL-E10098?logo=graphql&logoColor=white) +![Apollo Server](https://img.shields.io/badge/Apollo_Server-311C87?logo=apollographql&logoColor=white) +![MongoDB](https://img.shields.io/badge/MongoDB-47A248?logo=mongodb&logoColor=white) -Install and start this project from its folder with: +--- -```sh -pnpm --ignore-workspace install --frozen-lockfile -pnpm --ignore-workspace dev +## Innhold + +- [Om prosjektet](#om-prosjektet) +- [Teknologistack](#teknologistack) +- [Funksjonalitet](#funksjonalitet) +- [Kom i gang](#kom-i-gang) +- [Database og API](#database-og-api) +- [Arbeidsflyt](#arbeidsflyt) +- [Dokumentasjon](#dokumentasjon) + +--- + +## Om prosjektet + +Country Boys lar brukeren utforske bydata fra gruppas GraphQL-backend. Frontend-en henter data via Apollo Server, som håndterer kommunikasjonen med MongoDB på VM-en. Nettleseren kobler seg aldri direkte til databasen. + +```text +React + TypeScript ──(GraphQL over HTTP)──▶ Apollo Server på VM ──▶ MongoDB på VM + ▲ │ + └──────────── JSON-respons ───────────────┘ ``` -The `--ignore-workspace` option is needed when this project is opened underneath a parent directory that has its own `pnpm-workspace.yaml`. +Under lokal utvikling går frontend-kall til `/api/graphql`. Vite videresender denne ruten til Apollo-serveren på `http://it2810-20.idi.ntnu.no:3001/`. Dette unngår at nettleseren trenger direkte CORS-tilgang til backend mens man utvikler. -For production, configure the web server to proxy `/api/graphql` to the Apollo server and serve the site over HTTPS. Alternatively, set `VITE_GRAPHQL_URL` to an HTTPS GraphQL endpoint and configure CORS on Apollo to allow the site's origin. Do not expose the MongoDB connection string to the frontend. City search, filters, pagination, and reviews use the API; saved cities remain in the current browser because the API does not provide account or bookmark operations. +## Teknologistack -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +| Lag | Teknologi | Rolle | +|---|---|---| +| **Frontend** | React 19 + TypeScript | Brukergrensesnitt og klienttilstand | +| | Vite 8 | Utviklingsserver, proxy og bygg | +| | Fetch API | Sender GraphQL-operasjoner som HTTP POST; Apollo Client er ikke installert | +| **Backend** | Apollo Server | GraphQL-API på port `3001` | +| **Database** | MongoDB | Lagring på VM, nås av backend | +| **Kvalitet** | TypeScript | Typekontroll ved produksjonsbygg | +| | ESLint | Linting | -Currently, two official plugins are available: +> **Viktig prinsipp:** Søk, filtrering, sortering og paginering sendes til GraphQL-backend. Frontend-en henter bare siden med byer den skal vise. -- [@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/) +## Funksjonalitet -## React Compiler +### Søk og navigering +- [x] Søker på bynavn med case-insensitiv delstrengsmatching via `searchCities`. +- [x] Henter 12 byer om gangen og kan laste inn flere med `offset`-paginering. +- [x] Viser totalt antall treff og om det finnes flere resultater. -The React Compiler is enabled on this template. See [this documentation](https://react.dev/learn/react-compiler) for more information. +### Filtrering og sortering +- [x] Filtrerer på land. +- [x] Filtrerer på befolkningsintervall. +- [x] Sorterer alfabetisk, etter land eller etter befolkning. +- [ ] Filter- og søkevalg gjenopprettes ikke etter omlasting av siden. -Note: This will impact Vite dev & build performances. -You can also try [the experimental native React Compiler support in plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md#rust-react-compiler) by using `compiler: true` in the plugin options instead of using the Babel plugin. +### Anmeldelser og bokmerker +- [x] Viser byens gjennomsnittsvurdering, antall anmeldelser og eksisterende anmeldelser. +- [x] Sender nye anmeldelser til backend med `addReview`-mutasjonen. +- [x] Lagrer bokmerker i nettleserens `localStorage`. +- [ ] Bokmerker er ikke knyttet til en bruker og synkroniseres ikke mellom enheter. +- [ ] API-et eksponerer ikke innlogging eller brukeradministrasjon. -## Expanding the ESLint configuration +### Tilgjengelighet og feiltilstander +- [x] Viser lasting, tomt resultat og API-feil med mulighet for å prøve på nytt. +- [x] Søk, knapper og skjemaelementer har tilgjengelige etiketter og tastaturfokus. -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: +## Kom i gang -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... +### Forutsetninger +- Node.js 24 eller nyere. +- pnpm. +- Tilgang til NTNU-nettet eller NTNU-VPN for å nå backend-VM-en. - // 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, +### Installasjon og utvikling - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +Kjør kommandoene fra prosjektmappen: +```bash +pnpm install +pnpm dev ``` -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... - }, - }, -]) +Vite skriver ut lokal URL når serveren starter, vanligvis `http://localhost:5173/`. + +### Scripts +| Kommando | Beskrivelse | +|---|---| +| `pnpm dev` | Starter Vite-utviklingsserver med GraphQL-proxy | +| `pnpm build` | Kjører TypeScript-kontroll og bygger for produksjon | +| `pnpm lint` | Kjører ESLint | +| `pnpm preview` | Forhåndsviser produksjonsbygget lokalt | + +Det er ikke konfigurert et eget testscript i `package.json` ennå. + +## Database og API + +MongoDB kjører på VM-en og skal bare nås av Apollo-backend. Frontend-en bruker GraphQL-endepunktet: + +```text +http://it2810-20.idi.ntnu.no:3001/ ``` + +I utviklingsmodus er Vite-proxyen definert i `vite.config.ts`. Klienten i `src/graphql.ts` bruker `/api/graphql` som standard. En alternativ offentlig GraphQL-adresse kan settes ved bygging med `VITE_GRAPHQL_URL`. + +### GraphQL-operasjoner som frontend bruker + +| Operasjon | Bruk | +|---|---| +| `searchCities` | Søk, land-/befolkningsfilter, sortering og paginering. Backend setter en øvre grense på 100 treff per kall. | +| `countries` | Fyller landfilteret. | +| `addReview` | Lagrer en anmeldelse for en by. | + +Test for eksempel følgende spørring i Apollo Sandbox når du er på NTNU-nettet eller VPN: + +```graphql +query { + searchCities(limit: 3, offset: 0) { + totalCount + hasMore + items { + id + name + country + } + } +} +``` + +### Sikkerhet og produksjon + +- MongoDB-adresse, brukernavn og passord skal aldri legges i frontend eller sendes til nettleseren. +- Apollo-endepunktet bruker HTTP i dagens VM-oppsett. Dersom frontend publiseres over HTTPS, må webserveren proxy `/api/graphql` til Apollo over backend-nettverket, eller Apollo må tilgjengeliggjøres over HTTPS. +- Hvis produksjonen kaller Apollo direkte fra et annet domene, må backend konfigurere CORS for frontend-domenet. +- API-et har ikke autentisering nå. Anmeldelser sendes med navnet brukeren skriver inn; navnet er ikke verifisert som en identitet. +- API-endepunktet kan kreve NTNU-nett eller VPN. En offentlig frontend blir ikke tilgjengelig for eksterne brukere før nettverkstilgangen til backend er avklart. + +## Arbeidsflyt + +Gjør endringer i en egen branch og bruk pull request for gjennomgang. + +Før pull request: + +```bash +pnpm lint +pnpm build +``` + +## Dokumentasjon + +- Denne README-en beskriver funksjoner, teknologistack og hvordan frontend kommuniserer med API-et. +- GraphQL-operasjonene og klientkallet ligger i `src/App.tsx` og `src/graphql.ts`. +- Lokal GraphQL-proxy er definert i `vite.config.ts`. +- Endringer i backend-schemaet må gjenspeiles i GraphQL-operasjonene og TypeScript-typene i frontend. \ No newline at end of file