Skip to content

Commit 973448d

Browse files
committed
Initial commit
0 parents  commit 973448d

32 files changed

+15565
-0
lines changed

.editorconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
ij_typescript_use_double_quotes = false
14+
15+
[*.md]
16+
max_line_length = off
17+
trim_trailing_whitespace = false

.gitignore

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# See https://docs.github.com/get-started/getting-started-with-git/ignoring-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

.vscode/extensions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3+
"recommendations": ["angular.ng-template"]
4+
}

.vscode/launch.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
}

.vscode/tasks.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
}

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Dynamic Angular Dashboard
2+
3+
A responsive **Dynamic Angular Dashboard** with user authentication, API integration, state management using Angular Signals, and performance optimizations.
4+
5+
---
6+
7+
## Features
8+
- **User Authentication** → JWT-based login & logout
9+
- **Dynamic Data Table** → Fetches data from [JSONPlaceholder](https://jsonplaceholder.typicode.com/posts)
10+
- **Filter/Search, Sorting, Pagination** → Built with Angular Material Table
11+
- **State Management** → Uses Angular Signals
12+
- **Lazy Loading & Performance Optimizations** → Uses OnPush Change Detection and async pipe
13+
- **Dark Mode Toggle**
14+
- **Auth Unit Test**
15+
16+
---
17+
18+
## Setup & Installation
19+
20+
### **Step 1: Clone the Repository**
21+
```sh
22+
git clone https://github.com/chiragobhan/dynamic-angular-dashboard.git
23+
cd dynamic-angular-dashboard
24+
```
25+
26+
### **Step 2: Install Dependencies**
27+
```sh
28+
npm install
29+
```
30+
31+
### **Step 3: Run JSON Server (Mock Backend)**
32+
We use `json-server` to simulate an API for user authentication. Users are stored in `db.json`:
33+
```json
34+
{
35+
"users": [
36+
{ "id": 1, "username": "admin", "password": "password", "token": "mock-jwt-token" },
37+
{ "id": 2, "username": "testuser", "password": "test123", "token": "mock-jwt-token" }
38+
]
39+
}
40+
```
41+
#### **Start JSON Server**
42+
```sh
43+
npx json-server --watch db.json --port 3000
44+
```
45+
46+
### **Step 4: Run the Angular App**
47+
```sh
48+
ng serve
49+
```
50+
Then open `http://localhost:4200/` in your browser.
51+
52+
---
53+
54+
## How It Works
55+
### **Authentication**
56+
- Users login via `json-server` API (Mock backend)
57+
- JWT token is stored in `localStorage`
58+
- `AuthGuard` protects routes, and prevents logged-out users from accessing `/dashboard`
59+
60+
### **State Management**
61+
- **Angular Signals** manage authentication state
62+
- Reactive `signal()` ensures instant UI updates on login/logout
63+
64+
### **Lazy Loading & Performance**
65+
- The **dashboard content** is lazy-loaded and uses OnPush Change Detection
66+
- **API requests** are optimized via Angular’s `async pipe`
67+
- **Pagination, Sorting, and Filtering** happen on the frontend for better UX
68+
69+
### **Dark Mode Toggle**
70+
- Uses `localStorage` to persist user theme
71+
- Applied via `document.body.classList.toggle('dark-theme')`
72+
73+
---
74+
75+
## Running Tests
76+
To run unit tests:
77+
```sh
78+
ng test
79+
```
80+
This will open the **Karma test runner** and execute auth unit test.
81+
82+
---
83+
84+
## Images
85+
86+
### Login Page | Light Mode
87+
<img src="https://github.com/user-attachments/assets/cfa66e10-114c-4466-8c87-7e93b6f23103" width="1000">
88+
89+
### Login Page | Dark Mode
90+
<img src="https://github.com/user-attachments/assets/6bc82649-1587-46c4-b4df-5c8a19a7bb29" width="1000">
91+
92+
### Dashboard Page | Light Mode
93+
<img src="https://github.com/user-attachments/assets/959b1942-fcae-4c3f-a72a-d846c4aa895e" width="1000">
94+
95+
### Dashboard Page | Dark Mode
96+
<img src="https://github.com/user-attachments/assets/79e988bf-cc71-48c4-874b-be14f3b180b3" width="1000">
97+
98+
---
99+
100+
**Disclaimer:** This project is an assignment completed for [Pillway](https://www.pillway.com/). All **logos and branding elements** belong to **Pillway** and are used solely for demonstration purposes.

angular.json

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
{
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3+
"version": 1,
4+
"newProjectRoot": "projects",
5+
"projects": {
6+
"pillway-dashboard": {
7+
"projectType": "application",
8+
"schematics": {
9+
"@schematics/angular:component": {
10+
"style": "scss"
11+
}
12+
},
13+
"root": "",
14+
"sourceRoot": "src",
15+
"prefix": "app",
16+
"architect": {
17+
"build": {
18+
"builder": "@angular-devkit/build-angular:application",
19+
"options": {
20+
"outputPath": "dist/pillway-dashboard",
21+
"index": "src/index.html",
22+
"browser": "src/main.ts",
23+
"polyfills": [
24+
"zone.js"
25+
],
26+
"tsConfig": "tsconfig.app.json",
27+
"inlineStyleLanguage": "scss",
28+
"assets": [
29+
{
30+
"glob": "**/*",
31+
"input": "public"
32+
}
33+
],
34+
"styles": [
35+
"node_modules/@angular/material/prebuilt-themes/cyan-orange.css",
36+
"src/styles.scss"
37+
],
38+
"scripts": []
39+
},
40+
"configurations": {
41+
"production": {
42+
"budgets": [
43+
{
44+
"type": "initial",
45+
"maximumWarning": "500kB",
46+
"maximumError": "1MB"
47+
},
48+
{
49+
"type": "anyComponentStyle",
50+
"maximumWarning": "4kB",
51+
"maximumError": "8kB"
52+
}
53+
],
54+
"outputHashing": "all"
55+
},
56+
"development": {
57+
"optimization": false,
58+
"extractLicenses": false,
59+
"sourceMap": true
60+
}
61+
},
62+
"defaultConfiguration": "production"
63+
},
64+
"serve": {
65+
"builder": "@angular-devkit/build-angular:dev-server",
66+
"configurations": {
67+
"production": {
68+
"buildTarget": "pillway-dashboard:build:production"
69+
},
70+
"development": {
71+
"buildTarget": "pillway-dashboard:build:development"
72+
}
73+
},
74+
"defaultConfiguration": "development"
75+
},
76+
"extract-i18n": {
77+
"builder": "@angular-devkit/build-angular:extract-i18n"
78+
},
79+
"test": {
80+
"builder": "@angular-devkit/build-angular:karma",
81+
"options": {
82+
"polyfills": [
83+
"zone.js",
84+
"zone.js/testing"
85+
],
86+
"tsConfig": "tsconfig.spec.json",
87+
"inlineStyleLanguage": "scss",
88+
"assets": [
89+
{
90+
"glob": "**/*",
91+
"input": "public"
92+
}
93+
],
94+
"styles": [
95+
"node_modules/@angular/material/prebuilt-themes/cyan-orange.css",
96+
"src/styles.scss"
97+
],
98+
"scripts": []
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}

db.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"users": [
3+
{
4+
"id": 1,
5+
"username": "admin",
6+
"password": "password",
7+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30"
8+
},
9+
{
10+
"id": 2,
11+
"username": "testuser",
12+
"password": "test123",
13+
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.NHVaYe26MbtOYhSKkoKYdFVomg4i8ZJd8_-RU8VNbftc4TSMb4bXP3l3YlNWACwyXPGffz5aXHc6lty1Y2t4SWRqGteragsVdZufDn5BlnJl9pdR_kdVFUsra2rWKEofkZeIC4yWytE58sMIihvo9H1ScmmVwBcQP6XETqYd0aSHp1gOa9RdUPDvoXQ5oqygTqVtxaDr6wUFKrKItgBMzWIdNZ6y7O9E0DhEPTbE9rfBo6KTFsHAZnMg4k68CDp2woYIaXbmYTWcvbzIuHO7_37GT79XdIwkm95QJ7hYC9RiwrV7mesbY4PAahERJawntho0my942XheVLmGwLMBkQ"
14+
}
15+
]
16+
}
17+

0 commit comments

Comments
 (0)