Files
library/apps/frontend/src/app/app.routes.ts
T
hikari 3da648544e
Node.js CI / CI (pull_request) Failing after 1m21s
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 1m22s
feat: implement comprehensive achievement system with 62 achievements
Adds a complete achievement system with gamification features across all user interactions.

**Database & Types:**
- Add UserAchievement model to track user progress and earned achievements
- Add achievement-related fields to User model (achievementPoints, currentStreak, lastStreakCheck)
- Add ACHIEVEMENT_UNLOCKED audit action type
- Define 62 achievements as TypeScript constants across 5 categories

**Achievement Categories:**
- Suggestions (15): First suggestion through ultimate curator milestones
- Likes (12): First like through legendary fan milestones
- Comments (12): First comment through review legend milestones
- Engagement (15): Login streaks and total activity tracking
- Reports (8): Valid reports and accuracy tracking

**Backend Implementation:**
- Create AchievementService with comprehensive checking logic
- Add achievement route with 6 API endpoints
- Integrate achievement checking into all user interaction points:
  - Suggestions (create + accept)
  - Likes (toggle)
  - Comments (all 6 media types)
  - Login streaks
  - Reports (profile + comment)
- Update UserService to include achievement points in profiles

**Frontend Implementation:**
- Create AchievementService for API communication
- Create achievements page showing all 62 achievements with:
  - Category filtering (All, Suggestions, Likes, Comments, Engagement, Reports)
  - Tier-based styling (Bronze, Silver, Gold, Platinum, Diamond)
  - Progress indicators for in-progress achievements
  - Earned date display for completed achievements
- Add "Recent Achievements" section to user profiles
- Add "🏆 Achievements" link to header navigation
- Only show "View All" link on own profile

**Technical Features:**
- Real-time achievement checking on user actions
- Progress tracking to avoid recalculation
- Points system for gamification
- Tier-based gradient styling
- Leaderboard-ready architecture

Resolves #48

Co-Authored-By: Hikari <hikari@nhcarrigan.com>
2026-02-19 22:02:10 -08:00

73 lines
2.3 KiB
TypeScript

import { Route } from '@angular/router';
export const appRoutes: Route[] = [
{
path: '',
loadComponent: () => import('./components/home/home.component').then(m => m.HomeComponent)
},
{
path: 'games',
loadComponent: () => import('./components/games/games-list.component').then(m => m.GamesListComponent)
},
{
path: 'books',
loadComponent: () => import('./components/books/books-list.component').then(m => m.BooksListComponent)
},
{
path: 'music',
loadComponent: () => import('./components/music/music-list.component').then(m => m.MusicListComponent)
},
{
path: 'art',
loadComponent: () => import('./components/art/art-gallery.component').then(m => m.ArtGalleryComponent)
},
{
path: 'shows',
loadComponent: () => import('./components/shows/shows-list.component').then(m => m.ShowsListComponent)
},
{
path: 'manga',
loadComponent: () => import('./components/manga/manga-list.component').then(m => m.MangaListComponent)
},
{
path: 'admin/users',
loadComponent: () => import('./components/admin/admin-users.component').then(m => m.AdminUsersComponent)
},
{
path: 'admin/audit',
loadComponent: () => import('./components/admin/admin-audit.component').then(m => m.AdminAuditComponent)
},
{
path: 'admin/suggestions',
loadComponent: () => import('./components/admin/admin-suggestions.component').then(m => m.AdminSuggestionsComponent)
},
{
path: 'admin/reports',
loadComponent: () => import('./components/admin-reports/admin-reports.component').then(m => m.AdminReportsComponent)
},
{
path: 'my-suggestions',
loadComponent: () => import('./components/my-suggestions/my-suggestions.component').then(m => m.MySuggestionsComponent)
},
{
path: 'my-likes',
loadComponent: () => import('./components/my-likes/my-likes.component').then(m => m.MyLikesComponent)
},
{
path: 'profile/:identifier',
loadComponent: () => import('./components/profile/profile.component').then(m => m.ProfileComponent)
},
{
path: 'settings',
loadComponent: () => import('./components/settings/settings.component').then(m => m.SettingsComponent)
},
{
path: 'achievements',
loadComponent: () => import('./components/achievements/achievements.component').then(m => m.AchievementsComponent)
},
{
path: '**',
redirectTo: ''
}
];