diff --git a/apps/frontend/src/app/components/header/header.component.ts b/apps/frontend/src/app/components/header/header.component.ts index 7d35d54..ba10b71 100644 --- a/apps/frontend/src/app/components/header/header.component.ts +++ b/apps/frontend/src/app/components/header/header.component.ts @@ -58,6 +58,7 @@ import { ApiService } from '../../services/api.service'; class="dropdown-menu" role="menu" aria-label="User menu" + tabindex="-1" (keydown.escape)="closeDropdown()" > My Profile diff --git a/shared-types/src/lib/achievement.constants.ts b/shared-types/src/lib/achievement.constants.ts index 63b3fe7..fcbf485 100644 --- a/shared-types/src/lib/achievement.constants.ts +++ b/shared-types/src/lib/achievement.constants.ts @@ -5,72 +5,178 @@ */ import { AchievementCategory, - AchievementDefinition, + type AchievementDefinition, AchievementTier, } from "./achievement.types"; export const ACHIEVEMENTS: Record = { - // ========== SUGGESTION ACHIEVEMENTS (15) ========== - suggestion_first_steps: { - key: "suggestion_first_steps", - title: "First Steps", - description: "Submit your first 10 suggestions to the library", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Bronze, - icon: "🌱", - points: 50, - requirements: { count: 10 }, + + suggestion_approved: { + category: AchievementCategory.Suggestion, + description: "Have your first suggestion accepted", + icon: "✅", + key: "suggestion_approved", + points: 50, + requirements: { count: 1 }, + title: "Approved!", + tier: AchievementTier.Bronze, }, + suggestion_contributor: { - key: "suggestion_contributor", - title: "Contributor", - description: "Submit 50 suggestions to the library", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Silver, - icon: "📝", - points: 100, + category: AchievementCategory.Suggestion, + description: "Submit 50 suggestions to the library", + icon: "📝", + key: "suggestion_contributor", + points: 100, requirements: { count: 50 }, + tier: AchievementTier.Silver, + title: "Contributor", }, + suggestion_dedicated: { - key: "suggestion_dedicated", - title: "Dedicated", - description: "Submit 100 suggestions to the library", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Gold, - icon: "⭐", - points: 250, + category: AchievementCategory.Suggestion, + description: "Submit 100 suggestions to the library", + icon: "⭐", + key: "suggestion_dedicated", + points: 250, requirements: { count: 100 }, + tier: AchievementTier.Gold, + title: "Dedicated", }, - suggestion_master: { - key: "suggestion_master", - title: "Master Curator", - description: "Submit 250 suggestions to the library", - category: AchievementCategory.Suggestion, + + suggestion_acceptance_100: { + key: "suggestion_acceptance_100", + description: "Achieve 100% acceptance rate (minimum 10 suggestions)", + title: "Perfect Record", + category: AchievementCategory.Suggestion, + icon: "✨", tier: AchievementTier.Platinum, - icon: "💎", - points: 500, - requirements: { count: 250 }, + points: 500, + requirements: { count: 10, rate: 1.0 }, + }, + // ========== SUGGESTION ACHIEVEMENTS (15) ========== +suggestion_first_steps: { + category: AchievementCategory.Suggestion, + description: "Submit your first 10 suggestions to the library", + icon: "🌱", + key: "suggestion_first_steps", + points: 50, + requirements: { count: 10 }, + tier: AchievementTier.Bronze, + title: "First Steps", + }, + suggestion_acceptance_75: { + description: "Maintain a 75%+ acceptance rate (minimum 20 suggestions)", + key: "suggestion_acceptance_75", + category: AchievementCategory.Suggestion, + title: "Quality Over Quantity", + icon: "🎯", + points: 300, + tier: AchievementTier.Gold, + requirements: { count: 20, rate: 0.75 }, }, suggestion_legend: { - key: "suggestion_legend", - title: "Legend", - description: "Submit 500 suggestions to the library", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Diamond, - icon: "👑", - points: 1000, + category: AchievementCategory.Suggestion, + description: "Submit 500 suggestions to the library", + icon: "👑", + key: "suggestion_legend", + points: 1000, requirements: { count: 500 }, + tier: AchievementTier.Diamond, + title: "Legend", }, - suggestion_approved: { - key: "suggestion_approved", - title: "Approved!", - description: "Have your first suggestion accepted", - category: AchievementCategory.Suggestion, + like_enthusiast: { + key: "like_enthusiast", + description: "Like 25 items in the library", + title: "Enthusiast", + category: AchievementCategory.Like, + icon: "💕", tier: AchievementTier.Bronze, - icon: "✅", - points: 50, - requirements: { count: 1 }, + points: 50, + requirements: { count: 25 }, }, + suggestion_master: { + category: AchievementCategory.Suggestion, + description: "Submit 250 suggestions to the library", + icon: "💎", + key: "suggestion_master", + points: 500, + requirements: { count: 250 }, + title: "Master Curator", + tier: AchievementTier.Platinum, + }, + like_fan: { + description: "Like 100 items in the library", + key: "like_fan", + category: AchievementCategory.Like, + title: "Fan", + icon: "💖", + points: 100, + tier: AchievementTier.Silver, + requirements: { count: 100 }, + }, + suggestion_quality_10: { + category: AchievementCategory.Suggestion, + description: "Have 10 suggestions accepted", + icon: "🏆", + key: "suggestion_quality_10", + points: 200, + requirements: { count: 10 }, + title: "Elite Curator", + tier: AchievementTier.Gold, + }, + suggestion_enthusiast: { + description: "Submit 5 suggestions in one day", + category: AchievementCategory.Suggestion, + key: "suggestion_enthusiast", + icon: "🔥", + title: "Suggestion Enthusiast", + points: 150, + requirements: { count: 5, dayRange: 1 }, + tier: AchievementTier.Silver, + }, + suggestion_quality_100: { + description: "Have 100 suggestions accepted", + key: "suggestion_quality_100", + category: AchievementCategory.Suggestion, + title: "Ultimate Curator", + icon: "👸", + points: 1500, + tier: AchievementTier.Diamond, + requirements: { count: 100 }, + }, + like_book_lover: { + description: "Like 50 books", + key: "like_book_lover", + category: AchievementCategory.Like, + title: "Book Lover", + icon: "📚", + points: 100, + tier: AchievementTier.Silver, + requirements: { count: 50 }, + }, + suggestion_quality_25: { + description: "Have 25 suggestions accepted", + key: "suggestion_quality_25", + category: AchievementCategory.Suggestion, + title: "Master Curator", + icon: "💫", + points: 400, + tier: AchievementTier.Platinum, + requirements: { count: 25 }, + }, + + like_cinephile: { + description: "Like 50 shows/films", + key: "like_cinephile", + category: AchievementCategory.Like, + title: "Cinephile", + icon: "🎬", + points: 100, + tier: AchievementTier.Silver, + requirements: { count: 50 }, + }, + suggestion_quality_5: { key: "suggestion_quality_5", title: "Quality Curator", @@ -81,27 +187,32 @@ export const ACHIEVEMENTS: Record = { points: 100, requirements: { count: 5 }, }, - suggestion_quality_10: { - key: "suggestion_quality_10", - title: "Elite Curator", - description: "Have 10 suggestions accepted", - category: AchievementCategory.Suggestion, + + like_diverse: { + description: "Like items from all 6 media types", + key: "like_diverse", + category: AchievementCategory.Like, + title: "Diverse Taste", + icon: "🌍", + points: 200, tier: AchievementTier.Gold, - icon: "🏆", - points: 200, - requirements: { count: 10 }, + requirements: { diversity: true }, }, - suggestion_quality_25: { - key: "suggestion_quality_25", - title: "Master Curator", - description: "Have 25 suggestions accepted", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Platinum, - icon: "💫", - points: 400, - requirements: { count: 25 }, + + // ========== COMMENT ACHIEVEMENTS (12) ========== +comment_first: { + key: "comment_first", + description: "Leave your first comment in the library", + title: "First Thoughts", + category: AchievementCategory.Comment, + icon: "💬", + tier: AchievementTier.Bronze, + points: 25, + requirements: { count: 1 }, }, - suggestion_quality_50: { + + +suggestion_quality_50: { key: "suggestion_quality_50", title: "Grand Master", description: "Have 50 suggestions accepted", @@ -111,167 +222,176 @@ export const ACHIEVEMENTS: Record = { points: 700, requirements: { count: 50 }, }, - suggestion_quality_100: { - key: "suggestion_quality_100", - title: "Ultimate Curator", - description: "Have 100 suggestions accepted", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Diamond, - icon: "👸", - points: 1500, - requirements: { count: 100 }, - }, - suggestion_acceptance_75: { - key: "suggestion_acceptance_75", - title: "Quality Over Quantity", - description: "Maintain a 75%+ acceptance rate (minimum 20 suggestions)", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Gold, - icon: "🎯", - points: 300, - requirements: { rate: 0.75, count: 20 }, - }, - suggestion_acceptance_100: { - key: "suggestion_acceptance_100", - title: "Perfect Record", - description: "Achieve 100% acceptance rate (minimum 10 suggestions)", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Platinum, - icon: "✨", - points: 500, - requirements: { rate: 1.0, count: 10 }, + + comment_critic: { + key: "comment_critic", + description: "Leave 50 comments in the library", + title: "Critic", + category: AchievementCategory.Comment, + icon: "🗣️", + tier: AchievementTier.Silver, + points: 100, + requirements: { count: 50 }, }, + + suggestion_renaissance: { - key: "suggestion_renaissance", - title: "Renaissance Person", description: "Submit accepted suggestions across all 6 media types", - category: AchievementCategory.Suggestion, + key: "suggestion_renaissance", + category: AchievementCategory.Suggestion, + title: "Renaissance Person", + icon: "🌈", + points: 400, tier: AchievementTier.Gold, - icon: "🌈", - points: 400, requirements: { diversity: true }, }, - suggestion_enthusiast: { - key: "suggestion_enthusiast", - title: "Suggestion Enthusiast", - description: "Submit 5 suggestions in one day", - category: AchievementCategory.Suggestion, - tier: AchievementTier.Silver, - icon: "🔥", - points: 150, - requirements: { count: 5, dayRange: 1 }, + + +comment_expert: { + description: "Leave 100 comments in the library", + key: "comment_expert", + category: AchievementCategory.Comment, + title: "Expert Critic", + icon: "🎭", + points: 250, + tier: AchievementTier.Gold, + requirements: { count: 100 }, }, // ========== LIKE ACHIEVEMENTS (12) ========== - like_first: { - key: "like_first", - title: "First Like", +like_first: { description: "Like your first item in the library", - category: AchievementCategory.Like, + key: "like_first", + category: AchievementCategory.Like, + title: "First Like", + icon: "❤️", + points: 25, tier: AchievementTier.Bronze, - icon: "❤️", - points: 25, requirements: { count: 1 }, }, - like_enthusiast: { - key: "like_enthusiast", - title: "Enthusiast", - description: "Like 25 items in the library", - category: AchievementCategory.Like, - tier: AchievementTier.Bronze, - icon: "💕", - points: 50, - requirements: { count: 25 }, - }, - like_fan: { - key: "like_fan", - title: "Fan", - description: "Like 100 items in the library", - category: AchievementCategory.Like, - tier: AchievementTier.Silver, - icon: "💖", - points: 100, - requirements: { count: 100 }, - }, - like_super_fan: { - key: "like_super_fan", - title: "Super Fan", - description: "Like 250 items in the library", - category: AchievementCategory.Like, - tier: AchievementTier.Gold, - icon: "💝", - points: 250, - requirements: { count: 250 }, - }, - like_mega_fan: { - key: "like_mega_fan", - title: "Mega Fan", - description: "Like 500 items in the library", - category: AchievementCategory.Like, - tier: AchievementTier.Platinum, - icon: "💗", - points: 500, + + comment_legend: { + description: "Leave 500 comments in the library", + key: "comment_legend", + category: AchievementCategory.Comment, + title: "Review Legend", + icon: "🏅", + points: 1000, + tier: AchievementTier.Diamond, requirements: { count: 500 }, }, + + like_mega_fan: { + description: "Like 500 items in the library", + key: "like_mega_fan", + category: AchievementCategory.Like, + title: "Mega Fan", + icon: "💗", + points: 500, + tier: AchievementTier.Platinum, + requirements: { count: 500 }, + }, + + comment_detailed: { + description: "Write 10 comments with 500+ characters", + category: AchievementCategory.Comment, + key: "comment_detailed", + icon: "📝", + title: "Detailed Critic", + points: 150, + requirements: { count: 10 }, + tier: AchievementTier.Silver, + }, + + like_super_fan: { + key: "like_super_fan", + description: "Like 250 items in the library", + title: "Super Fan", + category: AchievementCategory.Like, + icon: "💝", + tier: AchievementTier.Gold, + points: 250, + requirements: { count: 250 }, + }, + comment_essay: { + category: AchievementCategory.Comment, + description: "Write 5 comments with 1000+ characters", + icon: "📄", + key: "comment_essay", + points: 300, + title: "Essay Writer", + requirements: { count: 5 }, + tier: AchievementTier.Gold, + }, like_legendary: { - key: "like_legendary", - title: "Legendary Fan", + key: "like_legendary", description: "Like 1000 items in the library", - category: AchievementCategory.Like, - tier: AchievementTier.Diamond, + title: "Legendary Fan", + category: AchievementCategory.Like, icon: "💞", - points: 1000, + tier: AchievementTier.Diamond, + points: 1000, requirements: { count: 1000 }, }, - like_book_lover: { - key: "like_book_lover", - title: "Book Lover", - description: "Like 50 books", - category: AchievementCategory.Like, - tier: AchievementTier.Silver, - icon: "📚", - points: 100, - requirements: { count: 50 }, + comment_diverse: { + description: "Comment on all 6 media types", + category: AchievementCategory.Comment, + key: "comment_diverse", + icon: "🎨", + title: "Well-Rounded Critic", + points: 250, + requirements: { diversity: true }, + tier: AchievementTier.Gold, }, like_gamer: { - key: "like_gamer", - title: "Gamer", + key: "like_gamer", description: "Like 50 games", - category: AchievementCategory.Like, - tier: AchievementTier.Silver, + title: "Gamer", + category: AchievementCategory.Like, icon: "🎮", - points: 100, + tier: AchievementTier.Silver, + points: 100, requirements: { count: 50 }, }, - like_cinephile: { - key: "like_cinephile", - title: "Cinephile", - description: "Like 50 shows/films", - category: AchievementCategory.Like, - tier: AchievementTier.Silver, - icon: "🎬", - points: 100, - requirements: { count: 50 }, + comment_first_to_comment: { + category: AchievementCategory.Comment, + description: "Be the first to comment on 10 items", + icon: "🗨️", + key: "comment_first_to_comment", + points: 200, + title: "Discussion Starter", + requirements: { count: 10 }, + tier: AchievementTier.Silver, }, like_music: { - key: "like_music", - title: "Music Enthusiast", + key: "like_music", description: "Like 50 music albums", - category: AchievementCategory.Like, - tier: AchievementTier.Silver, + title: "Music Enthusiast", + category: AchievementCategory.Like, icon: "🎵", - points: 100, + tier: AchievementTier.Silver, + points: 100, requirements: { count: 50 }, }, - like_diverse: { - key: "like_diverse", - title: "Diverse Taste", - description: "Like items from all 6 media types", - category: AchievementCategory.Like, - tier: AchievementTier.Gold, - icon: "🌍", - points: 200, - requirements: { diversity: true }, + comment_master: { + description: "Leave 250 comments in the library", + category: AchievementCategory.Comment, + key: "comment_master", + icon: "📖", + title: "Master Reviewer", + points: 500, + requirements: { count: 250 }, + tier: AchievementTier.Platinum, + }, + comment_novel: { + category: AchievementCategory.Comment, + description: "Write 3 comments with 2000+ characters", + icon: "📚", + key: "comment_novel", + points: 500, + requirements: { count: 3 }, + tier: AchievementTier.Platinum, + title: "Novel Writer", }, like_binge: { key: "like_binge", @@ -283,131 +403,138 @@ export const ACHIEVEMENTS: Record = { points: 150, requirements: { count: 20, dayRange: 1 }, }, - - // ========== COMMENT ACHIEVEMENTS (12) ========== - comment_first: { - key: "comment_first", - title: "First Thoughts", - description: "Leave your first comment in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Bronze, - icon: "💬", - points: 25, - requirements: { count: 1 }, - }, comment_reviewer: { - key: "comment_reviewer", - title: "Reviewer", + key: "comment_reviewer", description: "Leave 10 comments in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Bronze, + title: "Reviewer", + category: AchievementCategory.Comment, icon: "✍️", - points: 50, + tier: AchievementTier.Bronze, + points: 50, requirements: { count: 10 }, }, - comment_critic: { - key: "comment_critic", - title: "Critic", - description: "Leave 50 comments in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Silver, - icon: "🗣️", - points: 100, - requirements: { count: 50 }, - }, - comment_expert: { - key: "comment_expert", - title: "Expert Critic", - description: "Leave 100 comments in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Gold, - icon: "🎭", - points: 250, - requirements: { count: 100 }, - }, - comment_master: { - key: "comment_master", - title: "Master Reviewer", - description: "Leave 250 comments in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Platinum, - icon: "📖", - points: 500, - requirements: { count: 250 }, - }, - comment_legend: { - key: "comment_legend", - title: "Review Legend", - description: "Leave 500 comments in the library", - category: AchievementCategory.Comment, - tier: AchievementTier.Diamond, - icon: "🏅", - points: 1000, - requirements: { count: 500 }, - }, - comment_detailed: { - key: "comment_detailed", - title: "Detailed Critic", - description: "Write 10 comments with 500+ characters", - category: AchievementCategory.Comment, - tier: AchievementTier.Silver, - icon: "📝", - points: 150, - requirements: { count: 10 }, - }, - comment_essay: { - key: "comment_essay", - title: "Essay Writer", - description: "Write 5 comments with 1000+ characters", - category: AchievementCategory.Comment, - tier: AchievementTier.Gold, - icon: "📄", - points: 300, - requirements: { count: 5 }, - }, - comment_novel: { - key: "comment_novel", - title: "Novel Writer", - description: "Write 3 comments with 2000+ characters", - category: AchievementCategory.Comment, - tier: AchievementTier.Platinum, - icon: "📚", - points: 500, - requirements: { count: 3 }, - }, comment_thoughtful: { - key: "comment_thoughtful", - title: "Thoughtful Reviewer", - description: "Comment on 50 different items", - category: AchievementCategory.Comment, - tier: AchievementTier.Silver, - icon: "💭", - points: 150, + category: AchievementCategory.Comment, + description: "Comment on 50 different items", + icon: "💭", + key: "comment_thoughtful", + points: 150, requirements: { uniqueItems: 50 }, - }, - comment_diverse: { - key: "comment_diverse", - title: "Well-Rounded Critic", - description: "Comment on all 6 media types", - category: AchievementCategory.Comment, - tier: AchievementTier.Gold, - icon: "🎨", - points: 250, - requirements: { diversity: true }, - }, - comment_first_to_comment: { - key: "comment_first_to_comment", - title: "Discussion Starter", - description: "Be the first to comment on 10 items", - category: AchievementCategory.Comment, - tier: AchievementTier.Silver, - icon: "🗨️", - points: 200, - requirements: { count: 10 }, + tier: AchievementTier.Silver, + title: "Thoughtful Reviewer", }, + engagement_early_adopter: { + description: "Be among the first 10 users to join", + category: AchievementCategory.Engagement, + key: "engagement_early_adopter", + icon: "🌟", + title: "Early Adopter", + points: 1000, + requirements: {}, + tier: AchievementTier.Diamond, + }, + + engagement_power_user: { + description: "Achieve Triple Threat 10 times", + category: AchievementCategory.Engagement, + key: "engagement_power_user", + icon: "💫", + title: "Power User", + points: 750, + requirements: { count: 10 }, + tier: AchievementTier.Platinum, + }, + + engagement_founding_100: { + category: AchievementCategory.Engagement, + description: "Be among the first 100 users to join", + icon: "🎖️", + key: "engagement_founding_100", + points: 500, + title: "Founding Member", + requirements: {}, + tier: AchievementTier.Gold, + }, + + engagement_streak_100: { + category: AchievementCategory.Engagement, + description: "Login for 100 days in a row", + icon: "🏆", + key: "engagement_streak_100", + points: 500, + title: "Committed", + requirements: { streak: 100 }, + tier: AchievementTier.Gold, + }, + + engagement_founding_1000: { + category: AchievementCategory.Engagement, + description: "Be among the first 1000 users to join", + icon: "🚀", + key: "engagement_founding_1000", + points: 200, + requirements: {}, + title: "Pioneer", + tier: AchievementTier.Silver, + }, + + engagement_streak_30: { + description: "Login for 30 days in a row", + category: AchievementCategory.Engagement, + key: "engagement_streak_30", + icon: "💪", + title: "Dedicated", + points: 250, + requirements: { streak: 30 }, + tier: AchievementTier.Silver, + }, + + engagement_streak_365: { + category: AchievementCategory.Engagement, + description: "Login for 365 days in a row", + icon: "⚡", + key: "engagement_streak_365", + points: 2000, + title: "Unstoppable", + requirements: { streak: 365 }, + tier: AchievementTier.Diamond, + }, + + engagement_streak_7: { + description: "Login for 7 days in a row", + key: "engagement_streak_7", + category: AchievementCategory.Engagement, + title: "Daily Visitor", + icon: "🔥", + points: 100, + tier: AchievementTier.Bronze, + requirements: { streak: 7 }, + }, + + engagement_triple_threat: { + category: AchievementCategory.Engagement, + description: "Submit a suggestion, like an item, and leave a comment in the same day", + icon: "🎯", + key: "engagement_triple_threat", + points: 200, + requirements: { dayRange: 1 }, + title: "Triple Threat", + tier: AchievementTier.Silver, + }, + +engagement_veteran_180: { + category: AchievementCategory.Engagement, + description: "Have an account for 6 months", + icon: "📅", + key: "engagement_veteran_180", + points: 150, + requirements: { dayRange: 180 }, + tier: AchievementTier.Silver, + title: "Seasoned", + }, // ========== ENGAGEMENT ACHIEVEMENTS (15) ========== - engagement_welcome: { +engagement_welcome: { key: "engagement_welcome", title: "Welcome!", description: "Complete your profile setup", @@ -417,227 +544,133 @@ export const ACHIEVEMENTS: Record = { points: 25, requirements: {}, }, - engagement_streak_7: { - key: "engagement_streak_7", - title: "Daily Visitor", - description: "Login for 7 days in a row", - category: AchievementCategory.Engagement, - tier: AchievementTier.Bronze, - icon: "🔥", - points: 100, - requirements: { streak: 7 }, - }, - engagement_streak_30: { - key: "engagement_streak_30", - title: "Dedicated", - description: "Login for 30 days in a row", - category: AchievementCategory.Engagement, - tier: AchievementTier.Silver, - icon: "💪", - points: 250, - requirements: { streak: 30 }, - }, - engagement_streak_100: { - key: "engagement_streak_100", - title: "Committed", - description: "Login for 100 days in a row", - category: AchievementCategory.Engagement, - tier: AchievementTier.Gold, - icon: "🏆", - points: 500, - requirements: { streak: 100 }, - }, - engagement_streak_365: { - key: "engagement_streak_365", - title: "Unstoppable", - description: "Login for 365 days in a row", - category: AchievementCategory.Engagement, - tier: AchievementTier.Diamond, - icon: "⚡", - points: 2000, - requirements: { streak: 365 }, - }, - engagement_triple_threat: { - key: "engagement_triple_threat", - title: "Triple Threat", - description: "Submit a suggestion, like an item, and leave a comment in the same day", - category: AchievementCategory.Engagement, - tier: AchievementTier.Silver, - icon: "🎯", - points: 200, - requirements: { dayRange: 1 }, - }, - engagement_power_user: { - key: "engagement_power_user", - title: "Power User", - description: "Achieve Triple Threat 10 times", - category: AchievementCategory.Engagement, - tier: AchievementTier.Platinum, - icon: "💫", - points: 750, - requirements: { count: 10 }, - }, - engagement_early_adopter: { - key: "engagement_early_adopter", - title: "Early Adopter", - description: "Be among the first 10 users to join", - category: AchievementCategory.Engagement, - tier: AchievementTier.Diamond, - icon: "🌟", - points: 1000, - requirements: {}, - }, - engagement_founding_100: { - key: "engagement_founding_100", - title: "Founding Member", - description: "Be among the first 100 users to join", - category: AchievementCategory.Engagement, - tier: AchievementTier.Gold, - icon: "🎖️", - points: 500, - requirements: {}, - }, - engagement_founding_1000: { - key: "engagement_founding_1000", - title: "Pioneer", - description: "Be among the first 1000 users to join", - category: AchievementCategory.Engagement, - tier: AchievementTier.Silver, - icon: "🚀", - points: 200, - requirements: {}, + engagement_veteran_1825: { + category: AchievementCategory.Engagement, + description: "Have an account for 5 years", + icon: "🌠", + key: "engagement_veteran_1825", + points: 1500, + requirements: { dayRange: 1825 }, + tier: AchievementTier.Diamond, + title: "Legend", }, engagement_veteran_30: { - key: "engagement_veteran_30", - title: "Veteran", - description: "Have an account for 30 days", - category: AchievementCategory.Engagement, - tier: AchievementTier.Bronze, - icon: "⏰", - points: 50, + category: AchievementCategory.Engagement, + description: "Have an account for 30 days", + icon: "⏰", + key: "engagement_veteran_30", + points: 50, requirements: { dayRange: 30 }, - }, - engagement_veteran_180: { - key: "engagement_veteran_180", - title: "Seasoned", - description: "Have an account for 6 months", - category: AchievementCategory.Engagement, - tier: AchievementTier.Silver, - icon: "📅", - points: 150, - requirements: { dayRange: 180 }, + tier: AchievementTier.Bronze, + title: "Veteran", }, engagement_veteran_365: { - key: "engagement_veteran_365", - title: "Longstanding", - description: "Have an account for 1 year", - category: AchievementCategory.Engagement, - tier: AchievementTier.Gold, - icon: "🎂", - points: 300, + category: AchievementCategory.Engagement, + description: "Have an account for 1 year", + icon: "🎂", + key: "engagement_veteran_365", + points: 300, requirements: { dayRange: 365 }, + tier: AchievementTier.Gold, + title: "Longstanding", }, engagement_veteran_730: { - key: "engagement_veteran_730", - title: "Elder", - description: "Have an account for 2 years", - category: AchievementCategory.Engagement, - tier: AchievementTier.Platinum, - icon: "🗓️", - points: 600, + category: AchievementCategory.Engagement, + description: "Have an account for 2 years", + icon: "🗓️", + key: "engagement_veteran_730", + points: 600, requirements: { dayRange: 730 }, - }, - engagement_veteran_1825: { - key: "engagement_veteran_1825", - title: "Legend", - description: "Have an account for 5 years", - category: AchievementCategory.Engagement, - tier: AchievementTier.Diamond, - icon: "🌠", - points: 1500, - requirements: { dayRange: 1825 }, + tier: AchievementTier.Platinum, + title: "Elder", }, + report_accuracy_80: { + category: AchievementCategory.Report, + description: "Maintain 80%+ ACTION_TAKEN rate (minimum 10 reports)", + icon: "🎯", + key: "report_accuracy_80", + points: 300, + requirements: { count: 10, rate: 0.8 }, + tier: AchievementTier.Gold, + title: "Sharp Eye", + }, + + report_accuracy_90: { + category: AchievementCategory.Report, + description: "Maintain 90%+ ACTION_TAKEN rate (minimum 10 reports)", + icon: "🦅", + key: "report_accuracy_90", + points: 500, + requirements: { count: 10, rate: 0.9 }, + tier: AchievementTier.Platinum, + title: "Eagle Eye", + }, + + report_consistent: { + category: AchievementCategory.Report, + description: "Submit at least one report weekly for 4 weeks", + icon: "📆", + key: "report_consistent", + points: 200, + requirements: { count: 4 }, + tier: AchievementTier.Silver, + title: "Consistent Guardian", + }, + + report_guardian: { + category: AchievementCategory.Report, + description: "Have 5 reports result in ACTION_TAKEN", + icon: "🛡️", + key: "report_guardian", + points: 100, + requirements: { count: 5 }, + tier: AchievementTier.Silver, + title: "Guardian", + }, + + report_protector: { + category: AchievementCategory.Report, + description: "Have 10 reports result in ACTION_TAKEN", + icon: "⚔️", + key: "report_protector", + points: 250, + requirements: { count: 10 }, + tier: AchievementTier.Gold, + title: "Protector", + }, + + report_vigilant: { + category: AchievementCategory.Report, + description: "Have 25 reports result in ACTION_TAKEN", + icon: "🔰", + key: "report_vigilant", + points: 500, + requirements: { count: 25 }, + tier: AchievementTier.Platinum, + title: "Vigilant Protector", + }, + + report_volume: { + category: AchievementCategory.Report, + description: "Submit 50 reports (any status)", + icon: "📝", + key: "report_volume", + points: 150, + requirements: { count: 50 }, + tier: AchievementTier.Silver, + title: "Dedicated Reporter", + }, // ========== REPORT ACHIEVEMENTS (8) ========== report_watchful: { - key: "report_watchful", + description: "Submit your first valid report (ACTION_TAKEN)", + category: AchievementCategory.Report, + key: "report_watchful", + icon: "👀", title: "Watchful Eye", - description: "Submit your first valid report (ACTION_TAKEN)", - category: AchievementCategory.Report, - tier: AchievementTier.Bronze, - icon: "👀", - points: 50, + points: 50, requirements: { count: 1 }, - }, - report_guardian: { - key: "report_guardian", - title: "Guardian", - description: "Have 5 reports result in ACTION_TAKEN", - category: AchievementCategory.Report, - tier: AchievementTier.Silver, - icon: "🛡️", - points: 100, - requirements: { count: 5 }, - }, - report_protector: { - key: "report_protector", - title: "Protector", - description: "Have 10 reports result in ACTION_TAKEN", - category: AchievementCategory.Report, - tier: AchievementTier.Gold, - icon: "⚔️", - points: 250, - requirements: { count: 10 }, - }, - report_vigilant: { - key: "report_vigilant", - title: "Vigilant Protector", - description: "Have 25 reports result in ACTION_TAKEN", - category: AchievementCategory.Report, - tier: AchievementTier.Platinum, - icon: "🔰", - points: 500, - requirements: { count: 25 }, - }, - report_accuracy_80: { - key: "report_accuracy_80", - title: "Sharp Eye", - description: "Maintain 80%+ ACTION_TAKEN rate (minimum 10 reports)", - category: AchievementCategory.Report, - tier: AchievementTier.Gold, - icon: "🎯", - points: 300, - requirements: { rate: 0.8, count: 10 }, - }, - report_accuracy_90: { - key: "report_accuracy_90", - title: "Eagle Eye", - description: "Maintain 90%+ ACTION_TAKEN rate (minimum 10 reports)", - category: AchievementCategory.Report, - tier: AchievementTier.Platinum, - icon: "🦅", - points: 500, - requirements: { rate: 0.9, count: 10 }, - }, - report_consistent: { - key: "report_consistent", - title: "Consistent Guardian", - description: "Submit at least one report weekly for 4 weeks", - category: AchievementCategory.Report, - tier: AchievementTier.Silver, - icon: "📆", - points: 200, - requirements: { count: 4 }, - }, - report_volume: { - key: "report_volume", - title: "Dedicated Reporter", - description: "Submit 50 reports (any status)", - category: AchievementCategory.Report, - tier: AchievementTier.Silver, - icon: "📝", - points: 150, - requirements: { count: 50 }, + tier: AchievementTier.Bronze, }, }; diff --git a/shared-types/src/lib/achievement.types.ts b/shared-types/src/lib/achievement.types.ts index 06968b7..7d08de0 100644 --- a/shared-types/src/lib/achievement.types.ts +++ b/shared-types/src/lib/achievement.types.ts @@ -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; + progressByCategory: Array<{ category: AchievementCategory; - earned: number; - total: number; - }[]; + earned: number; + total: number; + }>; } diff --git a/shared-types/src/lib/activity.types.ts b/shared-types/src/lib/activity.types.ts index b247828..8882970 100644 --- a/shared-types/src/lib/activity.types.ts +++ b/shared-types/src/lib/activity.types.ts @@ -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; total: number; hasMore: boolean; } diff --git a/shared-types/src/lib/auth.types.ts b/shared-types/src/lib/auth.types.ts index 59c9183..8fda2c2 100644 --- a/shared-types/src/lib/auth.types.ts +++ b/shared-types/src/lib/auth.types.ts @@ -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 { diff --git a/shared-types/src/lib/comment.types.ts b/shared-types/src/lib/comment.types.ts index 212e2ed..b5ba1b8 100644 --- a/shared-types/src/lib/comment.types.ts +++ b/shared-types/src/lib/comment.types.ts @@ -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 { diff --git a/shared-types/src/lib/leaderboard.types.ts b/shared-types/src/lib/leaderboard.types.ts index 3140d46..f5a3ba8 100644 --- a/shared-types/src/lib/leaderboard.types.ts +++ b/shared-types/src/lib/leaderboard.types.ts @@ -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; + topLikes: Array; + topComments: Array; + topOverall: Array; } export { diff --git a/shared-types/src/lib/report.types.ts b/shared-types/src/lib/report.types.ts index dca7a50..b25e449 100644 --- a/shared-types/src/lib/report.types.ts +++ b/shared-types/src/lib/report.types.ts @@ -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;