{"id":13807808,"url":"https://github.com/starter-kits-usmb/front-angular","last_synced_at":"2025-05-14T00:32:10.554Z","repository":{"id":221157218,"uuid":"707635436","full_name":"starter-kits-usmb/front-angular","owner":"starter-kits-usmb","description":"starter kit with angular ","archived":false,"fork":false,"pushed_at":"2024-08-04T14:14:04.000Z","size":2012,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-11-18T23:53:39.847Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/starter-kits-usmb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-10-20T10:22:30.000Z","updated_at":"2024-10-20T14:04:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"1e5061d6-62b9-4739-ab50-2b474dc90d80","html_url":"https://github.com/starter-kits-usmb/front-angular","commit_stats":null,"previous_names":["starter-kits-usmb/front-angular"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starter-kits-usmb%2Ffront-angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starter-kits-usmb%2Ffront-angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starter-kits-usmb%2Ffront-angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/starter-kits-usmb%2Ffront-angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/starter-kits-usmb","download_url":"https://codeload.github.com/starter-kits-usmb/front-angular/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254046416,"owners_count":22005591,"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":[],"created_at":"2024-08-04T01:01:30.643Z","updated_at":"2025-05-14T00:32:05.543Z","avatar_url":"https://github.com/starter-kits-usmb.png","language":"HTML","readme":"# AngularStarterKit\n\nThis starter kit use angular version `18.0.0` and includes the following features:\n\n- [x] Scalable folder structure\n- [x] Linter and prettier\n- [x] Routing and lazy loading\n- [x] Authentication service\n- [x] Light design system and layout utilities (css class based)\n- [x] Toast service (snackbar and loading screen)\n- [x] Modal service (support custom modals)\n- [x] Test setup (jest)\n- [x] docker compose for production\n\n## Start from this template\n\n1. Clone this repository\n2. Delete `.git` folder and run `git init` to start a new repository\n3. Run `npm install`\n4. Run `ng serve` to start the development server\n5. Navigate to `http://localhost:4200/`.\n\n## Build\n\nRun `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.\n\n## Running unit tests\n\nRun `ng test` to execute the unit tests via jest.\n\n# Guidelines\n\n## Folder structure\n\n```bash\npublic/\n├─ assets/ # static assets\n│  ├─ icons/\n│  ├─ illustrations/\nsrc/\n├─ app/ # source code of the application\n│  ├─ core/ # core components and classes etc\n│  │  ├─ components/ # generic components and header, footer etc..\n│  │  ├─ constants/ # constants for the app\n│  │  ├─ guards/ # guards for routes\n│  │  ├─ interceptors/ # interceptors for http requests\n│  │  ├─ models/ # models, interfaces for your app\n│  │  ├─ services/ # general services\n│  ├─ modules/ # features\n│  ├─ styles/ # global styles\n│  ├─ app.component.ts # the root component (there is more files hidden for simplicity)\n├─ environments/ # environment variables. DO NOT PUT SECRETS HERE. THIS IS VISIBILE IN THE BROWSER\n```\n\n## linter and prettier\n\nSetup your ide to lint and format on save. This will help you to keep the code clean and consistent.\n\nfor vscode, install the following extensions:\n\n- prettier\n- eslint\n\nand configure them to lint on save.\n\n## Routing and lazy loading\n\nThe app is using standalone components. This means that the components are loaded only when the user navigates to the route. This is a good practice to improve the performance of the app. The routing is configured in `app.routes.ts` file.\n\n## Authentication service\n\nThe `AuthService` allows you to authenticate a user and keep it logged in thanks to localstorage with a JWT token.\n\n### Before starting\n\ndon't forget to unsubscribe from observables. The easiest way is to use `takeUntil`as last operator of your pipe\n\n```typescript\nsomeobservable$.pipe(takeUntil(this.destroyed$)).subscribe( ... )\n```\n\n### AuthService\n\nFirst you need to import the authService and inject it.\n\n```typescript\nconstructor(private readonly authService:AuthService){}\n```\n\n##### services attributes\n\nYou can retrieve the user's token and check if the user is connected.\n\n```typescript\nconst userToken: string = authService.token;\nconst isUserConnected: boolean = authService.connected;\n```\n\n### Login\n\nconnect a user. This method will automatically save the JWT token in the service and the local storage.\nIn case of failure it will show an error toast.\n\n```typescript\nauthService.login(login: string, password: string)\n  .pipe(takeUntil(this.destroy$))\n  .subscribe((loggedIn: boolean) =\u003e {\n    if (loggedIn) {\n      // Successfully logged in\n    } else {\n      // Handle login failure\n    }\n  });\n```\n\n### Register\n\nTo allow users to create a new account. This will NOT connect the user.\nIn case of failure it will show an error toast.\n\n```typescript\nauthService.register(login: string, password: string)\n  .pipe(takeUntil(this.destroy$))\n  .subscribe((registered: boolean) =\u003e {\n    if (registered) {\n      // Successfully registered\n    } else {\n      // Handle registration failure\n    }\n  });\n```\n\n### Checking Token Validity\n\nYou can check the validity of the user's token by using the `isTokenValid` method.\nIf the token is invalid, the user will be logged out.\n\n```typescript\nauthService\n  .isTokenValid()\n  .pipe(takeUntil(this.destroy$))\n  .subscribe((isValid: boolean) =\u003e {\n    if (isValid) {\n      // Token is valid\n    } else {\n      // Token is invalid or expired\n    }\n  });\n```\n\n### Logout\n\nTo disconnect the user and clear their token.\n\n```typescript\nauthService.logout();\n```\n\nThat's it! You can now use the `AuthService` !\n\n## Modal service \u0026 custom modals\n\nThe modal service allows you to open a modal and close it from anywhere in the app. It also allows you to create custom modals.\n\n### Create a custom modal\n\nLet's create the UsernameModalComponent.\n\nFirst be sure that the module where UsernameModalComponent is declared has imported the `SharedModule`.\n\n#### username-modal.component.ts\n\nTo create a custom modal, you need to create a component that extends the `BaseModalComponent`, it allows you to open the modal with the service. You can modify the payload in your `handleClose` function.\n\n```typescript\nexport class UsernameModalComponent extends BaseModalComponent {\n  username: string = '';\n\n  constructor() {\n    super();\n  }\n\n  handleClose(event: ModalPayload) {\n    const editedPayload = { ...event, data: this.username };\n    this.onClose(editedPayload);\n  }\n}\n```\n\n#### username-modal.component.html\n\nIn the template you will need to use the modal component `app-modal`. This component will handle the modal logic \u0026 options. You can add your custom content inside the modal\n\n**You have to**\n\n- pass the `options` _(inherited from BaseModalComponent)_\n- define the function `handleClose` that will be called when the user close the modal.\n\nThe `validator` is optional and allows you to disable the confirm button if the validator returns false.\n\n```html\n\u003capp-modal\n  [options]=\"options\"\n  [validator]=\"username !== ''\"\n  (closeEvent)=\"handleClose($event)\"\u003e\n  \u003c!-- custom info --\u003e\n  \u003cdiv class=\"w-100 flex-col center middle\"\u003e\n    \u003cinput\n      type=\"text\"\n      class=\"basic\"\n      placeholder=\"basic input\"\n      [(ngModel)]=\"username\"\n      placeholder=\"Name\" /\u003e\n  \u003c/div\u003e\n\u003c/app-modal\u003e\n```\n\n### The service\n\nFirst you need to import the modalService and inject it.\n\n```typescript\nconstructor(private readonly modalService:ModalService){}\n```\n\nThen you can either open any modal. Modals options are always optionals. you can custom mutliple options like the title, the size, the data etc...\n\n```typescript\nexport interface ModalOptions {\n  title?: string;\n  message?: string;\n  confirmText?: string;\n  cancelText?: string;\n  confirmColor?: string;\n  cancelColor?: string;\n}\n```\n\nHere are the default options.\n\n```typescript\n{\n  title: 'Modal title',\n  message: '',\n  confirmText: 'Yes',\n  cancelText: 'No',\n  confirmColor: 'primary',\n  cancelColor: 'basic'\n}\n```\n\n```typescript\nopenModal() {\n    this.modalService\n      .open(YourModalComponent, { title: \"What's your name ?\" })\n      .subscribe(payload =\u003e {\n        if (payload.success) {\n          // Do something, the modal was confirmed\n        } else {\n          // Do something else the modal was canceled\n        }\n      });\n  }\n```\n\nYou can also open a confirmation modal (under the hood it's just a basic modal with different default options)\n\n```typescript\n{\n  title: 'Please confirm your choice',\n  message: 'Are you sure you want to do this?',\n  cancelText: 'Cancel',\n  confirmText: 'Confirm',\n  confirmColor: 'danger',\n}\n```\n\n```typescript\nopenConfirmModal() {\n    this.modalService.openConfirmModal().subscribe(payload =\u003e {\n      if (payload.success) {\n        // Do something, user confirmed\n      } else {\n        // Do something else user canceled\n      }\n    });\n  }\n```\n\nAnd that's it! You can now use your modal ! You can check the `CustomModalComponent` in the app (in the `starter-kit` module) for a working example.\n\n## Language service (i18n)\n\nsee angular internationalization documentation for more information: [angular i18n](https://angular.dev/guide/i18n)\n\n#### Using the pipe\n\n```html\n\u003cp\u003e{{ 'global.title' | translate }}\u003c/p\u003e\n```\n\n#### Using the service\n\n```typescript\nconstructor(private readonly languageService: LanguageService) {}\n\nngOnInit() {\n  this.languageService.getTranslation('global.title').pipe(take(1)).subscribe((translation: string) =\u003e {\n    console.log(translation); // Hello world\n  });\n}\n```\n\n## Design system\n\nThis is a very light design system, based on css classes. The idea is to have a set of classes that can be used to build the UI.\n\n### Flex layout\n\nThe syntax is `.flex-\u003cdirection\u003e`.\nThe direction can be `row` or `col` and it can be combined with the following modifiers:\n`.left`, `.center`, `.right` for the x-axis\n`.top`, `.middle`, `.bottom` for the y-axis\n`.btw` for space between elements following the direction\n`.wrap`, `.wrap-reverse` for wrapping elements\nfor wrapping elements in reverse order\n`.no-gap`, `.small-gap`, `.micro-gap` for the gap between elements. By default, the gap is 1rem.\n\n### Grid layout\n\nThe syntax is `.grid-\u003crow/col\u003e-\u003cnumber\u003e`.\nThe number can be from 2 to 5 and symbolize the number of columns/rows.\n\n### Sizes\n\nThe syntax is `.h-\u003csize\u003e` for height and `.w-\u003csize\u003e` for width.\n`full` size is 100vw or 100vh\n`100` and `50` are % values.\n\n### Variables\n\nThe variables are defined in `src/styles/variables.scss` file. You can use them in your components by importing them. Use them as much as possible to keep the design consistent.\n\n```scss\n@import '/src/app/styles/variables.scss';\n```\n\n### Responsive\n\nFor responsive design, use flex layout and grid layout as much as possible and avoid `px` values. Use `vw`/`vh` `rem` and `%` values instead.\n\nYou can also use the following mixins:\n\n```scss\n@import '/src/app/styles/mixins.scss';\n\n.my-class {\n  //default styles (in this case for width 300px to 600px)\n\n  @include width-under(300px) {\n    // styles for width under 300px\n  }\n\n  @include width-over(600px) {\n    // styles for width over 600px\n  }\n}\n```\n","funding_links":[],"categories":["Table of contents"],"sub_categories":["Angular"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarter-kits-usmb%2Ffront-angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstarter-kits-usmb%2Ffront-angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarter-kits-usmb%2Ffront-angular/lists"}