In this comprehensive guide, we'll build a modern User Management System using Angular. This application showcases several advanced features including theme switching, undo/redo functionality, and robust data management.
Table of Contents
- Project Overview
- Architecture and Design
- Core Features Implementation
- Services Implementation
- Component Development
- Advanced Features
- Best Practices and Tips
Project Overview
Our User Management System includes the following features.
- Modern, responsive design with light/dark theme support
- Interactive data grid with in-place editing
- Complete CRUD operations with validation
- Undo/Redo functionality
- Data export capabilities (Excel, PDF, PNG)
- Loading placeholders
- Enhanced user experience with tooltips
- Form validation with error messages
- Duplicate entry prevention
- Confirmation dialogs
- Local storage persistence
- Reusable components
Architecture and Design
Project Structure
src/
├── app/
│ ├── components/
│ │ ├── user-grid/
│ │ └── shared/
│ ├── services/
│ │ ├── user.service.ts
│ │ ├── theme.service.ts
│ │ └── data.service.ts
│ └── models/
│ └── user.model.ts
Core Models
// user.model.ts
export interface User {
id?: number;
name: string;
userName: string;
email: string;
phone: string;
website: string;
}
export interface UserState {
users: User[];
undoStack: User[][];
redoStack: User[][];
}
Core Features Implementation
- Theme Service: The theme service manages application-wide theme switching.
@Injectable({
providedIn: 'root'
})
export class ThemeService {
private isDarkTheme = new BehaviorSubject<boolean>(false);
isDarkTheme$ = this.isDarkTheme.asObservable();
constructor() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
this.setDarkTheme(savedTheme === 'dark');
}
}
setDarkTheme(isDark: boolean) {
this.isDarkTheme.next(isDark);
localStorage.setItem('theme', isDark ? 'dark' : 'light');
document.body.classList.toggle('dark-theme', isDark);
}
}
- User Service: The User Service handles all data operations with undo/redo support.
@Injectable({
providedIn: 'root'
})
export class UserService {
private readonly STORAGE_KEY = 'user_data';
private state: UserState = {
users: [],
undoStack: [],
redoStack: []
};
private usersSubject = new BehaviorSubject<User[]>([]);
users$ = this.usersSubject.asObservable();
// CRUD Operations with Undo/Redo Support
addUser(user: User): boolean {
if (this.isDuplicate(user)) return false;
this.pushToUndoStack();
user.id = this.getNextId();
this.state.users.push(user);
this.updateState();
return true;
}
// Additional methods for update, delete, undo, redo
}
- Data Grid Component: The main grid component implements the user interface.
@Component({
selector: 'app-user-grid',
template: `
<div class="user-grid-container" [class.dark-theme]="isDarkTheme$ | async">
<div class="header">
<h2>User Management</h2>
<div class="actions">
<app-button (click)="addNewUser()">Add User</app-button>
<app-button (click)="toggleTheme()">Toggle Theme</app-button>
</div>
</div>
<!-- Grid implementation -->
</div>
`
})
export class UserGridComponent implements OnInit {
users$ = this.userService.getUsers();
isDarkTheme$ = this.themeService.isDarkTheme$;
constructor(
private userService: UserService,
private themeService: ThemeService
) {}
}
Advanced Features
Export Functionality
export class ExportService {
exportToExcel(data: User[]) {
const worksheet = XLSX.utils.json_to_sheet(data);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'Users');
XLSX.writeFile(workbook, 'users.xlsx');
}
// Similar methods for PDF and PNG export
}
Loading Placeholders
<ng-container *ngIf="loading$ | async; else userGrid">
<div class="placeholder-grid">
<div class="placeholder-row" *ngFor="let i of [1, 2, 3, 4, 5]">
<!-- Placeholder content -->
</div>
</div>
</ng-container>
Form Validation
export class UserFormComponent {
userForm = this.fb.group({
name: ['', [Validators.required, Validators.minLength(2)]],
email: ['', [Validators.required, Validators.email]],
userName: ['', [Validators.required, Validators.pattern('[a-zA-Z0-9_-]*')]],
// Additional form controls
});
}
Tips
- State Management
- Use BehaviorSubject for reactive state management
- Implement undo/redo using stack data structures
- Persist state changes to localStorage
- Performance Optimization
- Use OnPush change detection strategy
- Implement trackBy functions for ngFor loops
- Lazy load features when possible
- Error Handling
- Implement comprehensive error handling
- Use toast notifications for user feedback
- Log errors appropriately
This User Management System demonstrates several Angular best practices and advanced features. Key takeaways include.
- Proper service architecture for state management
- Implementing complex features like undo/redo
- Creating reusable components
- Managing application themes
- Handling data persistence
- Form validation and error handling
Demo
![Demo]()
![Dark mode]()
![Light mode]()