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]()