Skip to content

ImDoode/user-dashboard-angular

Repository files navigation

User Dashboard Angular

Тестовое Angular-приложение с авторизацией и защищенным dashboard-разделом для работы со списком пользователей из DummyJSON API.

Репозиторий: ImDoode/user-dashboard-angular Демо: user-dashboard-angular на GitHub Pages

Проект решает две основные задачи:

  • авторизация пользователя и хранение сессии на клиенте;
  • отображение списка пользователей с фильтрацией, lazy routing, детальной карточкой и догрузкой данных.

Что реализовано

  • standalone Angular-приложение без NgModule-архитектуры;
  • маршрутизация с разделением на публичную и защищенную зоны;
  • guards для доступа авторизованных и неавторизованных пользователей;
  • HTTP interceptor для подстановки токена;
  • страница пользователей с фильтрами, URL-sync и бесконечный скролл;
  • деталка с подробной информацией о пользователе;
  • фасад для логики страницы пользователей;
  • unit-тесты на ключевые сценарии;
  • ESLint и pre-commit hook с автоматической проверкой lint + test.

Стек

  • Angular 21
  • TypeScript
  • RxJS
  • Angular CDK (virtual-scroll)
  • Vitest
  • ESLint
  • Husky

Быстрый старт

Установка зависимостей:

npm install

Запуск dev-сервера:

npm start

Сборка:

npm run build

Проверка тестов:

npm test -- --watch=false

Проверка линтера:

npm run lint

Сборка под GitHub Pages:

npm run build:pages

Если имя репозитория изменится, локально передай свой base href явно:

npm run build -- --base-href /<repo-name>/

Полная локальная проверка качества:

npm run check

GitHub Pages CI/CD

Для проекта настроен workflow .github/workflows/deploy-pages.yml, который:

  • запускается при push в master и вручную через workflow_dispatch;
  • устанавливает зависимости через npm ci;
  • прогоняет npm run check;
  • собирает production-версию Angular-приложения с base href, вычисленным из имени GitHub-репозитория;
  • публикует содержимое dist/user-dashboard-angular/browser в GitHub Pages.

Структура проекта

Основной код находится в src/app.

Ключевые директории:

  • src/app/core — cross-cutting слой: guards, interceptors, модели, базовые сервисы.
  • src/app/features — feature-модули приложения.
  • src/app/features/auth — страница логина.
  • src/app/features/users — список пользователей, фильтры, деталка пользователя, фасад и feature routes.
  • src/app/layouts — layout-компоненты для auth и dashboard зоны.

Внутри users feature структура разделена на:

  • pages — контейнерные page-компоненты;
  • components — переиспользуемые UI-блоки внутри фичи;
  • constants — конфигурация фильтров и служебные константы;
  • utils — чистые функции без Angular-зависимостей.

Маршрутизация

Корневой роутинг описан в src/app/app.routes.ts.

Структура маршрутов:

  • /login — публичная зона под AuthLayoutComponent, доступна только гостям;
  • /dashboard — защищенная зона под DashboardLayoutComponent, доступна только после авторизации;
  • /dashboard/users — список пользователей;
  • /dashboard/users/:id — деталка пользователя как дочерний маршрут.

Почему так:

  • layout-компоненты отделяют каркас страниц от бизнес-логики;
  • guards делают правила доступа явными на уровне роутинга;
  • users feature загружается лениво, что уменьшает размер бандла.

Архитектурные решения

1. Standalone components

Проект использует standalone-подход Angular вместо NgModule.

Почему это выбрано:

  • меньше инфраструктурного кода;
  • проще локально понимать зависимости компонента;
  • лучше сочетается с lazy loading и современной Angular-архитектурой.

2. Feature-first структура

Код сгруппирован по бизнес-фичам, а не по типам файлов.

