├── src ├── assets │ ├── .gitkeep │ ├── images │ │ ├── logo │ │ │ ├── login.png │ │ │ └── my-logo.png │ │ └── authpage │ │ │ ├── signup.jpg │ │ │ ├── singupTwo.png │ │ │ └── profile-image.jpg │ └── data │ │ └── images.ts ├── app │ ├── app.component.css │ ├── admin │ │ ├── admin.component.css │ │ ├── views │ │ │ ├── events │ │ │ │ ├── events.component.css │ │ │ │ ├── test │ │ │ │ │ ├── test.component.css │ │ │ │ │ ├── test.component.html │ │ │ │ │ └── test.component.ts │ │ │ │ ├── events.component.html │ │ │ │ └── events.component.ts │ │ │ ├── dashboard │ │ │ │ ├── dashboard.component.css │ │ │ │ ├── dashboard.component.ts │ │ │ │ └── dashboard.component.html │ │ │ ├── elements │ │ │ │ ├── buttons │ │ │ │ │ ├── buttons.component.css │ │ │ │ │ ├── buttons.component.ts │ │ │ │ │ └── buttons.component.html │ │ │ │ ├── forms │ │ │ │ │ ├── forms.component.css │ │ │ │ │ ├── forms.component.ts │ │ │ │ │ └── forms.component.html │ │ │ │ ├── tab │ │ │ │ │ ├── admin-tab.component.css │ │ │ │ │ ├── admin-tab.component.html │ │ │ │ │ ├── admin-tab.component.ts │ │ │ │ │ └── tab-items.ts │ │ │ │ ├── alert │ │ │ │ │ ├── admin-alert.component.css │ │ │ │ │ ├── admin-alert.component.ts │ │ │ │ │ └── admin-alert.component.html │ │ │ │ ├── modal │ │ │ │ │ ├── admin-modal.component.css │ │ │ │ │ ├── admin-modal.component.ts │ │ │ │ │ └── admin-modal.component.html │ │ │ │ ├── data-table │ │ │ │ │ ├── data-table.component.css │ │ │ │ │ ├── data-table.component.html │ │ │ │ │ ├── data-table.component.ts │ │ │ │ │ └── table.data.ts │ │ │ │ └── elements.module.ts │ │ │ ├── settings │ │ │ │ ├── profile │ │ │ │ │ ├── profile.component.css │ │ │ │ │ ├── profile.component.html │ │ │ │ │ └── profile.component.ts │ │ │ │ ├── users │ │ │ │ │ ├── users.component.css │ │ │ │ │ ├── users.component.html │ │ │ │ │ └── users.component.ts │ │ │ │ └── settings.module.ts │ │ │ └── admin-page-not-found │ │ │ │ ├── admin-page-not-found.component.css │ │ │ │ ├── admin-page-not-found.component.html │ │ │ │ └── admin-page-not-found.component.ts │ │ ├── layouts │ │ │ ├── footer │ │ │ │ ├── footer.component.css │ │ │ │ ├── footer.component.html │ │ │ │ └── footer.component.ts │ │ │ ├── header │ │ │ │ ├── header.component.css │ │ │ │ ├── header.component.ts │ │ │ │ └── header.component.html │ │ │ ├── layouts.module.ts │ │ │ └── sidebar │ │ │ │ ├── sidebar-collapse.directive.ts │ │ │ │ ├── sidebar.component.ts │ │ │ │ ├── sidebar.component.css │ │ │ │ └── sidebar.component.html │ │ ├── admin.component.html │ │ ├── admin.routes.ts │ │ ├── admin.component.ts │ │ ├── admin.module.ts │ │ └── admin-routing.module.ts │ ├── public │ │ ├── home │ │ │ ├── home.component.css │ │ │ ├── home.component.ts │ │ │ └── home.component.html │ │ ├── public.component.css │ │ ├── auth │ │ │ ├── signin │ │ │ │ ├── signin.component.css │ │ │ │ ├── signin.model.ts │ │ │ │ ├── signin.component.ts │ │ │ │ └── signin.component.html │ │ │ ├── signup │ │ │ │ ├── signup.component.css │ │ │ │ ├── signup.component.ts │ │ │ │ └── signup.component.html │ │ │ ├── auth.response.ts │ │ │ ├── auth.service.ts │ │ │ ├── auth-routing.module.ts │ │ │ └── auth.module.ts │ │ ├── layouts │ │ │ ├── footer │ │ │ │ ├── footer.component.css │ │ │ │ ├── footer.component.ts │ │ │ │ └── footer.component.html │ │ │ └── header │ │ │ │ ├── header.component.css │ │ │ │ ├── header.component.ts │ │ │ │ └── header.component.html │ │ ├── page-not-found │ │ │ ├── page-not-found.component.css │ │ │ ├── page-not-found.component.html │ │ │ └── page-not-found.component.ts │ │ ├── public.routes.ts │ │ ├── public.component.html │ │ ├── public.component.ts │ │ ├── public-routing.module.ts │ │ └── public.module.ts │ ├── shared │ │ ├── components │ │ │ ├── spinner │ │ │ │ ├── spinner.component.css │ │ │ │ ├── spinner.component.ts │ │ │ │ └── spinner.component.html │ │ │ ├── preloader │ │ │ │ ├── preloader.component.css │ │ │ │ ├── preloader.component.html │ │ │ │ └── preloader.component.ts │ │ │ ├── validation-error │ │ │ │ ├── validation-error.component.css │ │ │ │ ├── error-messages.ts │ │ │ │ ├── validation-error.component.html │ │ │ │ └── validation-error.component.ts │ │ │ ├── alert │ │ │ │ ├── alert.type.ts │ │ │ │ ├── alert.component.html │ │ │ │ ├── alert.component.css │ │ │ │ └── alert.component.ts │ │ │ ├── ngw-tab │ │ │ │ ├── ngw-tab-contents.type.ts │ │ │ │ ├── directives │ │ │ │ │ ├── ngw-tab-body.directive.ts │ │ │ │ │ ├── ngw-tab-item.directive.ts │ │ │ │ │ ├── ngw-tab-title.directive.ts │ │ │ │ │ ├── ngw-tab.directive.ts │ │ │ │ │ ├── ngw-tab-content.directive.ts │ │ │ │ │ ├── ngw-tab-link.directive.ts │ │ │ │ │ └── ngw-tab.module.ts │ │ │ │ ├── ngw-tab.component.html │ │ │ │ ├── ngw-tab.component.css │ │ │ │ └── ngw-tab.component.ts │ │ │ ├── data-table │ │ │ │ ├── data-table.module.ts │ │ │ │ ├── data-table.component.ts │ │ │ │ ├── data-table.component.css │ │ │ │ └── data-table.component.html │ │ │ ├── button │ │ │ │ ├── button.module.ts │ │ │ │ └── directives │ │ │ │ │ └── app-btn-blue.directive.ts │ │ │ └── modal │ │ │ │ ├── modal.module.ts │ │ │ │ ├── modal.component.ts │ │ │ │ ├── modal.component.css │ │ │ │ └── modal.component.html │ │ ├── interfaces │ │ │ └── error.interface.ts │ │ ├── utils │ │ │ ├── utils.providers.ts │ │ │ ├── notyf.token.ts │ │ │ └── animations.ts │ │ └── services │ │ │ └── localStorage.service.ts │ ├── app.component.html │ ├── app.routes.ts │ ├── _core │ │ ├── helpers │ │ │ └── datetime.helper.ts │ │ ├── strategies │ │ │ ├── strategy.providers.ts │ │ │ └── AppTitleStrategy.ts │ │ ├── services │ │ │ └── common.service.ts │ │ └── interceptors │ │ │ ├── interceptors.provider.ts │ │ │ ├── requests.interceptor.ts │ │ │ └── errors.interceptor.ts │ ├── app.component.ts │ ├── app.module.ts │ └── app-routing.module.ts ├── favicon.ico ├── environments │ ├── environment.ts │ └── environment.development.ts ├── main.ts ├── index.html └── styles.css ├── docs ├── image.png ├── favicon.ico ├── assets │ ├── images │ │ ├── logo │ │ │ ├── login.png │ │ │ └── my-logo.png │ │ └── authpage │ │ │ ├── signup.jpg │ │ │ ├── singupTwo.png │ │ │ └── profile-image.jpg │ └── data │ │ └── images.ts ├── index.html ├── runtime.js.map └── runtime.js ├── .vscode ├── extensions.json ├── launch.json └── tasks.json ├── tsconfig.app.json ├── tsconfig.spec.json ├── .editorconfig ├── tailwind.config.js ├── .gitignore ├── tsconfig.json ├── LICENSE ├── package.json ├── README.md └── angular.json /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/admin.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/home/home.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/public.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/events/events.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/auth/signin/signin.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/auth/signup/signup.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/layouts/footer/footer.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/dashboard/dashboard.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/events/test/test.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/layouts/footer/footer.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/buttons/buttons.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/forms/forms.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/tab/admin-tab.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/profile/profile.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/users/users.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/public/page-not-found/page-not-found.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/spinner/spinner.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/alert/admin-alert.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/modal/admin-modal.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/shared/components/preloader/preloader.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/data-table/data-table.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/validation-error/validation-error.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/image.png -------------------------------------------------------------------------------- /src/app/admin/layouts/footer/footer.component.html: -------------------------------------------------------------------------------- 1 |

footer works!

2 | -------------------------------------------------------------------------------- /src/app/admin/views/admin-page-not-found/admin-page-not-found.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/admin/views/events/test/test.component.html: -------------------------------------------------------------------------------- 1 |

test works!

2 | -------------------------------------------------------------------------------- /src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | export enum AppRoutes{ 2 | Admin = "admin", 3 | } -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/app/shared/components/preloader/preloader.component.html: -------------------------------------------------------------------------------- 1 |

preloader works!

2 | -------------------------------------------------------------------------------- /src/app/public/page-not-found/page-not-found.component.html: -------------------------------------------------------------------------------- 1 |

page-not-found works!

2 | -------------------------------------------------------------------------------- /docs/assets/images/logo/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/assets/images/logo/login.png -------------------------------------------------------------------------------- /src/app/admin/views/admin-page-not-found/admin-page-not-found.component.html: -------------------------------------------------------------------------------- 1 |

admin-page-not-found works!

2 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/users/users.component.html: -------------------------------------------------------------------------------- 1 |
2 |

users works!

3 |
-------------------------------------------------------------------------------- /src/assets/images/logo/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/assets/images/logo/login.png -------------------------------------------------------------------------------- /src/assets/images/logo/my-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/assets/images/logo/my-logo.png -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | apiUrl: '' 4 | }; 5 | -------------------------------------------------------------------------------- /docs/assets/images/logo/my-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/assets/images/logo/my-logo.png -------------------------------------------------------------------------------- /docs/assets/images/authpage/signup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/assets/images/authpage/signup.jpg -------------------------------------------------------------------------------- /src/app/admin/views/settings/profile/profile.component.html: -------------------------------------------------------------------------------- 1 |
2 |

profile works!

3 |
4 | -------------------------------------------------------------------------------- /src/app/public/auth/signin/signin.model.ts: -------------------------------------------------------------------------------- 1 | export interface Signin { 2 | username: string; 3 | password: string; 4 | } -------------------------------------------------------------------------------- /src/app/shared/interfaces/error.interface.ts: -------------------------------------------------------------------------------- 1 | export interface IError { 2 | title: string; 3 | message: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/authpage/signup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/assets/images/authpage/signup.jpg -------------------------------------------------------------------------------- /docs/assets/images/authpage/singupTwo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/assets/images/authpage/singupTwo.png -------------------------------------------------------------------------------- /src/app/admin/views/elements/tab/admin-tab.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /src/app/public/auth/auth.response.ts: -------------------------------------------------------------------------------- 1 | export interface AuthResponse { 2 | token: string; 3 | RefreshToken: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/images/authpage/singupTwo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/assets/images/authpage/singupTwo.png -------------------------------------------------------------------------------- /src/app/public/public.routes.ts: -------------------------------------------------------------------------------- 1 | export enum PublicRoutes { 2 | Home = '', 3 | Signup = 'signup', 4 | Signin = 'signin', 5 | } 6 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.type.ts: -------------------------------------------------------------------------------- 1 | export enum AlertType { 2 | Success, 3 | Warning, 4 | Danger, 5 | Info, 6 | } 7 | -------------------------------------------------------------------------------- /src/assets/images/authpage/profile-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/src/assets/images/authpage/profile-image.jpg -------------------------------------------------------------------------------- /docs/assets/images/authpage/profile-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ANrajin/ngWind/HEAD/docs/assets/images/authpage/profile-image.jpg -------------------------------------------------------------------------------- /src/app/admin/views/elements/data-table/data-table.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/validation-error/error-messages.ts: -------------------------------------------------------------------------------- 1 | export const ERROR_MESSAGES = { 2 | required: () => "This field is required", 3 | } 4 | -------------------------------------------------------------------------------- /src/environments/environment.development.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: false, 3 | apiUrl: 'https://localhost:44327/' 4 | }; 5 | -------------------------------------------------------------------------------- /src/app/_core/helpers/datetime.helper.ts: -------------------------------------------------------------------------------- 1 | export class DatetimeHelper{ 2 | public static readonly currentYear : number = new Date().getFullYear(); 3 | } -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 3 | "recommendations": ["angular.ng-template"] 4 | } 5 | -------------------------------------------------------------------------------- /src/app/public/public.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | -------------------------------------------------------------------------------- /src/app/shared/utils/utils.providers.ts: -------------------------------------------------------------------------------- 1 | import {NOTYF, notyfFactory} from "./notyf.token"; 2 | 3 | export const UtilsProviders: object[] = [ 4 | {provide: NOTYF, useFactory: notyfFactory}, 5 | ] 6 | -------------------------------------------------------------------------------- /src/app/shared/components/validation-error/validation-error.component.html: -------------------------------------------------------------------------------- 1 | 2 | {{err}} 3 | 4 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/ngw-tab-contents.type.ts: -------------------------------------------------------------------------------- 1 | export interface NgwTabContents { 2 | Title: string; 3 | IsActive?: boolean; 4 | IsDisabled?: boolean; 5 | TabTitle?: string; 6 | Contents: string; 7 | } 8 | -------------------------------------------------------------------------------- /src/app/admin/views/events/events.component.html: -------------------------------------------------------------------------------- 1 |
2 |

events works!

