User-management frontend
// src/app/core/models/user.models.ts
export interface User {
customerId?: number;
name: string;
email: string;
mobileNumber: string;
address?: string;
password: string;
role: string;
preferences?: string;
createdAt?: string;
}
// Interface for the API response wrapper
export interface ApiResponse<T> {
status: string;
message: string;
data: T[];
}
//src/app/core/services/user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { User, ApiResponse } from '../models/user.models';
@Injectable({
providedIn: 'root',
})
export class UserService {
private apiUrl = 'http://localhost:8080/api/users'; // Adjust based on your backend URL
constructor(private http: HttpClient) {}
getAllUsers(): Observable<User[]> {
return this.http
.get<ApiResponse<User>>(${this.apiUrl}/all)
.pipe(map((response) => response.data));
}
getUserById(userId: number): Observable<User> {
return this.http
.get<ApiResponse<User>>(${this.apiUrl}/${userId})
.pipe(map((response) => response.data[0]));
}
updateUser(userId: number, user: User): Observable<User> {
return this.http
.put<ApiResponse<User>>(${this.apiUrl}/${userId}, user)
.pipe(map((response) => response.data[0]));
}
deleteUser(userId: number): Observable<void> {
return this.http
.delete<ApiResponse<User>>(${this.apiUrl}/${userId})
.pipe(map(() => undefined));
}
searchUsers(keyword: string): Observable<User[]> {
return this.http
.get<ApiResponse<User>>(${this.apiUrl}/search?keyword=${keyword})
.pipe(map((response) => response.data));
}
}
//src/app/features/user-management/user-list/user-list.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from '../../../core/services/user.service';
import { User } from '../../../core/models/user.models';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-user-list',
standalone: true,
imports: [CommonModule, RouterLink, FormsModule],
templateUrl: './user-list.component.html',
styleUrls: ['./user-list.component.css'],
})
export class UserListComponent implements OnInit {
users: User[] = [];
searchKeyword: string = '';
constructor(private userService: UserService) {}
ngOnInit(): void {
this.loadUsers();
}
loadUsers(): void {
this.userService.getAllUsers().subscribe((users) => {
this.users = users;
});
}
searchUsers(): void {
if (this.searchKeyword.trim()) {
this.userService.searchUsers(this.searchKeyword).subscribe((users) => {
this.users = users;
});
} else {
this.loadUsers();
}
}
deleteUser(userId: number): void {
if (confirm('Are you sure you want to delete this user?')) {
this.userService.deleteUser(userId).subscribe(() => {
this.users = this.users.filter((user) => user.customerId !== userId);
});
}
}
}
//src/app/features/user-management/user-list/user-list.component.html
<div class="user-list"> <h2>User Management</h2> <div class="search-bar"> <input type="text" [(ngModel)]="searchKeyword" (input)="searchUsers()" placeholder="Search users..." class="form-control" /> </div> <table class="table"> <thead> <tr> <th>Name</th> <th>Email</th> <th>Mobile Number</th> <th>Role</th> <th>Actions</th> </tr> </thead> <tbody> <tr *ngFor="let user of users"> <td>{{ user.name }}</td> <td>{{ user.email }}</td> <td>{{ user.mobileNumber }}</td> <td>{{ user.role }}</td> <td> <a [routerLink]="['/users/edit', user.customerId]" class="btn btn-sm btn-warning">Edit</a> <button (click)="deleteUser(user.customerId!)" class="btn btn-sm btn-danger">Delete</button> </td> </tr> </tbody> </table> </div>// src/app/features/user-management/user-list/user-list.component.css
.user-list {
padding: 20px;
}
.search-bar {
margin-bottom: 20px;
}
.form-control {
width: 300px;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.table {
width: 100%;
border-collapse: collapse;
}
.table th,
.table td {
border: 1px solid #ddd;
padding: 8px;
}
.table th {
background-color: #f4f4f4;
}
.btn {
margin: 5px;
}
// src/app/features/user-management/user-form/user-form.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { UserService } from '../../../core/services/user.service';
import { User } from '../../../core/models/user.models';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-form',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './user-form.component.html',
styleUrls: ['./user-form.component.css'],
})
export class UserFormComponent implements OnInit {
user: User = {
name: '',
email: '',
mobileNumber: '',
password: '',
role: '',
};
constructor(
private userService: UserService,
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit(): void {
const userId = this.route.snapshot.paramMap.get('id');
if (userId) {
this.userService.getUserById(+userId).subscribe((user) => {
this.user = user;
});
}
}
saveUser(): void {
this.userService.updateUser(this.user.customerId!, this.user).subscribe(() => {
this.router.navigate(['/users']);
});
}
}
// src/app/features/user-management/user-form/user-form.component.html
<div class="user-form"> <h2>Edit User</h2> <form (ngSubmit)="saveUser()"> <div class="form-group"> <label for="name">Name</label> <input id="name" [(ngModel)]="user.name" name="name" required class="form-control" /> </div> <div class="form-group"> <label for="email">Email</label> <input id="email" [(ngModel)]="user.email" name="email" type="email" required class="form-control" /> </div> <div class="form-group"> <label for="mobileNumber">Mobile Number</label> <input id="mobileNumber" [(ngModel)]="user.mobileNumber" name="mobileNumber" required class="form-control" /> </div> <div class="form-group"> <label for="address">Address</label> <input id="address" [(ngModel)]="user.address" name="address" class="form-control" /> </div> <div class="form-group"> <label for="password">Password</label> <input id="password" [(ngModel)]="user.password" name="password" type="password" required class="form-control" /> </div> <div class="form-group"> <label for="role">Role</label> <select id="role" [(ngModel)]="user.role" name="role" required class="form-control" > <option value="USER">User</option> <option value="ADMIN">Admin</option> </select> </div> <div class="form-group"> <label for="preferences">Preferences (JSON)</label> <textarea id="preferences" [(ngModel)]="user.preferences" name="preferences" class="form-control" ></textarea> </div> <button type="submit" class="btn btn-primary">Save</button> <a [routerLink]="['/users']" class="btn btn-secondary">Cancel</a> </form> </div>//src/app/features/user-management/user-form/user-form.component.css
.user-form {
padding: 20px;
max-width: 500px;
margin: 0 auto;
}
.form-group {
margin-bottom: 15px;
}
.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
textarea.form-control {
height: 100px;
}
.btn {
margin-right: 10px;
}
//src/app/app.routes.ts
import { Routes } from '@angular/router';
import { LandingComponent } from './features/landing/landing.component';
import { UserProfileComponent } from './shared/components/user-profile/user-profile.component';
import { PageNotFoundComponent } from './shared/components/page-not-found/page-not-found.component';
import { LoginComponent } from './features/auth/login/login.component';
import { RegisterComponent } from './features/auth/register/register.component';
import { UserDashboardComponent } from './features/customer/user-dashboard/user-dashboard.component';
import { ProfileUpdateComponent } from './features/auth/profile-update/profile-update.component';
import { AuthGuard } from './core/guards/auth.guard';
import { UserListComponent } from './features/user-management/user-list/user-list.component';
import { UserFormComponent } from './features/user-management/user-form/user-form.component';
export const routes: Routes = [
{ path: '', component: LandingComponent },
{ path: 'auth/login', component: LoginComponent },
{ path: 'auth/register', component: RegisterComponent },
{ path: 'customer/dashboard', component: UserDashboardComponent, canActivate: [AuthGuard] },
{ path: 'customer/profileUpdateComponent', component: ProfileUpdateComponent, canActivate: [AuthGuard] },
{ path: 'users', component: UserListComponent, canActivate: [AuthGuard] }, // New route
{ path: 'users/edit/:id', component: UserFormComponent, canActivate: [AuthGuard] }, // New route
{ path: '**', component: PageNotFoundComponent },
];
//src/app/core/interceptors/auth.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent,
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { AuthStore } from '../services/store/auth.store'; // Adjust based on your auth store
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authStore: AuthStore) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const token = this.authStore.getToken(); // Adjust based on your auth store method
if (token) {
const cloned = req.clone({
headers: req.headers.set('Authorization', Bearer ${token}),
});
return next.handle(cloned);
}
return next.handle(req);
}
}
//src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { AuthInterceptor } from './core/interceptors/auth.interceptor';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient(withInterceptors([AuthInterceptor])),
],
};