feat: Multiple Features, Accessibility, Security, and UX Improvements #59

Merged
naomi merged 27 commits from feat/polish into main 2026-02-20 01:51:25 -08:00
8 changed files with 642 additions and 608 deletions
Showing only changes of commit 544c090ff3 - Show all commits
@@ -58,6 +58,7 @@ import { ApiService } from '../../services/api.service';
class="dropdown-menu"
role="menu"
aria-label="User menu"
tabindex="-1"
(keydown.escape)="closeDropdown()"
>
<a [routerLink]="['/profile', user.slug || user.id]" class="dropdown-item" role="menuitem" (click)="closeDropdown()">My Profile</a>
File diff suppressed because it is too large Load Diff
+29 -29
View File
@@ -21,50 +21,50 @@ export enum AchievementTier {
}
export interface AchievementRequirements {
count?: number;
rate?: number;
streak?: number;
diversity?: boolean;
count?: number;
rate?: number;
streak?: number;
diversity?: boolean;
uniqueItems?: number;
dayRange?: number;
dayRange?: number;
}
export interface AchievementDefinition {
key: string;
title: string;
description: string;
category: AchievementCategory;
tier: AchievementTier;
icon: string;
points: number;
key: string;
title: string;
description: string;
category: AchievementCategory;
tier: AchievementTier;
icon: string;
points: number;
requirements: AchievementRequirements;
}
export interface UserAchievement {
id: string;
userId: string;
id: string;
userId: string;
achievementKey: string;
progress: number;
earned: boolean;
earnedAt?: Date;
createdAt: Date;
updatedAt: Date;
progress: number;
earned: boolean;
earnedAt?: Date;
createdAt: Date;
updatedAt: Date;
}
export interface AchievementProgress {
definition: AchievementDefinition;
progress: number;
earned: boolean;
earnedAt?: Date;
progress: number;
earned: boolean;
earnedAt?: Date;
}
export interface UserAchievementSummary {
totalPoints: number;
totalEarned: number;
recentAchievements: AchievementProgress[];
progressByCategory: {
totalPoints: number;
totalEarned: number;
recentAchievements: Array<AchievementProgress>;
progressByCategory: Array<{
category: AchievementCategory;
earned: number;
total: number;
}[];
earned: number;
total: number;
}>;
}
+15 -15
View File
@@ -30,39 +30,39 @@ interface BaseActivity {
}
interface SuggestionActivity extends BaseActivity {
type: ActivityType.suggestion;
entityType: string;
type: ActivityType.suggestion;
entityType: string;
suggestionTitle: string;
status: string;
status: string;
}
interface LikeActivity extends BaseActivity {
type: ActivityType.like;
entityType: string;
entityId: string;
type: ActivityType.like;
entityType: string;
entityId: string;
entityTitle: string;
}
interface CommentActivity extends BaseActivity {
type: ActivityType.comment;
entityType: string;
entityId: string;
entityTitle: string;
type: ActivityType.comment;
entityType: string;
entityId: string;
entityTitle: string;
commentPreview: string;
}
interface AchievementActivity extends BaseActivity {
type: ActivityType.achievement;
achievementKey: string;
achievementName: string;
achievementIcon: string;
type: ActivityType.achievement;
achievementKey: string;
achievementName: string;
achievementIcon: string;
achievementPoints: number;
}
type Activity = SuggestionActivity | LikeActivity | CommentActivity | AchievementActivity;
interface ActivityFeedResponse {
activities: Activity[];
activities: Array<Activity>;
total: number;
hasMore: boolean;
}
+3 -3
View File
@@ -34,9 +34,9 @@ interface User {
isAdmin: boolean;
isBanned: boolean;
inDiscord: boolean;
isVip: boolean;
isMod: boolean;
isStaff: boolean;
isVip: boolean;
isMod: boolean;
isStaff: boolean;
}
interface JwtPayload {
+22 -22
View File
@@ -4,34 +4,34 @@
* @author Naomi Carrigan
*/
import { PrimaryBadge } from "./auth.types";
import type { PrimaryBadge } from "./auth.types";
interface CommentUser {
id: string;
username: string;
avatar?: string;
id: string;
username: string;
avatar?: string;
primaryBadge?: PrimaryBadge;
inDiscord?: boolean;
isVip?: boolean;
isMod?: boolean;
isStaff?: boolean;
inDiscord?: boolean;
isVip?: boolean;
isMod?: boolean;
isStaff?: boolean;
}
interface Comment {
id: string;
content: string;
rawContent?: string;
userId: string;
user: CommentUser;
gameId?: string;
bookId?: string;
musicId?: string;
artId?: string;
showId?: string;
mangaId?: string;
hasPendingReports?: boolean;
createdAt: Date;
updatedAt: Date;
id: string;
content: string;
rawContent?: string;
userId: string;
user: CommentUser;
gameId?: string;
bookId?: string;
musicId?: string;
artId?: string;
showId?: string;
mangaId?: string;
hasPendingReports?: boolean;
createdAt: Date;
updatedAt: Date;
}
interface CreateCommentDto {
+20 -20
View File
@@ -5,21 +5,21 @@
*/
interface LeaderboardUser {
id: string;
username: string;
slug: string | null;
avatar: string | null;
id: string;
username: string;
slug: string | null;
avatar: string | null;
primaryBadge: string | null;
isVip: boolean;
isMod: boolean;
isStaff: boolean;
createdAt: Date;
isVip: boolean;
isMod: boolean;
isStaff: boolean;
createdAt: Date;
}
interface SuggestionsLeaderboard extends LeaderboardUser {
totalSuggestions: number;
totalSuggestions: number;
acceptedSuggestions: number;
acceptanceRate: number;
acceptanceRate: number;
}
interface LikesLeaderboard extends LeaderboardUser {
@@ -31,20 +31,20 @@ interface CommentsLeaderboard extends LeaderboardUser {
}
interface OverallLeaderboard extends LeaderboardUser {
totalSuggestions: number;
totalLikes: number;
totalComments: number;
achievementCount: number;
totalSuggestions: number;
totalLikes: number;
totalComments: number;
achievementCount: number;
achievementPoints: number;
currentStreak: number;
diversityScore: number;
currentStreak: number;
diversityScore: number;
}
interface LeaderboardResponse {
topSuggestions: SuggestionsLeaderboard[];
topLikes: LikesLeaderboard[];
topComments: CommentsLeaderboard[];
topOverall: OverallLeaderboard[];
topSuggestions: Array<SuggestionsLeaderboard>;
topLikes: Array<LikesLeaderboard>;
topComments: Array<CommentsLeaderboard>;
topOverall: Array<OverallLeaderboard>;
}
export {
+3 -3
View File
@@ -74,10 +74,10 @@ export interface CommentReport {
export interface CommentReportWithDetails extends CommentReport {
reportedComment: {
id: string;
content: string;
id: string;
content: string;
rawContent?: string;
userId: string;
userId: string;
user: {
id: string;
username: string;