3 | 4 | 5 |
6 | 7 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app/app.module'; 4 | 5 | 6 | platformBrowserDynamic().bootstrapModule(AppModule) 7 | .catch(err => console.error(err)); 8 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/_core/strategies/strategy.providers.ts: -------------------------------------------------------------------------------- 1 | import {TitleStrategy} from "@angular/router"; 2 | import {AppTitleStrategy} from "./AppTitleStrategy"; 3 | 4 | export const StrategyProviders: object[] = [ 5 | {provide: TitleStrategy, useClass: AppTitleStrategy} 6 | ]; 7 | -------------------------------------------------------------------------------- /src/app/public/public.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-public', 5 | templateUrl: './public.component.html', 6 | styleUrls: ['./public.component.css'] 7 | }) 8 | export class PublicComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/public/layouts/header/header.component.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler{ 2 | @apply -m-2.5 inline-flex items-center justify-center rounded-md p-2.5 text-gray-700 3 | } 4 | .nav-link{ 5 | @apply-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover: bg-gray-50 6 | } -------------------------------------------------------------------------------- /src/app/admin/layouts/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | templateUrl: './footer.component.html', 6 | styleUrls: ['./footer.component.css'] 7 | }) 8 | export class FooterComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/elements.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | 5 | 6 | @NgModule({ 7 | declarations: [], 8 | imports: [ 9 | CommonModule, 10 | ] 11 | }) 12 | export class ElementsModule { } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab-body.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTabBody]', 5 | standalone: true, 6 | host: { 7 | class: 'ngw-tab-body' 8 | } 9 | }) 10 | export class NgwTabBodyDirective { } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab-item.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTabItem]', 5 | standalone: true, 6 | host: { 7 | class: "ngw-tab-item" 8 | } 9 | }) 10 | export class NgwTabItemDirective { } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/data-table/data-table.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | 5 | 6 | @NgModule({ 7 | declarations: [], 8 | imports: [ 9 | CommonModule 10 | ] 11 | }) 12 | export class DataTableModule { } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab-title.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTabTitle]', 5 | standalone: true, 6 | host: { 7 | class: 'ngw-tab-title' 8 | } 9 | }) 10 | export class NgwTabTitleDirective { } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTab]', 5 | standalone: true, 6 | host: { 7 | class: 'ngw-tab-hr ngw-tab-container' 8 | } 9 | }) 10 | export class NgwTabDirective { } 11 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab-content.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTabContent]', 5 | standalone: true, 6 | host: { 7 | class: 'ngw-tab-content' 8 | } 9 | }) 10 | export class NgwTabContentDirective { } 11 | -------------------------------------------------------------------------------- /src/app/public/page-not-found/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-page-not-found', 5 | templateUrl: './page-not-found.component.html', 6 | styleUrls: ['./page-not-found.component.css'] 7 | }) 8 | export class PageNotFoundComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/forms/forms.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-forms', 5 | standalone: true, 6 | imports: [], 7 | templateUrl: './forms.component.html', 8 | styleUrl: './forms.component.css' 9 | }) 10 | export class FormsComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /src/app/admin/admin.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 |
7 | 8 |
9 |
10 |
-------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/app/admin/views/admin-page-not-found/admin-page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-admin-page-not-found', 5 | templateUrl: './admin-page-not-found.component.html', 6 | styleUrls: ['./admin-page-not-found.component.css'] 7 | }) 8 | export class AdminPageNotFoundComponent { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/app/_core/services/common.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | 7 | export class CommonService { 8 | constructor() { } 9 | 10 | public prepareRoute(...paths: string[]): string{ 11 | let rootRoute = '/'; 12 | return rootRoute.concat(paths.filter(Boolean).join('/')); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/shared/utils/notyf.token.ts: -------------------------------------------------------------------------------- 1 | import {InjectionToken} from '@angular/core'; 2 | import {Notyf} from 'notyf'; 3 | 4 | export const NOTYF = new InjectionToken('NotyfToken'); 5 | 6 | export function notyfFactory(): Notyf { 7 | return new Notyf({ 8 | position: {x: 'center', y: 'bottom'}, 9 | duration: 10000, 10 | dismissible: true, 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /src/app/admin/views/events/test/test.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | @Component({ 5 | selector: 'app-test', 6 | standalone: true, 7 | imports: [CommonModule], 8 | templateUrl: './test.component.html', 9 | styleUrls: ['./test.component.css'] 10 | }) 11 | export class TestComponent { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/users/users.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { pageTransition } from 'src/app/shared/utils/animations'; 3 | 4 | @Component({ 5 | selector: 'app-users', 6 | templateUrl: './users.component.html', 7 | styleUrls: ['./users.component.css'], 8 | animations: [pageTransition] 9 | }) 10 | export class UsersComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/button/button.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { AppBtnBlueDirective } from './directives/app-btn-blue.directive'; 4 | 5 | @NgModule({ 6 | declarations: [], 7 | imports: [CommonModule, AppBtnBlueDirective], 8 | exports: [AppBtnBlueDirective], 9 | }) 10 | export class ButtonModule {} 11 | -------------------------------------------------------------------------------- /src/app/admin/layouts/header/header.component.css: -------------------------------------------------------------------------------- 1 | .admin-navbar { 2 | z-index: 10; 3 | } 4 | 5 | .profile-dropdown-list { 6 | @apply absolute top-9 -right-3 mt-2 flex w-60 flex-col gap-3 rounded-xl bg-slate-100 border border-slate-500/30 p-4 shadow-lg transition ease-in-out duration-150 7 | } 8 | 9 | .profile-dropdown-list[aria-expanded=false] { 10 | @apply invisible scale-90 opacity-0 11 | } -------------------------------------------------------------------------------- /src/app/shared/components/modal/modal.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { ModalComponent } from './modal.component'; 4 | 5 | 6 | 7 | @NgModule({ 8 | declarations: [], 9 | imports: [ 10 | CommonModule, 11 | ModalComponent 12 | ], 13 | exports: [ModalComponent] 14 | }) 15 | export class ModalModule { } 16 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/profile/profile.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { pageTransition } from 'src/app/shared/utils/animations'; 3 | 4 | @Component({ 5 | selector: 'app-profile', 6 | templateUrl: './profile.component.html', 7 | styleUrls: ['./profile.component.css'], 8 | animations: [pageTransition] 9 | }) 10 | export class ProfileComponent { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/preloader/preloader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | @Component({ 5 | selector: 'app-preloader', 6 | standalone: true, 7 | imports: [CommonModule], 8 | templateUrl: './preloader.component.html', 9 | styleUrls: ['./preloader.component.css'] 10 | }) 11 | export class PreloaderComponent { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/buttons/buttons.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { ButtonModule } from 'src/app/shared/components/button/button.module'; 3 | 4 | @Component({ 5 | selector: 'app-buttons', 6 | standalone: true, 7 | imports: [ButtonModule], 8 | templateUrl: './buttons.component.html', 9 | styleUrl: './buttons.component.css', 10 | }) 11 | export class ButtonsComponent {} 12 | -------------------------------------------------------------------------------- /src/app/_core/interceptors/interceptors.provider.ts: -------------------------------------------------------------------------------- 1 | import {HTTP_INTERCEPTORS} from '@angular/common/http'; 2 | import {ErrorsInterceptor} from "./errors.interceptor"; 3 | import {RequestsInterceptor} from "./requests.interceptor"; 4 | 5 | export const httpInterceptorProviders = [ 6 | {provide: HTTP_INTERCEPTORS, useClass: RequestsInterceptor, multi: true}, 7 | {provide: HTTP_INTERCEPTORS, useClass: ErrorsInterceptor, multi: true}, 8 | ]; 9 | -------------------------------------------------------------------------------- /src/app/admin/admin.routes.ts: -------------------------------------------------------------------------------- 1 | export enum AdminRoutes { 2 | Dashboard = 'dashboard', 3 | Events = 'events', 4 | Settings = 'settings', 5 | Elements = 'elements', 6 | } 7 | 8 | export enum ElementRoutes { 9 | Alert = 'alert', 10 | Modal = 'modal', 11 | Buttons = 'buttons', 12 | Tabs = 'tabs', 13 | DataTable = 'data-table', 14 | Forms = 'forms', 15 | } 16 | 17 | export enum SettingRoutes { 18 | Profile = 'profile', 19 | Users = 'users', 20 | } 21 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ngwind 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/app/shared/components/button/directives/app-btn-blue.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, OnInit, Renderer2 } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[appBtnBlue]', 5 | standalone: true, 6 | }) 7 | export class AppBtnBlueDirective implements OnInit { 8 | constructor(private elementRef: ElementRef, private renderer: Renderer2) {} 9 | 10 | ngOnInit(): void { 11 | this.renderer.addClass(this.elementRef.nativeElement, 'btn-primary'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/services/localStorage.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | 3 | @Injectable({providedIn: "root"}) 4 | 5 | export class LocalStorageService{ 6 | put(key:string, value: any){ 7 | localStorage.setItem(key, value); 8 | } 9 | 10 | get(key: string):any{ 11 | return localStorage.getItem(key); 12 | } 13 | 14 | remove(key: string){ 15 | localStorage.removeItem(key); 16 | } 17 | 18 | destroy(){ 19 | localStorage.clear(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/admin/views/settings/settings.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { ProfileComponent } from './profile/profile.component'; 4 | import { UsersComponent } from './users/users.component'; 5 | 6 | 7 | 8 | @NgModule({ 9 | declarations: [ 10 | ProfileComponent, 11 | UsersComponent 12 | ], 13 | imports: [ 14 | CommonModule 15 | ], 16 | exports: [ 17 | ProfileComponent 18 | ] 19 | }) 20 | export class SettingsModule { } 21 | -------------------------------------------------------------------------------- /src/app/shared/components/spinner/spinner.component.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { Component, Input } from '@angular/core'; 3 | import { fadeInOut } from '../../utils/animations'; 4 | 5 | @Component({ 6 | selector: 'btn-spinner', 7 | standalone: true, 8 | imports: [CommonModule], 9 | templateUrl: './spinner.component.html', 10 | styleUrls: ['./spinner.component.css'], 11 | animations: [fadeInOut] 12 | }) 13 | export class SpinnerComponent { 14 | @Input() show: boolean = false; 15 | } 16 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ["./src/**/*.{html,ts}"], 4 | theme: { 5 | extend: { 6 | container: { 7 | center: true, 8 | padding: "1.5rem", 9 | screens: { 10 | xl: "1280px", 11 | }, 12 | maxWidth: { 13 | DEFAULT: "max-w-xl", 14 | }, 15 | }, 16 | transitionProperty: { 17 | height: "max-height", 18 | }, 19 | }, 20 | }, 21 | plugins: [], 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "ng serve", 7 | "type": "chrome", 8 | "request": "launch", 9 | "preLaunchTask": "npm: start", 10 | "url": "http://localhost:4200/" 11 | }, 12 | { 13 | "name": "ng test", 14 | "type": "chrome", 15 | "request": "launch", 16 | "preLaunchTask": "npm: test", 17 | "url": "http://localhost:9876/debug.html" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/assets/data/images.ts: -------------------------------------------------------------------------------- 1 | export interface IUsers { 2 | userOne: string; 3 | } 4 | export interface IAuth { 5 | signup: string; 6 | } 7 | export class Images { 8 | public static readonly mainLogo: string = './assets/images/logo/my-logo.png'; 9 | public static readonly bannerLogo: string = './assets/images/logo/login.png'; 10 | 11 | public static readonly auth: IAuth = { 12 | signup: './assets/images/authpage/signup.jpg', 13 | }; 14 | 15 | public static readonly users: IUsers = { 16 | userOne: './assets/images/authpage/profile-image.jpg', 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /docs/assets/data/images.ts: -------------------------------------------------------------------------------- 1 | export interface IUsers { 2 | userOne: string; 3 | } 4 | export interface IAuth { 5 | signup: string; 6 | } 7 | export class Images { 8 | public static readonly mainLogo: string = './assets/images/logo/my-logo.png'; 9 | public static readonly bannerLogo: string = './assets/images/logo/login.png'; 10 | 11 | public static readonly auth: IAuth = { 12 | signup: './assets/images/authpage/signup.jpg', 13 | }; 14 | 15 | public static readonly users: IUsers = { 16 | userOne: './assets/images/authpage/profile-image.jpg', 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /src/app/public/layouts/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { DatetimeHelper } from 'src/app/_core/helpers/datetime.helper'; 3 | import { Images } from 'src/assets/data/images'; 4 | 5 | @Component({ 6 | selector: 'public-footer', 7 | standalone: true, 8 | imports: [], 9 | templateUrl: './footer.component.html', 10 | styleUrl: './footer.component.css', 11 | }) 12 | export class PublicFooterComponent { 13 | public readonly currentYear: number = DatetimeHelper.currentYear; 14 | public mainLogo: string = Images.mainLogo; 15 | } 16 | -------------------------------------------------------------------------------- /src/app/admin/views/events/events.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Router } from "@angular/router"; 3 | import { pageTransition } from 'src/app/shared/utils/animations'; 4 | 5 | @Component({ 6 | selector: 'app-events', 7 | templateUrl: './events.component.html', 8 | styleUrls: ['./events.component.css'], 9 | animations: [pageTransition] 10 | }) 11 | export class EventsComponent { 12 | constructor(private router: Router) { 13 | } 14 | 15 | loadTest() { 16 | this.router.navigate(['admin', 'events', { outlets: { test: ['testing'] } }]); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/public/public-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { HomeComponent } from './home/home.component'; 4 | 5 | const routes: Routes = [ 6 | 7 | { 8 | path: '', 9 | title: 'Home', 10 | component: HomeComponent, 11 | }, 12 | // { 13 | // path: '', 14 | // loadChildren: () => import('./auth/auth.module').then((m) => m.AuthModule), 15 | // }, 16 | ]; 17 | 18 | @NgModule({ 19 | imports: [RouterModule.forChild(routes)], 20 | exports: [RouterModule], 21 | }) 22 | export class PublicRoutingModule {} 23 | -------------------------------------------------------------------------------- /src/app/public/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {HttpClient} from "@angular/common/http"; 3 | import {Signin} from "./signin/signin.model"; 4 | import {Observable} from "rxjs"; 5 | import {AuthResponse} from "./auth.response"; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class AuthService { 11 | private endpoints: any = { 12 | signin: "api/v1/Signin" 13 | }; 14 | 15 | constructor(private httpClient: HttpClient) { } 16 | 17 | signIn(data: Signin): Observable { 18 | return this.httpClient.post(this.endpoints.signin, data); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/_core/strategies/AppTitleStrategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { RouterStateSnapshot, TitleStrategy } from "@angular/router"; 3 | import { Title } from "@angular/platform-browser"; 4 | 5 | @Injectable({ providedIn: 'root' }) 6 | 7 | export class AppTitleStrategy extends TitleStrategy { 8 | constructor(private readonly title: Title) { 9 | super(); 10 | } 11 | 12 | override updateTitle(routerState: RouterStateSnapshot) { 13 | const title = this.buildTitle(routerState); 14 | 15 | if (title !== undefined) { 16 | this.title.setTitle(`Ngwind - ${title}`); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 7 | 9 | 10 | 11 |
12 |
-------------------------------------------------------------------------------- /src/app/public/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import {PublicRoutes} from "../public.routes"; 3 | import {CommonService} from "../../_core/services/common.service"; 4 | import {AppRoutes} from "../../app.routes"; 5 | import {AdminRoutes} from "../../admin/admin.routes"; 6 | 7 | @Component({ 8 | selector: 'app-home', 9 | templateUrl: './home.component.html', 10 | styleUrls: ['./home.component.css'] 11 | }) 12 | export class HomeComponent { 13 | readonly publicRoutes = PublicRoutes; 14 | 15 | constructor(public readonly commonService: CommonService) { 16 | } 17 | 18 | protected readonly AppRoutes = AppRoutes; 19 | protected readonly AdminRoutes = AdminRoutes; 20 | } 21 | -------------------------------------------------------------------------------- /src/app/shared/components/data-table/data-table.component.ts: -------------------------------------------------------------------------------- 1 | import { NgClass, NgIf } from '@angular/common'; 2 | import { Component, Input } from '@angular/core'; 3 | 4 | @Component({ 5 | selector: 'data-table', 6 | standalone: true, 7 | imports: [NgClass, NgIf], 8 | templateUrl: './data-table.component.html', 9 | styleUrl: './data-table.component.css', 10 | }) 11 | export class DataTableComponent { 12 | @Input() columnData: any = []; 13 | @Input() rowData: any = []; 14 | @Input() pageData: number[] = []; 15 | 16 | shorting: boolean = false; 17 | 18 | sortingUp() { 19 | this.shorting = !this.shorting; 20 | } 21 | sortingDown() { 22 | this.shorting = !this.shorting; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/public/auth/auth-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {RouterModule, Routes} from '@angular/router'; 3 | import {PublicRoutes} from "../public.routes"; 4 | import {SignupComponent} from "./signup/signup.component"; 5 | import {SigninComponent} from "./signin/signin.component"; 6 | 7 | const routes: Routes = [ 8 | { 9 | title: "Signin", 10 | path: PublicRoutes.Signup, 11 | component: SignupComponent 12 | }, 13 | { 14 | title: "Signup", 15 | path: PublicRoutes.Signin, 16 | component: SigninComponent 17 | }, 18 | ]; 19 | 20 | @NgModule({ 21 | imports: [RouterModule.forChild(routes)], 22 | exports: [RouterModule] 23 | }) 24 | export class AuthRoutingModule { } 25 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ngwind 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /src/app/shared/components/modal/modal.component.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 3 | 4 | @Component({ 5 | standalone: true, 6 | selector: 'app-modal', 7 | templateUrl: './modal.component.html', 8 | styleUrls: ['./modal.component.css'], 9 | imports: [CommonModule] 10 | }) 11 | export class ModalComponent { 12 | @Input() show: boolean = false; 13 | @Input() title: string = "Modal"; 14 | @Input() size: string = "xl:max-w-7xl"; 15 | @Input() footer: boolean = true; 16 | 17 | @Output() closeModal = new EventEmitter(); 18 | 19 | onModalClose() { 20 | this.show = false; 21 | this.closeModal.emit(this.show); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/alert/admin-alert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { AlertComponent } from 'src/app/shared/components/alert/alert.component'; 4 | import { AlertType } from 'src/app/shared/components/alert/alert.type'; 5 | import { pageTransition } from 'src/app/shared/utils/animations'; 6 | 7 | @Component({ 8 | selector: 'admin-alert', 9 | standalone: true, 10 | imports: [ 11 | CommonModule, 12 | AlertComponent 13 | ], 14 | templateUrl: './admin-alert.component.html', 15 | styleUrls: ['./admin-alert.component.css'], 16 | animations: [pageTransition], 17 | }) 18 | export class AdminAlertComponent { 19 | readonly alertType = AlertType; 20 | } 21 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/data-table/data-table.component.ts: -------------------------------------------------------------------------------- 1 | import { NgClass } from '@angular/common'; 2 | import { Component } from '@angular/core'; 3 | import { DataTableComponent } from 'src/app/shared/components/data-table/data-table.component'; 4 | import { IColumn, IProduct, TableData } from './table.data'; 5 | 6 | @Component({ 7 | selector: 'app-data-table', 8 | standalone: true, 9 | imports: [NgClass, DataTableComponent], 10 | templateUrl: './data-table.component.html', 11 | styleUrl: './data-table.component.css', 12 | }) 13 | export class AdminDataTableComponent { 14 | public products: IProduct[] = TableData.products; 15 | public pages: number[] = TableData.pageNumber; 16 | public columnData:IColumn[] = TableData.columnData 17 | } 18 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.component.css: -------------------------------------------------------------------------------- 1 | .alert { 2 | @apply mt-5 py-2 px-5 rounded text-sm shadow-sm relative transition-all ease-in-out duration-300 overflow-hidden 3 | } 4 | 5 | .alert-success { 6 | @apply border border-l-4 border-l-green-500 border-green-100 bg-green-100 text-green-600 7 | } 8 | 9 | .alert-info { 10 | @apply border border-l-4 border-l-blue-500 border-blue-100 bg-blue-100 text-blue-600 11 | } 12 | 13 | .alert-danger { 14 | @apply border border-l-4 border-l-red-500 border-red-100 bg-red-100 text-red-600 15 | } 16 | 17 | .alert-warning { 18 | @apply border border-l-4 border-l-orange-500 border-orange-100 bg-orange-100 text-orange-600 19 | } 20 | 21 | .alert-dismiss { 22 | @apply absolute top-0 right-0 cursor-pointer p-0.5; 23 | } -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab-link.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, EventEmitter, HostListener, Output } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[ngwTabLink]', 5 | standalone: true, 6 | host: { 7 | class: 'ngw-tab-link' 8 | } 9 | }) 10 | export class NgwTabLinkDirective { 11 | @Output() index: EventEmitter = new EventEmitter(); 12 | 13 | @HostListener('click', ['$event.target']) onClick(elem: Element) { 14 | const current = elem.closest('ul')?.querySelector('[aria-current=true]') as HTMLElement; 15 | current.setAttribute('aria-current', 'false'); 16 | elem.setAttribute('aria-current', 'true'); 17 | this.index.emit(Number(elem.getAttribute('aria-valuenow'))); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/app/admin/layouts/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef, Renderer2 } from '@angular/core'; 2 | import { Images } from 'src/assets/data/images'; 3 | 4 | @Component({ 5 | selector: 'app-header', 6 | templateUrl: './header.component.html', 7 | styleUrls: ['./header.component.css'], 8 | }) 9 | export class HeaderComponent { 10 | public userOne: string = Images.users.userOne; 11 | 12 | isOpen: boolean = false; 13 | 14 | constructor(private element: ElementRef, private renderer: Renderer2) {} 15 | 16 | onClickProfile = () => { 17 | const profileDropdownList = this.element.nativeElement.querySelector( 18 | '.profile-dropdown-list' 19 | ); 20 | this.renderer.setAttribute(profileDropdownList, 'aria-expanded', 'true'); 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/tab/admin-tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { CommonModule } from "@angular/common"; 3 | import { pageTransition } from "../../../../shared/utils/animations"; 4 | import { tabItems } from "./tab-items"; 5 | import { NgwTabComponent } from 'src/app/shared/components/ngw-tab/ngw-tab.component'; 6 | import { NgwTabContents } from 'src/app/shared/components/ngw-tab/ngw-tab-contents.type'; 7 | 8 | @Component({ 9 | selector: 'admin-tab', 10 | standalone: true, 11 | imports: [ 12 | CommonModule, 13 | NgwTabComponent 14 | ], 15 | templateUrl: './admin-tab.component.html', 16 | styleUrl: './admin-tab.component.css', 17 | animations: [pageTransition], 18 | }) 19 | export class AdminTabComponent { 20 | items: NgwTabContents[] = tabItems; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/ngw-tab.component.html: -------------------------------------------------------------------------------- 1 |
2 | @if (items.length > 0) { 3 | 14 |
15 |
16 |

{{title}}

17 |

{{content}}

18 |
19 |
20 | } 21 | @else { 22 | 23 | } 24 |
-------------------------------------------------------------------------------- /src/app/admin/admin.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef, HostListener, Renderer2 } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-admin', 5 | templateUrl: './admin.component.html', 6 | styleUrls: ['./admin.component.css'], 7 | }) 8 | export class AdminComponent { 9 | title = 'event-bud-frontend'; 10 | 11 | constructor(private element: ElementRef, private rendered: Renderer2) { } 12 | 13 | @HostListener('click', ['$event.target']) onClick(e: Element) { 14 | const profileDropdown = this.element.nativeElement.querySelector('.profile-dropdown') as Element; 15 | 16 | if (!profileDropdown.contains(e)) { 17 | const profileDropdownList = this.element.nativeElement.querySelector('.profile-dropdown-list'); 18 | this.rendered.setAttribute(profileDropdownList, 'aria-expanded', 'false') 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/admin/layouts/layouts.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { RouterModule } from '@angular/router'; 4 | import { FooterComponent } from './footer/footer.component'; 5 | import { HeaderComponent } from './header/header.component'; 6 | import { SidebarCollapseDirective } from './sidebar/sidebar-collapse.directive'; 7 | import { SidebarComponent } from './sidebar/sidebar.component'; 8 | 9 | 10 | 11 | @NgModule({ 12 | declarations: [ 13 | SidebarComponent, 14 | FooterComponent, 15 | HeaderComponent 16 | ], 17 | imports: [ 18 | CommonModule, 19 | RouterModule, 20 | SidebarCollapseDirective 21 | ], 22 | exports: [ 23 | HeaderComponent, 24 | SidebarComponent, 25 | FooterComponent, 26 | ] 27 | }) 28 | export class LayoutsModule { } 29 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/ngw-tab.component.css: -------------------------------------------------------------------------------- 1 | .ngw-tab-container { 2 | @apply text-sm font-medium text-gray-500 3 | } 4 | 5 | .ngw-tab-hr { 6 | @apply flex flex-wrap -mb-px text-center 7 | } 8 | 9 | .ngw-tab-item { 10 | @apply me-2 11 | } 12 | 13 | .ngw-tab-link { 14 | @apply inline-block p-4 border-b-2 border-transparent rounded-t-lg hover:text-slate-600 hover:border-slate-300 15 | } 16 | 17 | .ngw-tab-link[aria-current=true] { 18 | @apply border-emerald-600 text-emerald-600 19 | } 20 | 21 | .ngw-tab-link[aria-disabled=true] { 22 | @apply text-gray-400 hover:border-0 rounded-t-lg cursor-not-allowed 23 | } 24 | 25 | .ngw-tab-content { 26 | @apply mt-2 text-gray-900 27 | } 28 | 29 | .ngw-tab-body { 30 | @apply p-6 bg-slate-50 rounded-lg w-full text-sm 31 | } 32 | 33 | .ngw-tab-title { 34 | @apply text-lg font-bold mb-2 35 | } -------------------------------------------------------------------------------- /src/app/shared/utils/animations.ts: -------------------------------------------------------------------------------- 1 | import {animate, style, transition, trigger} from '@angular/animations'; 2 | 3 | export const fadeInOut = trigger('fadeInOut', [ 4 | transition(':enter', [ 5 | style({ opacity: 0 }), 6 | animate('150ms', style({ opacity: 1 })), 7 | ]), 8 | transition(':leave', [ 9 | animate('150ms', style({ opacity: 0 })), 10 | ]), 11 | ]); 12 | 13 | export const pageTransition = trigger('pageTransition', [ 14 | transition(':enter', [ 15 | style({ opacity: 0 }), 16 | animate('100ms', style({ opacity: 1 })), 17 | ]), 18 | transition(':leave', [ 19 | animate('100ms', style({ opacity: 0 })), 20 | ]), 21 | ]); 22 | 23 | export const slideDown = trigger('slideDown', [ 24 | transition(':enter', [ 25 | style({opacity: 0, maxHeight: '0'}), 26 | animate('300ms ease-in', style({opacity: 1, maxHeight: '1000px'})), 27 | ]), 28 | ]); 29 | -------------------------------------------------------------------------------- /src/app/public/layouts/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RouterLink } from '@angular/router'; 3 | import { CommonService } from 'src/app/_core/services/common.service'; 4 | import { AdminRoutes } from 'src/app/admin/admin.routes'; 5 | import { AppRoutes } from 'src/app/app.routes'; 6 | import { Images } from 'src/assets/data/images'; 7 | import { PublicRoutes } from '../../public.routes'; 8 | 9 | @Component({ 10 | selector: 'public-header', 11 | standalone: true, 12 | imports: [RouterLink], 13 | templateUrl: './header.component.html', 14 | styleUrl: './header.component.css', 15 | }) 16 | export class PublicHeaderComponent { 17 | public mainLogo: string = Images.mainLogo; 18 | readonly publicRoutes = PublicRoutes; 19 | readonly appRoutes = AppRoutes; 20 | readonly adminRoutes = AdminRoutes; 21 | constructor(public readonly commonService: CommonService) {} 22 | } 23 | -------------------------------------------------------------------------------- /src/app/public/public.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | import { RouterOutlet } from '@angular/router'; 4 | import { AuthModule } from './auth/auth.module'; 5 | import { HomeComponent } from './home/home.component'; 6 | import { PublicFooterComponent } from './layouts/footer/footer.component'; 7 | import { PublicHeaderComponent } from './layouts/header/header.component'; 8 | import { PageNotFoundComponent } from './page-not-found/page-not-found.component'; 9 | import { PublicRoutingModule } from './public-routing.module'; 10 | import { PublicComponent } from './public.component'; 11 | 12 | @NgModule({ 13 | declarations: [PublicComponent, PageNotFoundComponent, HomeComponent], 14 | imports: [ 15 | CommonModule, 16 | PublicRoutingModule, 17 | AuthModule, 18 | PublicHeaderComponent, 19 | PublicFooterComponent, 20 | RouterOutlet, 21 | ], 22 | }) 23 | export class PublicModule {} 24 | -------------------------------------------------------------------------------- /src/app/shared/components/modal/modal.component.css: -------------------------------------------------------------------------------- 1 | .modal { 2 | @apply relative z-10 3 | } 4 | 5 | .modal[aria-modal=false]{ 6 | @apply invisible ease-in duration-500 opacity-0 7 | } 8 | 9 | .modal[aria-modal=true] { 10 | @apply visible ease-out duration-300 opacity-100 11 | } 12 | 13 | .modal-backdrop { 14 | @apply fixed inset-0 bg-slate-900 bg-opacity-75 transition-opacity 15 | } 16 | 17 | .modal-wrapper { 18 | @apply fixed inset-0 z-10 w-screen overflow-y-auto 19 | } 20 | 21 | .modal-container { 22 | @apply flex min-h-full items-center justify-center p-4 text-center 23 | } 24 | 25 | .modal-box { 26 | @apply relative transform overflow-hidden rounded-xl bg-white text-left shadow-xl transition-all sm:my-8 27 | } 28 | 29 | .modal[aria-modal=true] .modal-box{ 30 | @apply ease-out duration-300 opacity-100 translate-y-0 sm:scale-100 31 | } 32 | 33 | .modal[aria-modal=false] .modal-box{ 34 | @apply ease-in duration-200 opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95 35 | } 36 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "ES2022", 21 | "useDefineForClassFields": false, 22 | "lib": [ 23 | "ES2022", 24 | "dom" 25 | ] 26 | }, 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/modal/admin-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { Component } from '@angular/core'; 3 | import { ModalComponent } from 'src/app/shared/components/modal/modal.component'; 4 | import { ModalModule } from 'src/app/shared/components/modal/modal.module'; 5 | import { pageTransition } from 'src/app/shared/utils/animations'; 6 | 7 | @Component({ 8 | selector: 'admin-modal', 9 | standalone: true, 10 | imports: [ 11 | CommonModule, 12 | ModalModule 13 | ], 14 | templateUrl: './admin-modal.component.html', 15 | styleUrl: './admin-modal.component.css', 16 | animations: [pageTransition] 17 | }) 18 | export class AdminModalComponent { 19 | showModal: boolean = false; 20 | 21 | modalCompnent: ModalComponent 22 | 23 | constructor() { 24 | this.modalCompnent = new ModalComponent(); 25 | } 26 | 27 | openModal() { 28 | this.showModal = !this.showModal; 29 | } 30 | 31 | onModalCloseHandler(event: boolean) { 32 | this.showModal = event; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/app/public/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | 4 | import {AuthRoutingModule} from './auth-routing.module'; 5 | import {SigninComponent} from "./signin/signin.component"; 6 | import {SignupComponent} from "./signup/signup.component"; 7 | import {ReactiveFormsModule} from "@angular/forms"; 8 | import {SpinnerComponent} from "../../shared/components/spinner/spinner.component"; 9 | import {ValidationErrorComponent} from "../../shared/components/validation-error/validation-error.component"; 10 | import {AlertComponent} from "../../shared/components/alert/alert.component"; 11 | 12 | 13 | @NgModule({ 14 | declarations: [ 15 | SigninComponent, 16 | SignupComponent 17 | ], 18 | imports: [ 19 | CommonModule, 20 | AuthRoutingModule, 21 | ReactiveFormsModule, 22 | SpinnerComponent, 23 | ValidationErrorComponent, 24 | AlertComponent, 25 | ], 26 | exports: [ 27 | SigninComponent, 28 | SignupComponent, 29 | ] 30 | }) 31 | export class AuthModule { } 32 | -------------------------------------------------------------------------------- /src/app/admin/admin.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { NgModule } from '@angular/core'; 3 | 4 | import { AdminRoutingModule } from './admin-routing.module'; 5 | import { LayoutsModule } from './layouts/layouts.module'; 6 | 7 | import { AdminComponent } from './admin.component'; 8 | import { AdminPageNotFoundComponent } from './views/admin-page-not-found/admin-page-not-found.component'; 9 | import { DashboardComponent } from './views/dashboard/dashboard.component'; 10 | import { EventsComponent } from './views/events/events.component'; 11 | import { SettingsModule } from './views/settings/settings.module'; 12 | import { ElementsModule } from './views/elements/elements.module'; 13 | 14 | 15 | @NgModule({ 16 | declarations: [ 17 | AdminComponent, 18 | DashboardComponent, 19 | AdminPageNotFoundComponent, 20 | EventsComponent, 21 | ], 22 | imports: [ 23 | CommonModule, 24 | AdminRoutingModule, 25 | LayoutsModule, 26 | SettingsModule, 27 | ElementsModule 28 | ] 29 | }) 30 | export class AdminModule { } 31 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/directives/ngw-tab.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { NgwTabDirective } from './ngw-tab.directive'; 4 | import { NgwTabItemDirective } from './ngw-tab-item.directive'; 5 | import { NgwTabLinkDirective } from './ngw-tab-link.directive'; 6 | import { NgwTabContentDirective } from './ngw-tab-content.directive'; 7 | import { NgwTabTitleDirective } from './ngw-tab-title.directive'; 8 | import { NgwTabBodyDirective } from './ngw-tab-body.directive'; 9 | 10 | 11 | 12 | @NgModule({ 13 | declarations: [], 14 | imports: [ 15 | CommonModule, 16 | NgwTabDirective, 17 | NgwTabItemDirective, 18 | NgwTabLinkDirective, 19 | NgwTabContentDirective, 20 | NgwTabTitleDirective, 21 | NgwTabBodyDirective 22 | ], 23 | exports: [ 24 | NgwTabDirective, 25 | NgwTabItemDirective, 26 | NgwTabLinkDirective, 27 | NgwTabContentDirective, 28 | NgwTabTitleDirective, 29 | NgwTabBodyDirective 30 | ] 31 | }) 32 | export class NgwTabModule { } 33 | -------------------------------------------------------------------------------- /src/app/admin/layouts/sidebar/sidebar-collapse.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ElementRef, HostListener } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[sidebarCollapse]', 5 | standalone: true, 6 | }) 7 | export class SidebarCollapseDirective { 8 | constructor(private elementRef: ElementRef) { } 9 | 10 | @HostListener('click') onClick() { 11 | const elem = this.elementRef.nativeElement as HTMLElement; 12 | const sidebar = elem.closest('.sidebar'); 13 | const sidebarIsCollapsed = sidebar?.getAttribute('aria-expanded'); 14 | 15 | if (sidebarIsCollapsed === 'false') { 16 | elem.closest('.sidebar')?.setAttribute('aria-expanded', 'true'); 17 | } 18 | else { 19 | sidebar?.setAttribute('aria-expanded', 'false'); 20 | } 21 | 22 | const subMenu = sidebar?.querySelectorAll('.sub-menu'); 23 | 24 | subMenu?.forEach((subMenu: Element) => { 25 | if (subMenu.getAttribute('aria-expanded') == 'true') 26 | subMenu.setAttribute('aria-expanded', 'false'); 27 | 28 | subMenu.toggleAttribute('icon-hidden'); 29 | }); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/app/_core/interceptors/requests.interceptor.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from "@angular/core"; 2 | import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http"; 3 | import {Observable} from "rxjs"; 4 | import {environment} from "src/environments/environment"; 5 | import {LocalStorageService} from "../../shared/services/localStorage.service"; 6 | 7 | @Injectable() 8 | 9 | export class RequestsInterceptor implements HttpInterceptor { 10 | constructor(private localStorageService: LocalStorageService) { 11 | } 12 | intercept(request: HttpRequest, next: HttpHandler): Observable> { 13 | const requestUrl: string = environment.apiUrl + request.url; 14 | const accessToken: string = this.localStorageService.get("token"); 15 | 16 | if(accessToken) { 17 | request = request.clone({ 18 | headers: request.headers.set('Authorization', 'Bearer ' + accessToken) 19 | }); 20 | } 21 | 22 | request = request.clone({ url: requestUrl }); 23 | 24 | return next.handle(request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 3 | "version": "2.0.0", 4 | "tasks": [ 5 | { 6 | "type": "npm", 7 | "script": "start", 8 | "isBackground": true, 9 | "problemMatcher": { 10 | "owner": "typescript", 11 | "pattern": "$tsc", 12 | "background": { 13 | "activeOnStart": true, 14 | "beginsPattern": { 15 | "regexp": "(.*?)" 16 | }, 17 | "endsPattern": { 18 | "regexp": "bundle generation complete" 19 | } 20 | } 21 | } 22 | }, 23 | { 24 | "type": "npm", 25 | "script": "test", 26 | "isBackground": true, 27 | "problemMatcher": { 28 | "owner": "typescript", 29 | "pattern": "$tsc", 30 | "background": { 31 | "activeOnStart": true, 32 | "beginsPattern": { 33 | "regexp": "(.*?)" 34 | }, 35 | "endsPattern": { 36 | "regexp": "bundle generation complete" 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 MD. Akter Nashid Rajin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {BrowserModule} from '@angular/platform-browser'; 3 | import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 4 | import {HttpClientModule} from '@angular/common/http'; 5 | import {AdminModule} from './admin/admin.module'; 6 | import {AppRoutingModule} from './app-routing.module'; 7 | 8 | import {AppComponent} from './app.component'; 9 | import {PublicModule} from './public/public.module'; 10 | 11 | import {httpInterceptorProviders} from './_core/interceptors/interceptors.provider'; 12 | import {StrategyProviders} from "./_core/strategies/strategy.providers"; 13 | import {UtilsProviders} from "./shared/utils/utils.providers"; 14 | 15 | @NgModule({ 16 | declarations: [ 17 | AppComponent, 18 | ], 19 | imports: [ 20 | BrowserModule, 21 | AppRoutingModule, 22 | AdminModule, 23 | PublicModule, 24 | BrowserAnimationsModule, 25 | HttpClientModule 26 | ], 27 | providers: [ 28 | httpInterceptorProviders, 29 | StrategyProviders, 30 | UtilsProviders 31 | ], 32 | bootstrap: [AppComponent] 33 | }) 34 | export class AppModule { } 35 | -------------------------------------------------------------------------------- /src/app/shared/components/ngw-tab/ngw-tab.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ViewEncapsulation } from '@angular/core'; 2 | import { NgwTabContents } from './ngw-tab-contents.type'; 3 | import { NgFor, NgIf } from '@angular/common'; 4 | import { NgwTabModule } from './directives/ngw-tab.module'; 5 | 6 | @Component({ 7 | selector: 'ngw-tab', 8 | standalone: true, 9 | imports: [ 10 | NgIf, 11 | NgFor, 12 | NgwTabModule 13 | ], 14 | templateUrl: './ngw-tab.component.html', 15 | styleUrl: './ngw-tab.component.css', 16 | encapsulation: ViewEncapsulation.None, 17 | }) 18 | export class NgwTabComponent { 19 | @Input() items: NgwTabContents[] = []; 20 | protected title: string = ""; 21 | protected content: string = ""; 22 | 23 | 24 | constructor() { } 25 | 26 | ngOnInit(): void { 27 | if (this.items.length > 0) { 28 | this.title = this.items[0].TabTitle ?? ""; 29 | this.content = this.items[0].Contents ?? ""; 30 | } 31 | } 32 | 33 | handleIndex(index: number) { 34 | if (this.items.length > 0) { 35 | this.title = this.items[index].TabTitle ?? ""; 36 | this.content = this.items[index].Contents ?? ""; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/shared/components/modal/modal.component.html: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import {NgModule} from '@angular/core'; 2 | import {PreloadAllModules, RouterModule, Routes} from '@angular/router'; 3 | import {AdminComponent} from './admin/admin.component'; 4 | import {AppComponent} from './app.component'; 5 | import {AppRoutes} from './app.routes'; 6 | import {PageNotFoundComponent} from './public/page-not-found/page-not-found.component'; 7 | import { PublicComponent } from './public/public.component'; 8 | 9 | const routes: Routes = [ 10 | { 11 | path: '', 12 | component: PublicComponent, 13 | loadChildren: () => import('./public/public.module').then((m) => m.PublicModule) 14 | }, 15 | { 16 | path: AppRoutes.Admin, 17 | component: AdminComponent, 18 | loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule), 19 | }, 20 | { 21 | path: '**', 22 | component: PageNotFoundComponent 23 | } 24 | ]; 25 | 26 | @NgModule({ 27 | imports: [RouterModule.forRoot(routes, { 28 | // enableTracing: true, //uncomment for debugging only 29 | preloadingStrategy: PreloadAllModules, 30 | scrollPositionRestoration: 'top', 31 | })], 32 | exports: [RouterModule] 33 | }) 34 | export class AppRoutingModule { } 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngwind", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^17.0.7", 14 | "@angular/common": "^17.0.7", 15 | "@angular/compiler": "^17.0.7", 16 | "@angular/core": "^17.0.7", 17 | "@angular/forms": "^17.0.7", 18 | "@angular/platform-browser": "^17.0.7", 19 | "@angular/platform-browser-dynamic": "^17.0.7", 20 | "@angular/router": "^17.0.7", 21 | "chart.js": "^4.4.0", 22 | "notyf": "^3.10.0", 23 | "rxjs": "~7.8.0", 24 | "tslib": "^2.3.0", 25 | "zone.js": "~0.14.2" 26 | }, 27 | "devDependencies": { 28 | "@angular-devkit/build-angular": "^17.0.7", 29 | "@angular/cli": "~17.0.7", 30 | "@angular/compiler-cli": "^17.0.7", 31 | "@types/jasmine": "~4.3.0", 32 | "autoprefixer": "^10.4.15", 33 | "jasmine-core": "~4.6.0", 34 | "karma": "~6.4.0", 35 | "karma-chrome-launcher": "~3.2.0", 36 | "karma-coverage": "~2.2.0", 37 | "karma-jasmine": "~5.1.0", 38 | "karma-jasmine-html-reporter": "~2.1.0", 39 | "postcss": "^8.4.30", 40 | "tailwindcss": "^3.3.3", 41 | "typescript": "~5.2.2" 42 | } 43 | } -------------------------------------------------------------------------------- /src/app/public/auth/signup/signup.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { DatetimeHelper } from 'src/app/_core/helpers/datetime.helper'; 3 | import { CommonService } from 'src/app/_core/services/common.service'; 4 | import { pageTransition } from 'src/app/shared/utils/animations'; 5 | import { PublicRoutes } from '../../public.routes'; 6 | import { Router } from '@angular/router'; 7 | import { AppRoutes } from 'src/app/app.routes'; 8 | import { AdminRoutes } from 'src/app/admin/admin.routes'; 9 | import { Images } from 'src/assets/data/images'; 10 | 11 | @Component({ 12 | selector: 'app-signup', 13 | templateUrl: './signup.component.html', 14 | styleUrls: ['./signup.component.css'], 15 | animations: [pageTransition] 16 | }) 17 | export class SignupComponent { 18 | readonly signupbannerImage:string = Images.auth.signup 19 | isLoading: boolean = false; 20 | readonly currentYear: number = DatetimeHelper.currentYear; 21 | readonly publicRoutes = PublicRoutes; 22 | 23 | constructor( 24 | public commonService: CommonService, 25 | private router: Router 26 | ) { } 27 | 28 | onFormSubmitHandler = (event: SubmitEvent) => { 29 | event.preventDefault(); 30 | 31 | this.isLoading = true; 32 | 33 | setTimeout(() => { 34 | this.isLoading = false; 35 | this.router.navigate([AppRoutes.Admin, AdminRoutes.Dashboard]); 36 | }, 3000); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/app/public/layouts/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/shared/components/spinner/spinner.component.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 7 | 9 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | 20 | -------------------------------------------------------------------------------- /src/app/admin/views/dashboard/dashboard.component.ts: -------------------------------------------------------------------------------- 1 | import { formatDate } from '@angular/common'; 2 | import { Component, OnInit } from '@angular/core'; 3 | import { Chart, registerables } from 'chart.js'; 4 | import { pageTransition } from 'src/app/shared/utils/animations'; 5 | Chart.register(...registerables); 6 | 7 | @Component({ 8 | selector: 'app-dashboard', 9 | templateUrl: './dashboard.component.html', 10 | styleUrls: ['./dashboard.component.css'], 11 | animations: [pageTransition] 12 | }) 13 | export class DashboardComponent implements OnInit { 14 | eventDate: any = formatDate(new Date(), 'MMM dd, yyyy', 'en'); 15 | 16 | ngOnInit(): void { 17 | var myChart = new Chart("areaWiseSale", { 18 | type: 'doughnut', 19 | data: { 20 | labels: ['Red', 'Blue', 'Yellow', 'Green'], 21 | datasets: [{ 22 | label: '# of Votes', 23 | data: [12, 19, 3, 5], 24 | backgroundColor: [ 25 | 'rgba(255, 99, 132, 0.2)', 26 | 'rgba(54, 162, 235, 0.2)', 27 | 'rgba(255, 206, 86, 0.2)', 28 | 'rgba(75, 192, 192, 0.2)', 29 | ], 30 | }] 31 | }, 32 | options: { 33 | scales: { 34 | x: { 35 | display: false 36 | }, 37 | y: { 38 | display: false 39 | }, 40 | }, 41 | plugins: { 42 | legend: { 43 | position: 'right', 44 | align: 'center', 45 | }, 46 | }, 47 | }, 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/shared/components/alert/alert.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { slideDown } from "../../utils/animations"; 4 | import { AlertType } from "./alert.type"; 5 | 6 | @Component({ 7 | selector: 'app-alert', 8 | standalone: true, 9 | imports: [CommonModule], 10 | templateUrl: './alert.component.html', 11 | styleUrls: ['./alert.component.css'], 12 | animations: [slideDown] 13 | }) 14 | export class AlertComponent { 15 | @Input() messages: string[] = []; 16 | @Input() type: AlertType = AlertType.Success; 17 | @Input() dismissible: boolean = false; 18 | @Input() show: boolean = false; 19 | 20 | @Output() hideAlert = new EventEmitter(); 21 | 22 | @ViewChild("alertElement", { static: false }) alertElement!: ElementRef; 23 | 24 | constructor(private elementRef: ElementRef) { 25 | } 26 | 27 | protected alertTypeClass(): string { 28 | let elemClass: string; 29 | 30 | switch (this.type) { 31 | case AlertType.Success: 32 | elemClass = "alert-success"; 33 | break; 34 | case AlertType.Danger: 35 | elemClass = "alert-danger"; 36 | break; 37 | case AlertType.Info: 38 | elemClass = "alert-info"; 39 | break; 40 | default: 41 | elemClass = "alert-warning"; 42 | } 43 | 44 | return elemClass; 45 | } 46 | 47 | protected dismissHandler(): void { 48 | this.show = false; 49 | this.hideAlert.emit(this.show); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/modal/admin-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 |
7 |
9 | 14 |
15 |
16 | 19 |
20 |

Are you sure you want to deactivate your account? All 21 | of your data will be permanently removed. This action cannot be undone.

22 |
23 |
24 |
25 |
26 |
-------------------------------------------------------------------------------- /src/app/shared/components/validation-error/validation-error.component.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, OnInit} from '@angular/core'; 2 | import {CommonModule} from "@angular/common"; 3 | import {FormControl} from "@angular/forms"; 4 | import {ERROR_MESSAGES} from "./error-messages"; 5 | 6 | @Component({ 7 | selector: 'validation-error', 8 | templateUrl: './validation-error.component.html', 9 | styleUrls: ['./validation-error.component.css'], 10 | standalone: true, 11 | imports: [CommonModule], 12 | }) 13 | export class ValidationErrorComponent implements OnInit { 14 | 15 | @Input() fieldControl!: FormControl | undefined; 16 | 17 | protected errorMessages: string[] = []; 18 | 19 | constructor() { 20 | } 21 | 22 | ngOnInit(): void { 23 | } 24 | 25 | hasError(): boolean { 26 | this.errorMessages = []; 27 | 28 | //check for server error 29 | if ( 30 | this.fieldControl !== null 31 | && this.fieldControl !== undefined 32 | && this.fieldControl.getError('messages') !== undefined) { 33 | this.errorMessages = this.fieldControl.getError('messages'); 34 | return true; 35 | } 36 | 37 | //check for client error 38 | if ( 39 | this.fieldControl !== null 40 | && this.fieldControl !== undefined 41 | && this.fieldControl.errors !== null) { 42 | Object.keys(this.fieldControl.errors!).map((err: any) => { 43 | // @ts-ignore 44 | this.errorMessages.push(ERROR_MESSAGES[err]()); 45 | }); 46 | 47 | return this.fieldControl.touched && this.fieldControl.errors !== null; 48 | } 49 | 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/tab/tab-items.ts: -------------------------------------------------------------------------------- 1 | import { NgwTabContents } from "src/app/shared/components/ngw-tab/ngw-tab-contents.type"; 2 | 3 | export const tabItems: NgwTabContents[] = [ 4 | { 5 | Title: "Profile", 6 | IsActive: true, 7 | TabTitle: "Profile Tab", 8 | Contents: `The crimson-tinted sunset bled through the dusty window of the antique shop, casting long shadows across the 9 | cluttered aisles. Amelia, her fingers trailing along a row of tarnished silver, shivered despite the stifling summer heat. 10 | An unseen melody, played on a ghostly organ, echoed through the labyrinthine shelves, sending goosebumps scampering across 11 | her skin.` 12 | }, 13 | { 14 | Title: "Settings", 15 | TabTitle: "Settings Tab", 16 | Contents: `Neon jellyfish pulsed beneath the cyber-lotus pond, their bioluminescent tendrils swaying to the hum of forgotten 17 | tech. Glitch-winged butterflies pirouetted through holographic trees, their pixels shimmering in the twilight haze. An 18 | ancient AI, buried deep within the city's circuits, whispered secrets of lost data streams and whispered revolutions. What 19 | dreams might bloom in this concrete jungle, under the gaze of a fractured moon?` 20 | }, 21 | { 22 | Title: "Contacts", 23 | TabTitle: "Contacts Tab", 24 | Contents: `It is a long established fact that a reader will be distracted by the readable content of a page when 25 | looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, 26 | as opposed to using 'Content here, content here', making it look like readable English.` 27 | }, 28 | ]; 29 | -------------------------------------------------------------------------------- /src/app/public/auth/signin/signin.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { FormBuilder } from '@angular/forms'; 3 | import { Router } from '@angular/router'; 4 | import { DatetimeHelper } from 'src/app/_core/helpers/datetime.helper'; 5 | import { CommonService } from 'src/app/_core/services/common.service'; 6 | import { AdminRoutes } from 'src/app/admin/admin.routes'; 7 | import { AppRoutes } from 'src/app/app.routes'; 8 | import { pageTransition } from 'src/app/shared/utils/animations'; 9 | import { Images } from 'src/assets/data/images'; 10 | import { AlertType } from '../../../shared/components/alert/alert.type'; 11 | import { PublicRoutes } from '../../public.routes'; 12 | 13 | @Component({ 14 | selector: 'app-signin', 15 | templateUrl: './signin.component.html', 16 | styleUrls: ['./signin.component.css'], 17 | animations: [pageTransition], 18 | }) 19 | export class SigninComponent { 20 | readonly signinBannerImage: string = Images.bannerLogo; 21 | 22 | isLoading: boolean = false; 23 | readonly publicRoutes = PublicRoutes; 24 | readonly currentYear: number = DatetimeHelper.currentYear; 25 | 26 | serverErrors: string[] = []; 27 | 28 | signInForm = this.formBuilder.group({ 29 | username: [''], 30 | password: [''], 31 | }); 32 | 33 | constructor( 34 | public commonService: CommonService, 35 | private formBuilder: FormBuilder, 36 | private router: Router 37 | ) {} 38 | protected readonly AlertType = AlertType; 39 | 40 | protected onFormSubmitHandler = (event: SubmitEvent) => { 41 | event.preventDefault(); 42 | this.isLoading = true; 43 | 44 | setTimeout(() => { 45 | this.isLoading = false; 46 | this.router.navigate([AppRoutes.Admin, AdminRoutes.Dashboard]); 47 | }, 3000); 48 | }; 49 | 50 | protected onAlertCloseHandler = (e: any) => { 51 | this.serverErrors = []; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /src/app/shared/components/data-table/data-table.component.css: -------------------------------------------------------------------------------- 1 | /* sticky table */ 2 | .data-table { 3 | & .table-container { 4 | height: 350px; 5 | max-height: 412px; 6 | overflow: auto; 7 | } 8 | th { 9 | @apply bg-slate-50; 10 | } 11 | 12 | & th[scope="col"] { 13 | position: sticky; 14 | top: 0; 15 | } 16 | } 17 | 18 | .table-container::-webkit-scrollbar { 19 | width: 3px; 20 | height: 5px; 21 | } 22 | 23 | .table-container::-webkit-scrollbar-track { 24 | @apply bg-slate-200; 25 | } 26 | 27 | .table-container::-webkit-scrollbar-thumb { 28 | @apply bg-slate-500 rounded-sm; 29 | } 30 | 31 | .table-container::-webkit-scrollbar-thumb:hover { 32 | @apply bg-slate-200; 33 | } 34 | 35 | .table-container { 36 | scrollbar-width: thin; 37 | scrollbar-color: bg-slate-500; 38 | } 39 | 40 | /* table */ 41 | 42 | .ng-wind-table { 43 | @apply w-full text-xs text-left text-gray-500; 44 | } 45 | .ng-wind-table-header { 46 | @apply text-xs text-gray-700 uppercase bg-gray-50 z-50; 47 | } 48 | .ng-wind-header-item { 49 | @apply px-4 py-3; 50 | } 51 | .ng-wind-data-item { 52 | @apply px-4 py-3; 53 | } 54 | 55 | /* pagination */ 56 | 57 | .ng-wind-table-pagination { 58 | @apply flex items-center flex-wrap md:flex-row justify-between pt-4 text-xs; 59 | } 60 | .ng-wind-table-page-view { 61 | @apply flex items-center font-normal text-gray-500 mb-4 md:mb-0 w-full md:w-auto; 62 | } 63 | 64 | .ng-wind-page-btn { 65 | @apply flex items-center justify-center px-2 h-7 ms-0 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100; 66 | } 67 | 68 | .page-number { 69 | @apply flex items-center justify-center px-3 h-7 leading-tight text-gray-500 border border-gray-300; 70 | } 71 | .active-page { 72 | @apply bg-blue-100 hover:bg-blue-100 hover:text-blue-700; 73 | } 74 | .ng-wind-page-prev { 75 | @apply rounded-s-md ng-wind-page-btn; 76 | } 77 | .ng-wind-page-next { 78 | @apply rounded-e-md ng-wind-page-btn; 79 | } 80 | .page-number-show-dropdown:focus { 81 | border: 0 !important; 82 | } 83 | -------------------------------------------------------------------------------- /src/app/_core/interceptors/errors.interceptor.ts: -------------------------------------------------------------------------------- 1 | import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from "@angular/common/http"; 2 | import {Inject, Injectable} from "@angular/core"; 3 | import {catchError, Observable, retry, throwError, timer} from "rxjs"; 4 | import {NOTYF} from "../../shared/utils/notyf.token"; 5 | import {Notyf} from "notyf"; 6 | import {IError} from "../../shared/interfaces/error.interface"; 7 | 8 | @Injectable() 9 | export class ErrorsInterceptor implements HttpInterceptor { 10 | constructor(@Inject(NOTYF) private notyf: Notyf) { 11 | } 12 | 13 | intercept(request: HttpRequest, next: HttpHandler): Observable> { 14 | this.notyf.dismissAll(); 15 | 16 | return next.handle(request).pipe( 17 | retry({ 18 | count: 3, delay: (errors: HttpErrorResponse, retryCount) => 19 | this.shouldRetry(errors, retryCount) 20 | }), 21 | catchError((errors: HttpErrorResponse) => { 22 | let errorMessage = "The server is not ready to process your request."; 23 | 24 | if (errors.status != 0) 25 | errorMessage = errors.error.title; 26 | 27 | if (errors.status >= 400 && errors.status <= 415) 28 | return throwError(() => this.handleFormErrors(errors.error)); 29 | 30 | this.notyf.error({ 31 | message: errorMessage, 32 | duration: 0 33 | }); 34 | 35 | return throwError(() => new Error(errorMessage)); 36 | }) 37 | ); 38 | } 39 | 40 | private shouldRetry(errors: HttpErrorResponse, retryCount: number) { 41 | if (errors.status == 400) 42 | return throwError(() => errors); 43 | 44 | return timer(retryCount * 1000); 45 | } 46 | 47 | private handleFormErrors(errors: IError[]) { 48 | let errorMessages: any = {}; 49 | 50 | errors.forEach((err: IError) => { 51 | const {title, message} = err; 52 | 53 | if (errorMessages[title.toLowerCase()]) 54 | errorMessages[title.toLowerCase()].push(message); 55 | else 56 | errorMessages[title.toLowerCase()] = [message]; 57 | }); 58 | 59 | return errorMessages; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ng-Wind (Angular Powered Tailwind CSS Minimal Admin Template) 2 | 3 | ![alt text](./docs/image.png) 4 | 5 | ngWind is a free to use minimal dashboard template designed and developed with Angular and Tailwind CSS. This template is highly customizable and easy to use. Currently the template has few features, enough to kick start your project. 6 | 7 | ## ✨ Frameworks 8 | 9 | - Angular 17 10 | - Tailwind CSS 11 | 12 | ## 🚀 Quick Start 13 | 14 | Make sure you have `node js` and `angular cli` installed your machine. Next follow these steps - 15 | 16 | 1. Clone this repository. 17 | 18 | 2. Execute the following command and install required dependencies. 19 | ``` 20 | npm install 21 | ``` 22 | 23 | 3. After Installing the dependencies, execute the following command 24 | ``` 25 | ng serve --open 26 | 27 | or 28 | 29 | ng s -o 30 | ``` 31 | 32 | After successfull build, the application will 🚀 launch into your browser in `http:\\localhost:4200` port. 33 | 34 | 35 | ## 📄 How to discuss 36 | 37 | If you find any issue, bug or any improvement start by making sure that it hasn't been already reported. You can search through the [issues](https://github.com/ANrajin/ngWind/issues) list. 38 | 39 | If not then [create a new issue](https://github.com/ANrajin/ngWind/issues/new) and provide some description that explain what changes or improvement is needed. 40 | 41 | 42 | ## 💻 How to contribute 43 | 44 | Contributors are highly welcome. Please read the contribution guide before starting. 45 | 46 | - Firstly, it's important to have some knowledge about the latest stable version of Angular, Angular CLI and Tailwind CSS, as we prefer to utilize the newest features provided by the framework as soon as they become available. 47 | 48 | - Please look at the [folder structure]() and understand it properly. We prefer a meaningful and easy to use a architecture so that any one who is a beginner also can understand the project easy and customize it based on their needs. 49 | 50 | - Fork the repository into you `github` account and clone it locally and install dependencies and run. 51 | 52 | - Contribute your changes and commit them. Please make sure to use proper commit message in your work and avoid to create a large `Pull Request` so that the reviewer can review your contribution easy. 53 | 54 | - We prefer to follow `#Issue number - Pull Request Title` For example: `#2 - This is a sample pull request` this format for PR title. Open the `Pull Request` into the repositoris `develop` branch. 55 | 56 | ## ✅ Licence 57 | 58 | ngWind is licensed under the MIT license, making it free to use for personal or portfolio projects 😊. Please note that the maintainers are not responsible for providing any `professional support or updates`. 59 | -------------------------------------------------------------------------------- /src/app/public/home/home.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 10 |
11 | 19 |
20 |

Data to enrich your online business 21 |

22 |

Anim aute id magna aliqua ad ad non deserunt sunt. Qui irure 23 | qui lorem cupidatat commodo. Elit sunt amet fugiat veniam occaecat fugiat aliqua.

24 |
25 | Dashboard 27 | Learn more 29 |
30 |
31 |
32 | 40 |
41 |
-------------------------------------------------------------------------------- /src/app/admin/layouts/sidebar/sidebar.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | AfterViewInit, 3 | Component, 4 | ElementRef, 5 | EventEmitter, 6 | OnDestroy, 7 | OnInit, 8 | Output, 9 | ViewEncapsulation 10 | } from '@angular/core'; 11 | import { NavigationEnd, Router } from '@angular/router'; 12 | import { Subscription } from 'rxjs'; 13 | import { CommonService } from 'src/app/_core/services/common.service'; 14 | import { AppRoutes } from 'src/app/app.routes'; 15 | import { AdminRoutes, ElementRoutes, SettingRoutes } from '../../admin.routes'; 16 | 17 | @Component({ 18 | selector: 'app-sidebar', 19 | templateUrl: './sidebar.component.html', 20 | styleUrls: ['./sidebar.component.css'], 21 | encapsulation: ViewEncapsulation.None 22 | }) 23 | 24 | export class SidebarComponent implements OnInit, AfterViewInit, OnDestroy { 25 | sidebarIsCollapsed: boolean = true; 26 | readonly appRoutes = AppRoutes; 27 | readonly adminRoutes = AdminRoutes; 28 | readonly settingRoutes = SettingRoutes; 29 | readonly elementRoutes = ElementRoutes; 30 | private routerSubscription: Subscription = new Subscription(); 31 | 32 | @Output() sidebarCollapsed = new EventEmitter(); 33 | 34 | constructor( 35 | public readonly commonServices: CommonService, 36 | private readonly elementRef: ElementRef, 37 | private router: Router) { } 38 | 39 | ngOnInit(): void { 40 | } 41 | 42 | ngAfterViewInit(): void { 43 | this.subMenuToggleHandlerOnRouteChange(); 44 | setTimeout(() => { this.subMenuToggleHandlerOnPageReload() }, 1); 45 | } 46 | 47 | ngOnDestroy(): void { 48 | this.routerSubscription.unsubscribe(); 49 | } 50 | 51 | subMenuToggleHandler = (event: MouseEvent): void => { 52 | const elem = event.target as HTMLElement; 53 | const subMenu = elem.closest("a.sub-menu") as Element; 54 | 55 | if (subMenu.getAttribute('aria-expanded') == 'false') 56 | subMenu.setAttribute('aria-expanded', 'true'); 57 | else 58 | subMenu.setAttribute('aria-expanded', 'false'); 59 | } 60 | 61 | subMenuToggleHandlerOnPageReload = (): void => { 62 | const elem = this.elementRef.nativeElement.querySelector('[aria-current="page"]') 63 | .closest('ul.sub-menu-item') as Element; 64 | 65 | const subMenu = elem?.previousSibling as Element; 66 | 67 | subMenu?.setAttribute('aria-expanded', 'true'); 68 | } 69 | 70 | subMenuToggleHandlerOnRouteChange = (): void => { 71 | this.routerSubscription = this.router.events.subscribe((event) => { 72 | if (event instanceof NavigationEnd) { 73 | const subMenu = this.elementRef.nativeElement.querySelectorAll(".sub-menu"); 74 | const elem = this.elementRef.nativeElement.querySelector(`[href='${event.url}']`) as Element; 75 | 76 | if (elem.closest('ul.sub-menu-item')) return; 77 | 78 | subMenu.forEach((subMenu: Element) => { 79 | if (subMenu.getAttribute('aria-expanded') == 'true') 80 | subMenu.setAttribute('aria-expanded', 'false'); 81 | }); 82 | } 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/app/admin/admin-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | import { AdminRoutes, ElementRoutes, SettingRoutes } from './admin.routes'; 4 | import { AdminPageNotFoundComponent } from './views/admin-page-not-found/admin-page-not-found.component'; 5 | import { DashboardComponent } from './views/dashboard/dashboard.component'; 6 | import { AdminAlertComponent } from './views/elements/alert/admin-alert.component'; 7 | import { ButtonsComponent } from './views/elements/buttons/buttons.component'; 8 | import { AdminDataTableComponent } from './views/elements/data-table/data-table.component'; 9 | import { FormsComponent } from './views/elements/forms/forms.component'; 10 | import { AdminModalComponent } from './views/elements/modal/admin-modal.component'; 11 | import { AdminTabComponent } from './views/elements/tab/admin-tab.component'; 12 | import { EventsComponent } from './views/events/events.component'; 13 | import { TestComponent } from './views/events/test/test.component'; 14 | import { ProfileComponent } from './views/settings/profile/profile.component'; 15 | import { UsersComponent } from './views/settings/users/users.component'; 16 | 17 | 18 | const routes: Routes = [ 19 | { 20 | path: '', 21 | redirectTo: AdminRoutes.Dashboard, 22 | pathMatch: 'full', 23 | }, 24 | { 25 | title: 'Dashboard', 26 | path: AdminRoutes.Dashboard, 27 | component: DashboardComponent, 28 | }, 29 | { 30 | title: 'Events', 31 | path: AdminRoutes.Events, 32 | component: EventsComponent, 33 | children: [ 34 | { 35 | path: 'testing', 36 | component: TestComponent, 37 | outlet: 'test', 38 | }, 39 | ], 40 | }, 41 | { 42 | title: 'Elements', 43 | path: AdminRoutes.Elements, 44 | children: [ 45 | { 46 | title: 'Alert', 47 | path: ElementRoutes.Alert, 48 | component: AdminAlertComponent, 49 | }, 50 | { 51 | path: 'tabs', 52 | component: AdminTabComponent, 53 | }, 54 | { 55 | title: 'Modal', 56 | path: ElementRoutes.Modal, 57 | component: AdminModalComponent, 58 | }, 59 | { 60 | title: 'Buttons', 61 | path: ElementRoutes.Buttons, 62 | component: ButtonsComponent, 63 | }, 64 | { 65 | title: 'Data Table', 66 | path: ElementRoutes.DataTable, 67 | component: AdminDataTableComponent, 68 | }, 69 | { 70 | title: 'Forms', 71 | path: ElementRoutes.Forms, 72 | component: FormsComponent, 73 | }, 74 | ], 75 | }, 76 | { 77 | path: AdminRoutes.Settings, 78 | children: [ 79 | { 80 | title: 'Settings', 81 | path: SettingRoutes.Profile, 82 | component: ProfileComponent, 83 | }, 84 | { 85 | title: 'Users', 86 | path: SettingRoutes.Users, 87 | component: UsersComponent, 88 | }, 89 | ], 90 | }, 91 | { path: '**', component: AdminPageNotFoundComponent }, 92 | ]; 93 | 94 | @NgModule({ 95 | declarations: [], 96 | imports: [RouterModule.forChild(routes)], 97 | exports: [RouterModule], 98 | }) 99 | export class AdminRoutingModule {} 100 | -------------------------------------------------------------------------------- /src/app/admin/layouts/sidebar/sidebar.component.css: -------------------------------------------------------------------------------- 1 | /* Sidebar */ 2 | .sidebar { 3 | @apply sticky top-0 px-3 bg-slate-900 min-h-screen pt-5 transition-all duration-300 4 | } 5 | 6 | .sidebar[aria-expanded=true] { 7 | @apply w-60 8 | } 9 | 10 | .sidebar[aria-expanded=false] { 11 | @apply w-0 p-0 overflow-hidden 12 | } 13 | 14 | .brand-wrapper { 15 | @apply flex items-center min-h-[2rem] justify-between 16 | } 17 | 18 | .brand { 19 | @apply flex items-center gap-x-2 transition-all duration-300 20 | } 21 | 22 | app-sidebar[aria-expanded="false"] .brand-wrapper { 23 | @apply justify-evenly 24 | } 25 | 26 | app-sidebar[aria-expanded="false"] .brand { 27 | @apply scale-0 w-0 28 | } 29 | 30 | /* Sidebar Links */ 31 | .menu-links { 32 | @apply flex flex-col gap-y-3 pt-5 font-medium; 33 | } 34 | 35 | .menu-item { 36 | @apply inline-flex w-full gap-x-2 items-center px-2 py-1 text-gray-500 transition duration-300 ease-in-out rounded overflow-hidden 37 | } 38 | 39 | .menu-item span { 40 | @apply text-sm 41 | } 42 | 43 | .sidebar[aria-expanded=false] .menu-links .menu-item span { 44 | @apply hidden 45 | } 46 | 47 | .menu-item.active { 48 | @apply text-emerald-600 49 | } 50 | 51 | .menu-item:hover { 52 | @apply bg-slate-800 text-emerald-600 53 | } 54 | 55 | .menu-item i::before { 56 | @apply inline 57 | } 58 | 59 | .sub-menu { 60 | position: relative; 61 | } 62 | 63 | .sub-menu[aria-expanded=true] { 64 | @apply text-gray-300 65 | } 66 | 67 | .sub-menu::after { 68 | font-family: "Bootstrap-Icons"; 69 | content: "\F282"; 70 | position: absolute; 71 | font-size: 0.5rem; 72 | right: 0; 73 | padding: 0.5rem; 74 | transition: all 0.2s ease-in-out; 75 | } 76 | 77 | .sub-menu[aria-expanded=true]::after { 78 | transform: rotateZ(90deg); 79 | } 80 | 81 | .sub-menu[icon-hidden]::after { 82 | opacity: 0; 83 | } 84 | 85 | .sub-menu-item { 86 | @apply flex flex-col ml-4 pl-2 border-l border-slate-700 text-sm overflow-hidden max-h-0 transition-[max-height] duration-300 ease-in-out 87 | } 88 | 89 | .sub-menu[aria-expanded=true]+.sub-menu-item { 90 | @apply !max-h-96 91 | } 92 | 93 | .collapsible-top-icon, 94 | .collapsible-bottom-icon { 95 | @apply transition-all duration-100 ease-in-out 96 | } 97 | 98 | .collapsible-btn-container { 99 | @apply fixed left-0 top-1/2 translate-x-[15rem] transition-all duration-300 100 | } 101 | 102 | .collapsible-top-icon { 103 | @apply bg-slate-400 h-4 w-1 translate-y-[0.15rem] rounded-full 104 | } 105 | 106 | .collapsible-bottom-icon { 107 | @apply bg-slate-400 h-4 w-1 translate-y-[-0.15rem] rounded-full 108 | } 109 | 110 | #sidebar-collapse-btn:hover .collapsible-top-icon { 111 | @apply bg-slate-800 112 | } 113 | 114 | #sidebar-collapse-btn:hover .collapsible-bottom-icon { 115 | @apply bg-slate-800 116 | } 117 | 118 | .sidebar[aria-expanded=false] .collapsible-btn-container { 119 | @apply translate-x-[0.3rem] 120 | } 121 | 122 | .sidebar[aria-expanded=false] .collapsible-btn-container .collapsible-top-icon { 123 | @apply rotate-[-15deg] 124 | } 125 | 126 | .sidebar[aria-expanded=false] .collapsible-btn-container .collapsible-bottom-icon { 127 | @apply rotate-[15deg] 128 | } 129 | 130 | .sidebar[aria-expanded=true] #sidebar-collapse-btn:hover .collapsible-top-icon { 131 | @apply rotate-[15deg] 132 | } 133 | 134 | .sidebar[aria-expanded=true] #sidebar-collapse-btn:hover .collapsible-bottom-icon { 135 | @apply rotate-[-15deg] 136 | } -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "ngwind": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:browser", 15 | "options": { 16 | "outputPath": "dist/ngwind", 17 | "index": "src/index.html", 18 | "main": "src/main.ts", 19 | "polyfills": [ 20 | "zone.js" 21 | ], 22 | "tsConfig": "tsconfig.app.json", 23 | "assets": [ 24 | "src/favicon.ico", 25 | "src/assets" 26 | ], 27 | "styles": [ 28 | "src/styles.css", 29 | "./node_modules/notyf/notyf.min.css" 30 | ], 31 | "scripts": [] 32 | }, 33 | "configurations": { 34 | "production": { 35 | "budgets": [ 36 | { 37 | "type": "initial", 38 | "maximumWarning": "500kb", 39 | "maximumError": "1mb" 40 | }, 41 | { 42 | "type": "anyComponentStyle", 43 | "maximumWarning": "2kb", 44 | "maximumError": "4kb" 45 | } 46 | ], 47 | "outputHashing": "all" 48 | }, 49 | "development": { 50 | "buildOptimizer": false, 51 | "optimization": false, 52 | "vendorChunk": true, 53 | "extractLicenses": false, 54 | "sourceMap": true, 55 | "namedChunks": true, 56 | "fileReplacements": [ 57 | { 58 | "replace": "src/environments/environment.ts", 59 | "with": "src/environments/environment.development.ts" 60 | } 61 | ] 62 | } 63 | }, 64 | "defaultConfiguration": "development" 65 | }, 66 | "serve": { 67 | "builder": "@angular-devkit/build-angular:dev-server", 68 | "configurations": { 69 | "production": { 70 | "buildTarget": "ngwind:build:production" 71 | }, 72 | "development": { 73 | "buildTarget": "ngwind:build:development" 74 | } 75 | }, 76 | "defaultConfiguration": "development" 77 | }, 78 | "extract-i18n": { 79 | "builder": "@angular-devkit/build-angular:extract-i18n", 80 | "options": { 81 | "buildTarget": "ngwind:build" 82 | } 83 | }, 84 | "test": { 85 | "builder": "@angular-devkit/build-angular:karma", 86 | "options": { 87 | "polyfills": [ 88 | "zone.js", 89 | "zone.js/testing" 90 | ], 91 | "tsConfig": "tsconfig.spec.json", 92 | "assets": [ 93 | "src/favicon.ico", 94 | "src/assets" 95 | ], 96 | "styles": [ 97 | "src/styles.css" 98 | ], 99 | "scripts": [] 100 | } 101 | } 102 | } 103 | } 104 | }, 105 | "cli": { 106 | "analytics": "d667393a-d259-4014-a102-9abf03f1d4c0" 107 | } 108 | } -------------------------------------------------------------------------------- /src/app/public/layouts/header/header.component.html: -------------------------------------------------------------------------------- 1 |
2 | 32 | 33 | 72 |
-------------------------------------------------------------------------------- /src/app/admin/layouts/header/header.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 9 |
10 |
11 | 14 |
15 |
16 |
17 | 21 |
22 |

johndoe

23 |

Administrator

24 |
25 |
26 | 27 | 63 |
64 |
65 |
66 |
-------------------------------------------------------------------------------- /src/app/admin/views/elements/data-table/table.data.ts: -------------------------------------------------------------------------------- 1 | export interface IProduct { 2 | id: number; 3 | name: string; 4 | color: string; 5 | category: string; 6 | price: number; 7 | } 8 | 9 | export interface IColumn { 10 | field: string; 11 | headerName: string; 12 | width?: number; 13 | isEditable?: boolean; 14 | isSortable?: boolean; 15 | type?: string | number | boolean ; 16 | } 17 | 18 | export class TableData { 19 | public static readonly products: IProduct[] = [ 20 | { 21 | id: 1, 22 | name: 'Apple MacBook Pro 17"', 23 | color: 'Silver', 24 | category: 'Laptop', 25 | price: 29999, 26 | }, 27 | { 28 | id: 2, 29 | name: 'Microsoft Surface Pro', 30 | color: 'White', 31 | category: 'Laptop PC', 32 | price: 1999, 33 | }, 34 | { 35 | id: 3, 36 | name: 'Magic Mouse 2', 37 | color: 'Black', 38 | category: 'Accessories', 39 | price: 99, 40 | }, 41 | { 42 | id: 4, 43 | name: 'Apple Watch', 44 | color: 'Black', 45 | category: 'Watches', 46 | price: 199, 47 | }, 48 | { 49 | id: 5, 50 | name: 'Apple iMac', 51 | color: 'Silver', 52 | category: 'PC', 53 | price: 199, 54 | }, 55 | { 56 | id: 6, 57 | name: 'Apple AirPods', 58 | color: 'White', 59 | category: 'Accessories', 60 | price: 399, 61 | }, 62 | { 63 | id: 7, 64 | name: 'iPad Pro', 65 | color: 'Gold', 66 | category: 'Tablet', 67 | price: 699, 68 | }, 69 | { 70 | id: 8, 71 | name: 'Magic Keyboard', 72 | color: 'Black', 73 | category: 'Accessories', 74 | price: 99, 75 | }, 76 | { 77 | id: 9, 78 | name: 'Smart Folio iPad Air', 79 | color: 'Blue', 80 | category: 'Accessories', 81 | price: 79, 82 | }, 83 | { 84 | id: 10, 85 | name: 'AirTag', 86 | color: 'Silver', 87 | category: 'Accessories', 88 | price: 29, 89 | }, 90 | { 91 | id: 7, 92 | name: 'iPad Pro', 93 | color: 'Gold', 94 | category: 'Tablet', 95 | price: 699, 96 | }, 97 | { 98 | id: 8, 99 | name: 'Magic Keyboard', 100 | color: 'Black', 101 | category: 'Accessories', 102 | price: 99, 103 | }, 104 | { 105 | id: 9, 106 | name: 'Smart Folio iPad Air', 107 | color: 'Blue', 108 | category: 'Accessories', 109 | price: 79, 110 | }, 111 | { 112 | id: 10, 113 | name: 'AirTag', 114 | color: 'Silver', 115 | category: 'Accessories', 116 | price: 29, 117 | }, 118 | ]; 119 | public static readonly columnData: IColumn[] = [ 120 | { 121 | field: 'productname', 122 | headerName: 'product name', 123 | width: 25, 124 | isEditable: true, 125 | isSortable: false, 126 | 127 | }, 128 | { 129 | field: 'color', 130 | headerName: 'Color', 131 | width: 25, 132 | isEditable: true, 133 | isSortable: false, 134 | 135 | }, 136 | { 137 | field: 'category', 138 | headerName: 'Category', 139 | width: 25, 140 | isEditable: true, 141 | isSortable: false, 142 | 143 | }, 144 | { 145 | field: 'price', 146 | headerName: 'Price', 147 | width: 25, 148 | isEditable: true, 149 | isSortable: false, 150 | 151 | }, 152 | { 153 | field: 'action', 154 | headerName: 'Action', 155 | width: 25, 156 | isEditable: true, 157 | isSortable: false, 158 | 159 | }, 160 | ]; 161 | 162 | public static readonly pageNumber: number[] = [1, 2, 3, 4, 5]; 163 | } 164 | -------------------------------------------------------------------------------- /src/app/public/auth/signin/signin.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Get Started Now 6 |

7 | 8 |

Enter your credentials to access your account

9 | 10 |
11 | 16 |
17 |
18 |
19 |
20 |
21 |

or

22 |
23 |
24 |
25 |
26 | 27 | 29 | 30 |
31 |
32 | 33 |
34 | 36 | 37 | 38 | 39 |
40 | 41 |
42 |
43 | 44 |
45 | 47 | 48 | 49 | 50 |
51 | 52 |
53 | 54 |
55 |
56 | 57 | 58 |
59 | Forget password? 60 |
61 | 62 | 68 |
69 | 70 |
71 |

Don't have any account? Sign up now!

73 |
74 |
75 | 82 |
83 |
-------------------------------------------------------------------------------- /src/app/public/auth/signup/signup.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Get Started Now 6 |

7 |

Enter your credentials to create your account

8 |
9 | 14 |
15 |
16 |
17 |
18 |
19 |

or

20 |
21 |
22 |
23 |
24 |
25 |
26 | 27 |
28 | 30 | 31 | 32 | 33 |
34 |
35 |
36 | 37 |
38 | 40 | 41 | 42 | 43 |
44 |
45 |
46 | 47 |
48 | 50 | 51 | 52 | 53 |
54 |
55 |
56 | 57 |
58 | 60 | 61 | 62 | 63 |
64 |
65 |
66 | 70 |
71 |
72 |

73 | Already have an account? 74 | 75 | Sign in 76 | 77 | instead. 78 |

79 |
80 |
81 | 88 |
89 |
-------------------------------------------------------------------------------- /docs/runtime.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"runtime.js","mappings":";;;;UAAA;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;UAEA;UACA;;;;;WCzBA;WACA;WACA;WACA;WACA,+BAA+B,wCAAwC;WACvE;WACA;WACA;WACA;WACA,iBAAiB,qBAAqB;WACtC;WACA;WACA,kBAAkB,qBAAqB;WACvC;WACA;WACA,KAAK;WACL;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;WC3BA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;;WAEA;WACA;WACA;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA,MAAM,qBAAqB;WAC3B;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;WACA;WACA","sources":["webpack/bootstrap","webpack/runtime/chunk loaded","webpack/runtime/define property getters","webpack/runtime/hasOwnProperty shorthand","webpack/runtime/make namespace object","webpack/runtime/jsonp chunk loading","webpack/before-startup","webpack/startup","webpack/after-startup"],"sourcesContent":["// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t\"runtime\": 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkngwind\"] = self[\"webpackChunkngwind\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","","",""],"names":[],"sourceRoot":"webpack:///","x_google_ignoreList":[0,1,2,3,4,5,6,7,8]} -------------------------------------------------------------------------------- /src/app/admin/views/elements/alert/admin-alert.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Basic Alerts

5 |
6 | 7 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 8 | blanditiis 9 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

10 |
11 | 12 | 13 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 14 | blanditiis 15 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

16 |
17 | 18 | 19 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 20 | blanditiis 21 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

22 |
23 | 24 | 25 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 26 | blanditiis 27 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

28 |
29 |
30 | 31 | 32 |
33 |
34 |

Dismissable Alerts

35 |
36 | 37 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 38 | blanditiis 39 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

40 |
41 | 42 | 43 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 44 | blanditiis 45 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

46 |
47 | 48 | 49 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 50 | blanditiis 51 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

52 |
53 | 54 | 55 |

Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 56 | blanditiis 57 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis?

58 |
59 |
60 | 61 |
62 |
63 |

Alerts With Icons

64 |
65 | 66 |
67 | 68 | Success 69 |
70 |

71 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 72 | blanditiis 73 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis? 74 |

75 |
76 | 77 | 78 |
79 | 80 | Danger 81 |
82 |

83 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 84 | blanditiis 85 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis? 86 |

87 |
88 | 89 | 90 |
91 | 92 | Info 93 |
94 |

95 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 96 | blanditiis 97 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis? 98 |

99 |
100 | 101 | 102 |
103 | 104 | Warning 105 |
106 |

107 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Deleniti repellendus porro nam, natus 108 | blanditiis 109 | quibusdam mollitia! Ipsam perferendis sint error laudantium eos atque aut nobis? 110 |

111 |
112 |
113 |
-------------------------------------------------------------------------------- /src/app/admin/layouts/sidebar/sidebar.component.html: -------------------------------------------------------------------------------- 1 | 112 | 113 |
114 | 122 |
-------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"); 2 | 3 | @import "tailwindcss/base"; 4 | @import "tailwindcss/components"; 5 | @import "tailwindcss/utilities"; 6 | 7 | @layer components { 8 | * { 9 | font-family: "Inter", sans-serif !important; 10 | -webkit-font-smoothing: antialiased; 11 | padding: 0; 12 | margin: 0; 13 | box-sizing: border-box; 14 | } 15 | 16 | /* Text color */ 17 | .text-light { 18 | @apply text-slate-400; 19 | } 20 | 21 | /* Text size */ 22 | .text-2xs { 23 | font-size: 0.5rem !important; 24 | } 25 | 26 | /* buttons utility */ 27 | .btn { 28 | @apply px-5 py-2 text-sm font-medium rounded-lg text-center transition-colors duration-300 border; 29 | } 30 | 31 | button:disabled { 32 | @apply opacity-80; 33 | } 34 | 35 | /* button sizes */ 36 | 37 | .btn-xs { 38 | @apply px-3 py-2 text-xs; 39 | } 40 | 41 | .btn-sm { 42 | @apply px-3 py-2 text-sm; 43 | } 44 | 45 | .btn-lg { 46 | @apply px-5 py-3 text-sm; 47 | } 48 | 49 | .btn-xl { 50 | @apply px-6 py-3.5 text-sm; 51 | } 52 | 53 | /* fill buttons type */ 54 | .btn-text { 55 | @apply transition duration-150 ease-in-out; 56 | } 57 | 58 | .btn-theme { 59 | @apply bg-emerald-700 border-emerald-700 text-white hover:bg-emerald-800 hover:border-emerald-800; 60 | } 61 | 62 | .btn-theme:focus { 63 | @apply outline-none ring-2 bg-emerald-600 ring-offset-1; 64 | } 65 | 66 | .btn-primary { 67 | @apply bg-blue-700 border-blue-700 text-white hover:bg-blue-800 hover:border-blue-800; 68 | } 69 | 70 | .btn-info { 71 | @apply bg-indigo-700 border-indigo-700 text-white hover:bg-indigo-800 hover:border-indigo-800; 72 | } 73 | 74 | .btn-success { 75 | @apply bg-green-700 border-green-700 text-white hover:bg-green-800 hover:border-green-800; 76 | } 77 | 78 | .btn-danger { 79 | @apply bg-red-700 border-red-700 text-white hover:bg-red-800 hover:border-red-800; 80 | } 81 | 82 | .btn-warning { 83 | @apply bg-yellow-600 border-yellow-600 text-white hover:bg-yellow-700 hover:border-yellow-700; 84 | } 85 | 86 | .btn-secondary { 87 | @apply bg-slate-700 border-slate-700 text-white hover:bg-slate-800 hover:border-slate-800; 88 | } 89 | 90 | /* outline buttons type */ 91 | 92 | .btn-outline-primary { 93 | @apply border bg-transparent border-blue-700 text-blue-700 hover:bg-blue-700 hover:text-white; 94 | } 95 | 96 | .btn-outline-info { 97 | @apply border bg-transparent border-indigo-700 text-indigo-700 hover:bg-indigo-700 hover:text-white; 98 | } 99 | 100 | .btn-outline-success { 101 | @apply border bg-transparent border-green-700 text-green-700 hover:bg-green-700 hover:text-white; 102 | } 103 | 104 | .btn-outline-danger { 105 | @apply border bg-transparent border-red-700 text-red-700 hover:bg-red-700 hover:text-white; 106 | } 107 | 108 | .btn-outline-warning { 109 | @apply border bg-transparent border-yellow-600 text-yellow-600 hover:bg-yellow-600 hover:text-white; 110 | } 111 | 112 | .btn-outline-secondary { 113 | @apply border bg-transparent border-slate-700 text-slate-700 hover:bg-slate-700 hover:text-white; 114 | } 115 | 116 | /* icon with button */ 117 | .btn-icon { 118 | @apply inline-flex items-center; 119 | } 120 | 121 | /* Card */ 122 | .card { 123 | @apply py-2 px-4 mb-4 h-full bg-white rounded-xl shadow-md shadow-gray-200; 124 | } 125 | 126 | .card-title { 127 | @apply text-gray-900; 128 | } 129 | 130 | /* Input */ 131 | .input { 132 | @apply transition-all duration-100 ease-in-out focus:ring-1 focus:ring-inset focus:ring-emerald-600; 133 | } 134 | 135 | .form-check { 136 | @apply flex items-center mb-4; 137 | } 138 | .form-check-input { 139 | @apply w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500; 140 | } 141 | .form-check-label { 142 | @apply ms-2 text-sm font-medium text-gray-900; 143 | } 144 | .form-switch { 145 | @apply relative inline-flex items-center mb-5 cursor-pointer; 146 | } 147 | .form-input-switch { 148 | @apply w-10 h-5 bg-gray-300 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300 rounded-full peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:w-4 after:h-4 after:transition-all peer-checked:bg-blue-600; 149 | } 150 | 151 | .form-group { 152 | @apply flex flex-col gap-y-0.5 mb-3; 153 | } 154 | 155 | .form-label-sm { 156 | @apply text-xs; 157 | } 158 | .form-label { 159 | @apply block mb-1 text-sm font-medium text-gray-900; 160 | } 161 | .form-label-lg { 162 | @apply text-lg; 163 | } 164 | 165 | .form-control { 166 | @apply py-2 px-3 block w-full border border-gray-200 text-gray-900 text-sm rounded-md !outline-none input; 167 | } 168 | .form-control-sm { 169 | @apply !py-1.5 !px-3 block w-full border border-gray-200 text-gray-900 text-sm rounded-[5px] !outline-none input; 170 | } 171 | .form-control-lg { 172 | @apply !py-3 !px-3 block w-full border border-gray-200 text-gray-900 text-sm rounded-lg !outline-none input; 173 | } 174 | 175 | .form-select { 176 | @apply py-2 px-2 block w-full border border-gray-200 text-gray-900 text-sm rounded-md !outline-none input; 177 | } 178 | .form-input-icon { 179 | @apply absolute inset-y-0 start-0 flex items-center ps-3.5 pointer-events-none; 180 | } 181 | label.required::after { 182 | content: "*"; 183 | @apply ml-[3px] text-red-500; 184 | } 185 | 186 | .file-upload { 187 | @apply block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer focus:outline-none; 188 | } 189 | 190 | input[type="file"]::file-selector-button { 191 | @apply border-0 py-2 px-4 bg-blue-700 text-white hover:bg-blue-600 cursor-pointer transition-colors; 192 | } 193 | } 194 | 195 | /*Additional Global Css Overrides*/ 196 | .notyf__toast { 197 | max-width: 50em !important; 198 | } 199 | 200 | .notyf__toast .notyf__ripple { 201 | height: 60em !important; 202 | width: 60em !important; 203 | } 204 | 205 | .notyf__message { 206 | font-size: 0.875rem !important; 207 | } 208 | -------------------------------------------------------------------------------- /docs/runtime.js: -------------------------------------------------------------------------------- 1 | /******/ (() => { // webpackBootstrap 2 | /******/ "use strict"; 3 | /******/ var __webpack_modules__ = ({}); 4 | /************************************************************************/ 5 | /******/ // The module cache 6 | /******/ var __webpack_module_cache__ = {}; 7 | /******/ 8 | /******/ // The require function 9 | /******/ function __webpack_require__(moduleId) { 10 | /******/ // Check if module is in cache 11 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 12 | /******/ if (cachedModule !== undefined) { 13 | /******/ return cachedModule.exports; 14 | /******/ } 15 | /******/ // Create a new module (and put it into the cache) 16 | /******/ var module = __webpack_module_cache__[moduleId] = { 17 | /******/ // no module.id needed 18 | /******/ // no module.loaded needed 19 | /******/ exports: {} 20 | /******/ }; 21 | /******/ 22 | /******/ // Execute the module function 23 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 24 | /******/ 25 | /******/ // Return the exports of the module 26 | /******/ return module.exports; 27 | /******/ } 28 | /******/ 29 | /******/ // expose the modules object (__webpack_modules__) 30 | /******/ __webpack_require__.m = __webpack_modules__; 31 | /******/ 32 | /************************************************************************/ 33 | /******/ /* webpack/runtime/chunk loaded */ 34 | /******/ (() => { 35 | /******/ var deferred = []; 36 | /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { 37 | /******/ if(chunkIds) { 38 | /******/ priority = priority || 0; 39 | /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; 40 | /******/ deferred[i] = [chunkIds, fn, priority]; 41 | /******/ return; 42 | /******/ } 43 | /******/ var notFulfilled = Infinity; 44 | /******/ for (var i = 0; i < deferred.length; i++) { 45 | /******/ var [chunkIds, fn, priority] = deferred[i]; 46 | /******/ var fulfilled = true; 47 | /******/ for (var j = 0; j < chunkIds.length; j++) { 48 | /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { 49 | /******/ chunkIds.splice(j--, 1); 50 | /******/ } else { 51 | /******/ fulfilled = false; 52 | /******/ if(priority < notFulfilled) notFulfilled = priority; 53 | /******/ } 54 | /******/ } 55 | /******/ if(fulfilled) { 56 | /******/ deferred.splice(i--, 1) 57 | /******/ var r = fn(); 58 | /******/ if (r !== undefined) result = r; 59 | /******/ } 60 | /******/ } 61 | /******/ return result; 62 | /******/ }; 63 | /******/ })(); 64 | /******/ 65 | /******/ /* webpack/runtime/define property getters */ 66 | /******/ (() => { 67 | /******/ // define getter functions for harmony exports 68 | /******/ __webpack_require__.d = (exports, definition) => { 69 | /******/ for(var key in definition) { 70 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 71 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 72 | /******/ } 73 | /******/ } 74 | /******/ }; 75 | /******/ })(); 76 | /******/ 77 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 78 | /******/ (() => { 79 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 80 | /******/ })(); 81 | /******/ 82 | /******/ /* webpack/runtime/make namespace object */ 83 | /******/ (() => { 84 | /******/ // define __esModule on exports 85 | /******/ __webpack_require__.r = (exports) => { 86 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 87 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 88 | /******/ } 89 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 90 | /******/ }; 91 | /******/ })(); 92 | /******/ 93 | /******/ /* webpack/runtime/jsonp chunk loading */ 94 | /******/ (() => { 95 | /******/ // no baseURI 96 | /******/ 97 | /******/ // object to store loaded and loading chunks 98 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 99 | /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded 100 | /******/ var installedChunks = { 101 | /******/ "runtime": 0 102 | /******/ }; 103 | /******/ 104 | /******/ // no chunk on demand loading 105 | /******/ 106 | /******/ // no prefetching 107 | /******/ 108 | /******/ // no preloaded 109 | /******/ 110 | /******/ // no HMR 111 | /******/ 112 | /******/ // no HMR manifest 113 | /******/ 114 | /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); 115 | /******/ 116 | /******/ // install a JSONP callback for chunk loading 117 | /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { 118 | /******/ var [chunkIds, moreModules, runtime] = data; 119 | /******/ // add "moreModules" to the modules object, 120 | /******/ // then flag all "chunkIds" as loaded and fire callback 121 | /******/ var moduleId, chunkId, i = 0; 122 | /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { 123 | /******/ for(moduleId in moreModules) { 124 | /******/ if(__webpack_require__.o(moreModules, moduleId)) { 125 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; 126 | /******/ } 127 | /******/ } 128 | /******/ if(runtime) var result = runtime(__webpack_require__); 129 | /******/ } 130 | /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); 131 | /******/ for(;i < chunkIds.length; i++) { 132 | /******/ chunkId = chunkIds[i]; 133 | /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { 134 | /******/ installedChunks[chunkId][0](); 135 | /******/ } 136 | /******/ installedChunks[chunkId] = 0; 137 | /******/ } 138 | /******/ return __webpack_require__.O(result); 139 | /******/ } 140 | /******/ 141 | /******/ var chunkLoadingGlobal = self["webpackChunkngwind"] = self["webpackChunkngwind"] || []; 142 | /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); 143 | /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); 144 | /******/ })(); 145 | /******/ 146 | /************************************************************************/ 147 | /******/ 148 | /******/ 149 | /******/ })() 150 | ; 151 | //# sourceMappingURL=runtime.js.map -------------------------------------------------------------------------------- /src/app/shared/components/data-table/data-table.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Table

4 |
5 |
6 |
7 |
8 |
9 | 10 | 11 | 12 | 21 | 24 | 27 | 30 | 33 | 34 | 35 | 36 | @if( rowData.length == 0 || rowData.length == undefined){ 37 |
38 | 52 |
53 | } @else { 54 | 55 | @for (product of rowData; track product?.id){ 56 | 57 | 60 | 63 | 66 | 69 | 72 | 73 | } 74 | 75 | } 76 |
13 | Product name 14 | 17 | 20 | 22 | Color 23 | 25 | Category 26 | 28 | Price 29 | 31 | Action 32 |
58 | {{product?.name}} 59 | 61 | {{product?.color}} 62 | 64 | {{product?.category}} 65 | 67 | {{product?.price}} 68 | 70 | Edit 71 |
77 |
78 |
79 | 117 |
118 |
119 |
-------------------------------------------------------------------------------- /src/app/admin/views/elements/buttons/buttons.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Fill buttons

5 |
6 |
7 | 10 | 13 | 16 | 19 | 22 | 25 |
26 |
27 |
28 |
29 |

Buttons sizes

30 |
31 |
32 | 35 | 38 | 41 | 44 | 45 |
46 |
47 |
48 |
49 |

Outlines buttons

50 |
51 |
52 | 55 | 58 | 61 | 64 | 67 | 70 |
71 |
72 |
73 |
74 |

Buttons with icon

75 |
76 |
77 | 85 | 93 |
94 |
95 |
96 |
97 |

Loader

98 |
99 |
100 | 112 | 125 |
126 |
127 |
-------------------------------------------------------------------------------- /src/app/admin/views/dashboard/dashboard.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 |
7 |
8 |

25

9 |

Total Events

10 |
11 |
12 |
13 |
14 | 15 |
16 |
17 |

2560+

18 |

Total Ticket Sold

19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 |

5000+

27 |

Total Registration

28 |
29 |
30 |
31 |
32 | 33 |
34 |
35 |

$8000

36 |

Total Revenue

37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |

Area Wise Sale

47 |
48 |
49 |
50 | 51 |
52 |
53 | Chart Data 54 |
55 |
56 |
57 |
58 |

59 | Ticket Sold Today 60 |

61 |

62 | 63 | 278 64 | piece 65 |

66 |

67 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Neque molestiae incidunt officiis veritatis, 68 | architecto nam soluta, exercitationem minima laudantium harum qui. 69 |

70 |
71 | 72 | View Details 73 | 74 | 75 |
76 |
77 | 78 |
79 | 80 |
81 |
82 |
83 |

Latest Customers

84 | 85 | View all 86 | 87 |
88 |
89 |
    90 |
  • 91 |
    92 |
    93 | user image 94 |
    95 |
    96 |

    97 | John Doe 98 |

    99 |

    100 | john.deo@email.com 101 |

    102 |
    103 |
    104 | ${{i}} 105 |
    106 |
    107 |
  • 108 |
109 | 110 |
111 |
112 |
Total
113 | 6 of 300 114 |
115 | 116 | View Sales Report 117 | 118 |
119 |
120 |
121 | 122 |
123 |
124 |

Upcoming Events

125 |
126 |
127 |
128 | 133 |
134 |

135 | Envato International Online Meetup 2020 136 |

137 |

California, USA

138 |

139 | Lorem ipsum dolor sit, amet consectetur adipisicing elit. Sint ipsa vero illum quos vitae 140 | dolorum, earum 141 | recusandae est modi ea possimus nihil aspernatur 142 | libero unde itaque error quis, sit tenetur esse quam harum corrupti! Quia, tenetur provident, 143 | vero, recusandae 144 | aliquam possimus at mollitia quo perspiciatis 145 | adipisci in? Odio, impedit cumque. 146 |

147 |
148 |
149 |
150 |
152 | 153 |
154 |

$200

155 |
156 |
157 |
159 | 160 |
161 |

150 pcs left

162 |
163 |
164 |
166 | 167 |
168 |

{{eventDate}}

169 |
170 |
171 |
172 |
173 | 174 | loading... 175 |
176 |
177 |
178 |
179 |
180 | -------------------------------------------------------------------------------- /src/app/admin/views/elements/forms/forms.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Input Sizes

5 |
6 |
7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 |
25 |

Select input

26 |
27 |
28 |
29 | 32 | 39 |
40 |
41 |
42 |
43 |
44 |

Input element with icon

45 |
46 |
47 |
48 | 51 |
52 |
53 | 60 |
61 | 64 |
65 |
66 | 67 |
68 |
69 |
70 |
71 |

Textarea

72 |
73 |
74 |
75 | 78 | 79 |
80 |
81 |
82 |
83 |
84 |

File upload

85 |
86 |
87 |
88 | 91 | 92 |
93 | A profile picture is useful to confirm your are logged into your account 94 |
95 |
96 |
97 |
98 |
99 |
100 |

Checkbox

101 |
102 |
103 |
104 | 105 | 107 |
108 |
109 | 110 | 112 |
113 |
114 | 115 | 117 |
118 |
119 | 120 | 122 |
123 |
124 |
125 |
126 |
127 |

Radio buttons

128 |
129 |
130 |
131 | 132 | 135 |
136 |
137 | 138 | 141 |
142 |
143 | 144 | 147 |
148 |
149 | 150 | 153 |
154 |
155 |
156 |
157 |
158 |

Toggle Switch

159 |
160 |
161 | 167 |
168 |
169 |
170 |
171 |

Full form

172 |
173 |
174 |
175 |
176 |
177 |
178 | 181 |
182 |
183 | 189 |
190 | 195 |

or drag and drop

196 |
197 |

PNG, JPG, GIF up to 10MB

198 |
199 |
200 |
201 |
202 |
203 |
204 | 205 | 206 |
207 |
208 |
209 |
210 | 211 | 212 |
213 |
214 |
215 |
216 | 217 | 218 |
219 |
220 |
221 |
222 | 223 | 224 |
225 |
226 |
227 |
228 | 229 | 230 |
231 |
232 | 233 |
234 |
--------------------------------------------------------------------------------