{"id":18614778,"url":"https://github.com/andrewjbateman/angular-tailwind-ratp","last_synced_at":"2025-10-29T16:33:24.381Z","repository":{"id":42531842,"uuid":"323968325","full_name":"AndrewJBateman/angular-tailwind-ratp","owner":"AndrewJBateman","description":":clipboard: Angular app to show JSON data from the RATP (French transport system) API","archived":false,"fork":false,"pushed_at":"2024-01-19T09:24:08.000Z","size":8753,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-25T06:51:15.238Z","etag":null,"topics":["angular","angular17","api-rest","deploy","deployment","lighthouse","netlify","pwa","ratp","rxjs","rxjs7","scss-styles","tailwind-purge","tailwindcss"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AndrewJBateman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-23T17:54:10.000Z","updated_at":"2024-01-14T15:49:44.000Z","dependencies_parsed_at":"2024-11-07T03:40:54.549Z","dependency_job_id":null,"html_url":"https://github.com/AndrewJBateman/angular-tailwind-ratp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewJBateman%2Fangular-tailwind-ratp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewJBateman%2Fangular-tailwind-ratp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewJBateman%2Fangular-tailwind-ratp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndrewJBateman%2Fangular-tailwind-ratp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndrewJBateman","download_url":"https://codeload.github.com/AndrewJBateman/angular-tailwind-ratp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248322228,"owners_count":21084333,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","angular17","api-rest","deploy","deployment","lighthouse","netlify","pwa","ratp","rxjs","rxjs7","scss-styles","tailwind-purge","tailwindcss"],"created_at":"2024-11-07T03:26:58.030Z","updated_at":"2025-10-29T16:33:19.331Z","avatar_url":"https://github.com/AndrewJBateman.png","language":"TypeScript","readme":"# :zap: Angular Tailwind RATP\n\n* Angular app using [TailwindCSS](https://tailwindcss.com/) components to display information from the [Paris Public Transport RATP API](https://data.ratp.fr/explore/?sort=modified\u0026refine.publisher=RATP) \u0026 the [Seine Ouest API](https://data.seineouest.fr/pages/accueil/) disabled parking data\n* **Note:** to open web links in a new window use: _ctrl+click on link_\n\n![GitHub repo size](https://img.shields.io/github/repo-size/AndrewJBateman/angular-tailwind-ratp?style=plastic)\n![GitHub pull requests](https://img.shields.io/github/issues-pr/AndrewJBateman/angular-tailwind-ratp?style=plastic)\n![GitHub Repo stars](https://img.shields.io/github/stars/AndrewJBateman/angular-tailwind-ratp?style=plastic)\n![GitHub last commit](https://img.shields.io/github/last-commit/AndrewJBateman/angular-tailwind-ratp?style=plastic)\n\n## :page_facing_up: Table of contents\n\n* [:zap: Angular Tailwind RATP](#zap-angular-tailwind-ratp)\n  * [:page\\_facing\\_up: Table of contents](#page_facing_up-table-of-contents)\n  * [:books: General info](#books-general-info)\n  * [:camera: Screenshots](#camera-screenshots)\n  * [:signal\\_strength: Technologies](#signal_strength-technologies)\n  * [:floppy\\_disk: Setup](#floppy_disk-setup)\n  * [:wrench: Testing](#wrench-testing)\n  * [:computer: Code Examples](#computer-code-examples)\n  * [:cool: Features](#cool-features)\n  * [:clipboard: Status \\\u0026 To-Do List](#clipboard-status--to-do-list)\n  * [:clap: Inspiration](#clap-inspiration)\n  * [:file\\_folder: License](#file_folder-license)\n  * [:envelope: Contact](#envelope-contact)\n\n## :books: General info\n\n* Home page: User post code search will show a list of retail outlets open to the public within the vicinity of the local RATP station. Note, only post codes with RATP stations will show a list (e.g. 75005 Paris has RATP, but 31000 Toulouse has no RATP), otherwise an error message is shown to try a different post code.\n* [Tailwind Responsive Table](https://tailwindcomponents.com/component/responsive-table-1) used to show RATP data\n* RATP page: shows status of metro, rer \u0026 tramways using Tailwind micro-cards\n* Parking page: shows location of disabled parking as a cluster of icons+popups on a Leaflet map\n* About and Contact pages give more information on app using Tailwind css cards\n* Website is in French\n* To build for production Tailwind’s purge option is used to tree-shake unused styles and optimize final build size.\n* [rxjs take(1) operater](https://advancedweb.hu/rxjs-the-differences-between-first-take-1-and-single/) used to take first element from the Github observable then close it, so unsubscribing is not necessary.\n* Latest ng flow control @if and @for used in HTML templates.\n\n## :camera: Screenshots\n\n![Example screenshot](./img/home.jpg)\n![Example screenshot](./img/about.jpg)\n![Example screenshot](./img/contact.jpg)\n![Example screenshot](./img/parking.png)\n\n## :signal_strength: Technologies\n\n* [Angular framework v17](https://angular.io/)\n* [@angular/forms v17](https://angular.io/api/forms) used with [PatternValidator](https://angular.io/api/forms/PatternValidator)\n* [Reactive Extensions Library for Javascript RxJS v7](https://rxjs.dev/)\n* [Tailwindcss v3](https://tailwindcss.com/) CSS framework\n* [Angular PWA v17](https://angular.io/guide/service-worker-getting-started)\n* [Leaflet v1](https://leafletjs.com/) open-source JavaScript library\nfor mobile-friendly interactive maps\n* [Leaflet Marker Cluster v1](https://github.com/Leaflet/Leaflet.markercluster) Marker Clustering plugin JS library for interactive maps\n\n## :floppy_disk: Setup\n\n* Run `npm i` to install dependencies\n* No API keys required\n* Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files\n* Run `npm run build` for a production build with css purging. Add defer to index.html css link\n* Run `http-server -p 8080 -c-1 dist/angular-tailwind-ratp` to view build on an apple/android phone or simulator (pick 2nd http address supplied)\n* The build files will be stored in the `dist/angular-tailwind-ratp` directory\n\n## :wrench: Testing\n\n* No tests set up\n\n## :computer: Code Examples\n\n* `ratp.service.ts` - function to fetch RATP API data based on a postcode string input\n\n```typescript\ngetRatpCommerceData(query: string): Observable\u003cRatpResponse\u003e {\n  const params = new HttpParams()\n    .set('dataset', 'commerces-de-proximite-agrees-ratp')\n    .set('q', query)\n    .set('rows', '10')\n    .set('refine.sort', '-code_postal');\n\n  const userSearchUrl = `${this.baseUrl}${params.toString()}`;\n\n  this.ratpCommerceData = this.http.get\u003cRatpResponse\u003e(userSearchUrl).pipe(\n    catchError(err =\u003e {\n      throw new Error('Error in getting API data. Details: ' + err);\n    })\n  );\n\n  return this.ratpCommerceData;\n}\n```\n\n## :cool: Features\n\n* The RATP \u0026 Github APIs do not require an API key\n* Lazy-loading of all pages except 'Home'\n* HTTP headers added due to Content Security Policy for prefetch-src, X Content Type Options, X Frame Options, Content Security Policy\n* Postcode search form with validation and error messages checks that only a 5-number postcode is entered\n* Tailwind build for production css purge results in a very small styles bundle (8.16kB latest)\n* Progressive Web App (PWA)\n* Excellent Google Chrome Lighthouse scores for pages: home: 100%, about: 100%, contact 98%\n* Netlify deployment set up so commiting a build folder to Github will update the deployment automatically\n\n## :clipboard: Status \u0026 To-Do List\n\n* Status: Working, deployed to Netlify. All files pass linting. App passes unit tests.\n* To-Do: Correct Home delay to render results \u0026 uncomment index.html CSP. Redo SSR. Add tests\n\n## :clap: Inspiration\n\n* [Angular Architects: article: Extending the Angular CLI’s build process without ejecting](https://www.angulararchitects.io/aktuelles/extending-the-angular-clis-build-process/)\n* [List of French postal codes](http://www.bioreference.net/encyclopedia/wikipedia/l/li/list_of_french_postal_codes.html)\n* [RATP API doc: Commerces de proximité agréés RATP](https://dataratp2.opendatasoft.com/explore/dataset/liste-des-commerces-de-proximite-agrees-ratp/api/?sort=code_postal)\n* [StackOverflow: How to solve semi-colon expected css(css-semicolonexpected)](https://stackoverflow.com/questions/61443484/how-to-solve-semi-colon-expected-csscss-semicolonexpected)\n* [dev.to: Setup TailwindCSS in Angular the easy way](https://dev.to/angular/setup-tailwindcss-in-angular-the-easy-way-1i5l)\n* [CSP: prefetch-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/prefetch-src)\n* [How does Content Security Policy (CSP) work?](https://stackoverflow.com/questions/30280370/how-does-content-security-policy-csp-work)\n* [Mozilla, Link prefetching FAQ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ)\n* [Mozilla, X-XSS-Protection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection)\n* [Website scanner for JavaScript vulnerabilities and security headers](https://snyk.io/test/website-scanner)\n* [Stackoverflow: combine-ngstyle-with-condition-if-else](https://stackoverflow.com/questions/37051496/combine-ngstyle-with-condition-if-else)\n* [Angular Material Dialog: A Complete Example](https://blog.angular-university.io/angular-material-dialog/)\n\n## :file_folder: License\n\n* This project is licensed under the terms of the MIT license.\n\n## :envelope: Contact\n\n* Repo created by [ABateman](https://github.com/AndrewJBateman), email: `gomezbateman@yahoo.com`\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewjbateman%2Fangular-tailwind-ratp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewjbateman%2Fangular-tailwind-ratp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewjbateman%2Fangular-tailwind-ratp/lists"}