Почему это выбрано:

  • проще масштабировать проект по сценариям, а не по техническим слоям;
  • изменения внутри одной фичи локализованы;
  • быстрее навигироваться по коду в реальной продуктовой разработке.

3. Фасад для users page

В src/app/features/users/pages/users-page/users-page.facade.ts вынесена orchestration-логика страницы пользователей.

Фасад отвечает за:

  • синхронизацию фильтров с URL;
  • загрузку данных;
  • пересечение результатов фильтрации;
  • пагинацию и бесконечный скролл;
  • состояние загрузки, ошибок и открытой деталки пользователя.

Компонент src/app/features/users/pages/users-page/users-page.component.ts при этом остается тонким UI-слоем.

Почему это выбрано:

  • компонент не перегружен побочными эффектами;
  • состояние и сценарии страницы централизованы;
  • бизнес-логику проще тестировать и рефакторить отдельно от шаблона.

4. Разделение list/detail моделей пользователя

В src/app/core/models/user.models.ts используются разные типы для разных API-контрактов:

  • UserListItem — для списков, поиска и фильтрации;
  • UserDetails — для детальной карточки пользователя.

Почему это выбрано:

  • список и детальная карточка реально используют разные поля;
  • типы отражают контракт API точнее;
  • тестовые моки стали короче и менее шумными;
  • снижается риск опираться на поля, которых нет в конкретном endpoint.

5. Typed select fields

В тех же моделях определены USER_LIST_SELECT_FIELDS и USER_DETAILS_SELECT_FIELDS, которые используются в src/app/core/services/users.service.ts.

Почему это выбрано:

  • список полей select больше не живет отдельной строкой в сервисе;
  • модель и HTTP-контракт синхронизированы на уровне TypeScript;
  • изменение модели сразу подсвечивает возможный разъезд с API-запросом.

6. Сервисный слой и кеширование

src/app/core/services/users.service.ts инкапсулирует HTTP-запросы, сбор всех страниц и кеш для полных списков пользователей.

Почему это выбрано:

  • компоненты и фасады не знают деталей HTTP;
  • повторные фильтры и поиски не создают лишних одинаковых запросов;
  • логика работы с API централизована в одном месте.

7. Сигналы для локального хранения состояни

Локальное состояние в компонентах и фасаде хранится через Angular Signals.

Почему это выбрано:

  • удобно описывать локальное состояние;
  • меньше ручной подписочной логики для представления;
  • хорошо сочетается с OnPush change detection.

RxJS при этом используется там, где он уместен:

  • для HTTP;
  • для реактивной работы с router streams;
  • для композиции async-потоков и фильтрации.

8. Guards и interceptor

src/app/core/guards ограничивают доступ к маршрутам, а src/app/core/interceptors/auth-token.interceptor.ts подставляет токен в запросы.

Почему это выбрано:

  • правила доступа не размазываются по компонентам;
  • HTTP-авторизация не дублируется в каждом запросе;
  • поведение безопасности находится в ожидаемых точках расширения Angular.

Качество и проверка изменений

В проекте настроены базовые quality gates:

  • ESLint для TypeScript-кода;
  • unit-тесты на Vitest;
  • pre-commit hook через Husky.

Перед коммитом выполняется:

npm run check

Это означает, что коммит блокируется, если не проходят:

  • npm run lint
  • npm run test:ci

Возможное TODO:

  • добавить интеграционные тесты на роутинг и guards;
  • добавить e2e тесты для бизнес логики;
  • вынести DTO и доменные модели в отдельные типы, если API начнет усложняться;

Итого

Проект собран как небольшое, но инженерно аккуратное приложение:

  • современный Angular без NgModules;
  • feature-first структура;
  • разделение на представление и фасад для сложной страницы;
  • типизация, привязанная к реальному API;
  • локальные проверки качества кода, достаточные для небольшого проекта.

About

Тестовое Angular-приложение с авторизацией и защищенным dashboard-разделом для работы со списком пользователей из DummyJSON API.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors