Feature-Rich User Management System in Angular

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

  1. Project Overview
  2. Architecture and Design
  3. Core Features Implementation
  4. Services Implementation
  5. Component Development
  6. Advanced Features
  7. 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

  1. State Management
    • Use BehaviorSubject for reactive state management
    • Implement undo/redo using stack data structures
    • Persist state changes to localStorage
  2. Performance Optimization
    • Use OnPush change detection strategy
    • Implement trackBy functions for ngFor loops
    • Lazy load features when possible
  3. 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.

  1. Proper service architecture for state management
  2. Implementing complex features like undo/redo
  3. Creating reusable components
  4. Managing application themes
  5. Handling data persistence
  6. Form validation and error handling

Demo

Demo

Dark mode

Light mode

Up Next
    Ebook Download
    View all
    Learn
    View all