From bd9cd310fca0d0ee90d2137691a7bd5356c6b88b Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 11 Feb 2026 14:57:27 +0100 Subject: [PATCH] Remove next-intl localization infrastructure Strips out the i18n layer (next-intl, message files, language switcher, provider) to reduce complexity. Nav components now use plain English strings. Co-Authored-By: Claude Opus 4.6 --- messages/en.json | 327 --------- messages/fr.json | 327 --------- next.config.ts | 5 +- package-lock.json | 703 +------------------- package.json | 1 - src/app/layout.tsx | 13 +- src/components/layouts/admin-sidebar.tsx | 7 +- src/components/layouts/applicant-nav.tsx | 10 +- src/components/layouts/jury-nav.tsx | 12 +- src/components/layouts/mentor-nav.tsx | 8 +- src/components/layouts/observer-nav.tsx | 6 +- src/components/layouts/role-nav.tsx | 11 +- src/components/shared/language-switcher.tsx | 61 -- src/i18n/request.ts | 22 - 14 files changed, 25 insertions(+), 1488 deletions(-) delete mode 100644 messages/en.json delete mode 100644 messages/fr.json delete mode 100644 src/components/shared/language-switcher.tsx delete mode 100644 src/i18n/request.ts diff --git a/messages/en.json b/messages/en.json deleted file mode 100644 index 1e49e9e..0000000 --- a/messages/en.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "common": { - "loading": "Loading...", - "save": "Save", - "cancel": "Cancel", - "delete": "Delete", - "edit": "Edit", - "create": "Create", - "close": "Close", - "confirm": "Confirm", - "back": "Back", - "next": "Next", - "submit": "Submit", - "search": "Search", - "filter": "Filter", - "export": "Export", - "import": "Import", - "refresh": "Refresh", - "actions": "Actions", - "status": "Status", - "name": "Name", - "email": "Email", - "role": "Role", - "date": "Date", - "description": "Description", - "settings": "Settings", - "yes": "Yes", - "no": "No", - "all": "All", - "none": "None", - "noResults": "No results found", - "error": "Error", - "success": "Success", - "warning": "Warning", - "info": "Info", - "required": "Required", - "optional": "Optional", - "total": "Total", - "page": "Page", - "of": "of", - "showing": "Showing", - "entries": "entries", - "perPage": "per page", - "language": "Language", - "english": "English", - "french": "French" - }, - "auth": { - "signIn": "Sign In", - "signOut": "Sign Out", - "signUp": "Sign Up", - "email": "Email Address", - "password": "Password", - "forgotPassword": "Forgot Password?", - "resetPassword": "Reset Password", - "newPassword": "New Password", - "confirmPassword": "Confirm Password", - "currentPassword": "Current Password", - "magicLink": "Sign in with Magic Link", - "magicLinkSent": "Check your email for a sign-in link", - "invalidCredentials": "Invalid email or password", - "accountLocked": "Account locked. Try again later.", - "setPassword": "Set Password", - "passwordRequirements": "Password must be at least 8 characters", - "passwordsDoNotMatch": "Passwords do not match", - "welcomeBack": "Welcome back", - "signInDescription": "Enter your email to sign in to your account", - "orContinueWith": "Or continue with" - }, - "nav": { - "dashboard": "Dashboard", - "programs": "Programs", - "rounds": "Rounds", - "projects": "Projects", - "users": "Users", - "evaluations": "Evaluations", - "assignments": "Assignments", - "analytics": "Analytics", - "settings": "Settings", - "audit": "Audit Log", - "myProjects": "My Projects", - "myEvaluations": "My Evaluations", - "profile": "Profile", - "help": "Help", - "notifications": "Notifications", - "mentoring": "Mentoring", - "liveVoting": "Live Voting", - "applications": "Applications", - "messages": "Messages", - "team": "Team", - "documents": "Documents", - "awards": "Awards", - "compare": "Compare", - "learningHub": "Learning Hub", - "reports": "Reports" - }, - "dashboard": { - "title": "Dashboard", - "welcome": "Welcome, {name}", - "overview": "Overview", - "recentActivity": "Recent Activity", - "pendingEvaluations": "Pending Evaluations", - "completedEvaluations": "Completed Evaluations", - "totalProjects": "Total Projects", - "activeRounds": "Active Rounds", - "assignedProjects": "Assigned Projects", - "upcomingDeadlines": "Upcoming Deadlines", - "quickActions": "Quick Actions", - "noActivity": "No recent activity" - }, - "programs": { - "title": "Programs", - "createProgram": "Create Program", - "editProgram": "Edit Program", - "programName": "Program Name", - "year": "Year", - "status": "Status", - "rounds": "Rounds", - "projects": "Projects", - "noPrograms": "No programs found", - "deleteConfirm": "Are you sure you want to delete this program?" - }, - "rounds": { - "title": "Rounds", - "createRound": "Create Round", - "editRound": "Edit Round", - "roundName": "Round Name", - "roundType": "Round Type", - "startDate": "Start Date", - "endDate": "End Date", - "votingWindow": "Voting Window", - "criteria": "Evaluation Criteria", - "status": "Status", - "active": "Active", - "closed": "Closed", - "upcoming": "Upcoming", - "noRounds": "No rounds found" - }, - "projects": { - "title": "Projects", - "createProject": "Create Project", - "editProject": "Edit Project", - "projectName": "Project Title", - "teamName": "Team Name", - "country": "Country", - "category": "Category", - "status": "Status", - "description": "Description", - "files": "Files", - "evaluations": "Evaluations", - "noProjects": "No projects found", - "importCsv": "Import CSV", - "bulkStatusUpdate": "Bulk Status Update", - "viewDetails": "View Details", - "assignMentor": "Assign Mentor", - "oceanIssue": "Ocean Issue" - }, - "evaluations": { - "title": "Evaluations", - "submitEvaluation": "Submit Evaluation", - "draft": "Draft", - "submitted": "Submitted", - "score": "Score", - "feedback": "Feedback", - "criteria": "Criteria", - "globalScore": "Global Score", - "decision": "Decision", - "recommend": "Recommend", - "doNotRecommend": "Do Not Recommend", - "saveAsDraft": "Save as Draft", - "finalSubmit": "Final Submit", - "confirmSubmit": "Are you sure? This action cannot be undone.", - "progress": "Progress", - "completionRate": "Completion Rate", - "noEvaluations": "No evaluations yet", - "evaluationSummary": "Evaluation Summary", - "strengths": "Strengths", - "weaknesses": "Weaknesses", - "overallAssessment": "Overall Assessment" - }, - "users": { - "title": "Users", - "createUser": "Create User", - "editUser": "Edit User", - "inviteUser": "Invite User", - "bulkImport": "Bulk Import", - "sendInvitation": "Send Invitation", - "resendInvitation": "Resend Invitation", - "role": "Role", - "status": "Status", - "active": "Active", - "invited": "Invited", - "suspended": "Suspended", - "noUsers": "No users found", - "expertiseTags": "Expertise Tags", - "maxAssignments": "Max Assignments", - "lastLogin": "Last Login", - "deleteConfirm": "Are you sure you want to delete this user?" - }, - "assignments": { - "title": "Assignments", - "assign": "Assign", - "unassign": "Unassign", - "bulkAssign": "Bulk Assign", - "smartAssign": "Smart Assignment", - "manual": "Manual", - "algorithm": "Algorithm", - "aiAuto": "AI Auto", - "noAssignments": "No assignments", - "assignedTo": "Assigned to", - "assignedBy": "Assigned by" - }, - "files": { - "title": "Files", - "upload": "Upload File", - "download": "Download", - "delete": "Delete File", - "fileName": "File Name", - "fileType": "File Type", - "fileSize": "File Size", - "uploadDate": "Upload Date", - "noFiles": "No files uploaded", - "dragAndDrop": "Drag and drop files here", - "maxSize": "Maximum file size: {size}", - "version": "Version", - "versionHistory": "Version History", - "replaceFile": "Replace File", - "bulkDownload": "Bulk Download" - }, - "settings": { - "title": "Settings", - "general": "General", - "branding": "Branding", - "email": "Email", - "security": "Security", - "ai": "AI Configuration", - "storage": "Storage", - "language": "Language", - "defaultLanguage": "Default Language", - "availableLanguages": "Available Languages", - "languageDescription": "Configure the platform's language settings", - "saved": "Settings saved successfully", - "saveFailed": "Failed to save settings" - }, - "liveVoting": { - "title": "Live Voting", - "session": "Session", - "startVoting": "Start Voting", - "stopVoting": "Stop Voting", - "endSession": "End Session", - "timeRemaining": "Time Remaining", - "castVote": "Cast Your Vote", - "voteSubmitted": "Vote submitted", - "results": "Results", - "juryScore": "Jury Score", - "audienceScore": "Audience Score", - "weightedTotal": "Weighted Total", - "noVotes": "No votes yet", - "votingClosed": "Voting has closed", - "presentationSettings": "Presentation Settings", - "audienceVoting": "Audience Voting" - }, - "mentor": { - "title": "Mentoring", - "myMentees": "My Mentees", - "projectDetails": "Project Details", - "sendMessage": "Send Message", - "notes": "Notes", - "addNote": "Add Note", - "milestones": "Milestones", - "completeMilestone": "Mark Complete", - "activity": "Activity", - "lastViewed": "Last Viewed", - "noMentees": "No mentees assigned" - }, - "profile": { - "title": "Profile", - "editProfile": "Edit Profile", - "name": "Full Name", - "email": "Email", - "phone": "Phone Number", - "country": "Country", - "bio": "Bio", - "expertise": "Areas of Expertise", - "notifications": "Notification Preferences", - "digestFrequency": "Digest Frequency", - "availability": "Availability", - "workload": "Preferred Workload", - "changePassword": "Change Password", - "deleteAccount": "Delete Account", - "deleteAccountConfirm": "This action cannot be undone. All your data will be permanently deleted." - }, - "onboarding": { - "welcome": "Welcome to MOPC", - "setupProfile": "Let's set up your profile", - "step1": "Personal Information", - "step2": "Expertise & Preferences", - "step3": "Review & Complete", - "complete": "Complete Setup", - "skip": "Skip for now" - }, - "errors": { - "generic": "Something went wrong. Please try again.", - "notFound": "Page not found", - "unauthorized": "You are not authorized to access this page", - "forbidden": "Access denied", - "serverError": "Internal server error", - "networkError": "Network error. Please check your connection.", - "sessionExpired": "Your session has expired. Please sign in again.", - "validationError": "Please check the form for errors" - }, - "notifications": { - "title": "Notifications", - "markAllRead": "Mark all as read", - "noNotifications": "No notifications", - "viewAll": "View all notifications" - }, - "coi": { - "title": "Conflict of Interest", - "declaration": "COI Declaration", - "declareConflict": "Declare Conflict of Interest", - "noConflict": "No conflict of interest", - "hasConflict": "Conflict declared", - "reason": "Reason for conflict", - "confirmDeclaration": "I confirm this declaration is accurate" - } -} diff --git a/messages/fr.json b/messages/fr.json deleted file mode 100644 index d22e1aa..0000000 --- a/messages/fr.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "common": { - "loading": "Chargement...", - "save": "Enregistrer", - "cancel": "Annuler", - "delete": "Supprimer", - "edit": "Modifier", - "create": "Cr\u00e9er", - "close": "Fermer", - "confirm": "Confirmer", - "back": "Retour", - "next": "Suivant", - "submit": "Soumettre", - "search": "Rechercher", - "filter": "Filtrer", - "export": "Exporter", - "import": "Importer", - "refresh": "Actualiser", - "actions": "Actions", - "status": "Statut", - "name": "Nom", - "email": "E-mail", - "role": "R\u00f4le", - "date": "Date", - "description": "Description", - "settings": "Param\u00e8tres", - "yes": "Oui", - "no": "Non", - "all": "Tous", - "none": "Aucun", - "noResults": "Aucun r\u00e9sultat trouv\u00e9", - "error": "Erreur", - "success": "Succ\u00e8s", - "warning": "Avertissement", - "info": "Information", - "required": "Obligatoire", - "optional": "Facultatif", - "total": "Total", - "page": "Page", - "of": "de", - "showing": "Affichage de", - "entries": "entr\u00e9es", - "perPage": "par page", - "language": "Langue", - "english": "Anglais", - "french": "Fran\u00e7ais" - }, - "auth": { - "signIn": "Se connecter", - "signOut": "Se d\u00e9connecter", - "signUp": "S'inscrire", - "email": "Adresse e-mail", - "password": "Mot de passe", - "forgotPassword": "Mot de passe oubli\u00e9 ?", - "resetPassword": "R\u00e9initialiser le mot de passe", - "newPassword": "Nouveau mot de passe", - "confirmPassword": "Confirmer le mot de passe", - "currentPassword": "Mot de passe actuel", - "magicLink": "Se connecter avec un lien magique", - "magicLinkSent": "V\u00e9rifiez votre e-mail pour un lien de connexion", - "invalidCredentials": "E-mail ou mot de passe invalide", - "accountLocked": "Compte verrouill\u00e9. R\u00e9essayez plus tard.", - "setPassword": "D\u00e9finir le mot de passe", - "passwordRequirements": "Le mot de passe doit contenir au moins 8 caract\u00e8res", - "passwordsDoNotMatch": "Les mots de passe ne correspondent pas", - "welcomeBack": "Bon retour", - "signInDescription": "Entrez votre e-mail pour vous connecter \u00e0 votre compte", - "orContinueWith": "Ou continuer avec" - }, - "nav": { - "dashboard": "Tableau de bord", - "programs": "Programmes", - "rounds": "Tours", - "projects": "Projets", - "users": "Utilisateurs", - "evaluations": "\u00c9valuations", - "assignments": "Affectations", - "analytics": "Analytique", - "settings": "Param\u00e8tres", - "audit": "Journal d'audit", - "myProjects": "Mes projets", - "myEvaluations": "Mes \u00e9valuations", - "profile": "Profil", - "help": "Aide", - "notifications": "Notifications", - "mentoring": "Mentorat", - "liveVoting": "Vote en direct", - "applications": "Candidatures", - "messages": "Messages", - "team": "\u00c9quipe", - "documents": "Documents", - "awards": "Prix", - "compare": "Comparer", - "learningHub": "Centre de ressources", - "reports": "Rapports" - }, - "dashboard": { - "title": "Tableau de bord", - "welcome": "Bienvenue, {name}", - "overview": "Aper\u00e7u", - "recentActivity": "Activit\u00e9 r\u00e9cente", - "pendingEvaluations": "\u00c9valuations en attente", - "completedEvaluations": "\u00c9valuations termin\u00e9es", - "totalProjects": "Total des projets", - "activeRounds": "Tours actifs", - "assignedProjects": "Projets assign\u00e9s", - "upcomingDeadlines": "\u00c9ch\u00e9ances \u00e0 venir", - "quickActions": "Actions rapides", - "noActivity": "Aucune activit\u00e9 r\u00e9cente" - }, - "programs": { - "title": "Programmes", - "createProgram": "Cr\u00e9er un programme", - "editProgram": "Modifier le programme", - "programName": "Nom du programme", - "year": "Ann\u00e9e", - "status": "Statut", - "rounds": "Tours", - "projects": "Projets", - "noPrograms": "Aucun programme trouv\u00e9", - "deleteConfirm": "\u00cates-vous s\u00fbr de vouloir supprimer ce programme ?" - }, - "rounds": { - "title": "Tours", - "createRound": "Cr\u00e9er un tour", - "editRound": "Modifier le tour", - "roundName": "Nom du tour", - "roundType": "Type de tour", - "startDate": "Date de d\u00e9but", - "endDate": "Date de fin", - "votingWindow": "Fen\u00eatre de vote", - "criteria": "Crit\u00e8res d'\u00e9valuation", - "status": "Statut", - "active": "Actif", - "closed": "Cl\u00f4tur\u00e9", - "upcoming": "\u00c0 venir", - "noRounds": "Aucun tour trouv\u00e9" - }, - "projects": { - "title": "Projets", - "createProject": "Cr\u00e9er un projet", - "editProject": "Modifier le projet", - "projectName": "Titre du projet", - "teamName": "Nom de l'\u00e9quipe", - "country": "Pays", - "category": "Cat\u00e9gorie", - "status": "Statut", - "description": "Description", - "files": "Fichiers", - "evaluations": "\u00c9valuations", - "noProjects": "Aucun projet trouv\u00e9", - "importCsv": "Importer CSV", - "bulkStatusUpdate": "Mise \u00e0 jour en masse du statut", - "viewDetails": "Voir les d\u00e9tails", - "assignMentor": "Assigner un mentor", - "oceanIssue": "Probl\u00e9matique oc\u00e9anique" - }, - "evaluations": { - "title": "\u00c9valuations", - "submitEvaluation": "Soumettre l'\u00e9valuation", - "draft": "Brouillon", - "submitted": "Soumis", - "score": "Note", - "feedback": "Commentaires", - "criteria": "Crit\u00e8res", - "globalScore": "Note globale", - "decision": "D\u00e9cision", - "recommend": "Recommander", - "doNotRecommend": "Ne pas recommander", - "saveAsDraft": "Enregistrer comme brouillon", - "finalSubmit": "Soumission finale", - "confirmSubmit": "\u00cates-vous s\u00fbr ? Cette action est irr\u00e9versible.", - "progress": "Progression", - "completionRate": "Taux de compl\u00e9tion", - "noEvaluations": "Aucune \u00e9valuation pour le moment", - "evaluationSummary": "R\u00e9sum\u00e9 de l'\u00e9valuation", - "strengths": "Points forts", - "weaknesses": "Points faibles", - "overallAssessment": "\u00c9valuation globale" - }, - "users": { - "title": "Utilisateurs", - "createUser": "Cr\u00e9er un utilisateur", - "editUser": "Modifier l'utilisateur", - "inviteUser": "Inviter un utilisateur", - "bulkImport": "Importation en masse", - "sendInvitation": "Envoyer l'invitation", - "resendInvitation": "Renvoyer l'invitation", - "role": "R\u00f4le", - "status": "Statut", - "active": "Actif", - "invited": "Invit\u00e9", - "suspended": "Suspendu", - "noUsers": "Aucun utilisateur trouv\u00e9", - "expertiseTags": "Tags d'expertise", - "maxAssignments": "Affectations max.", - "lastLogin": "Derni\u00e8re connexion", - "deleteConfirm": "\u00cates-vous s\u00fbr de vouloir supprimer cet utilisateur ?" - }, - "assignments": { - "title": "Affectations", - "assign": "Affecter", - "unassign": "D\u00e9saffecter", - "bulkAssign": "Affectation en masse", - "smartAssign": "Affectation intelligente", - "manual": "Manuel", - "algorithm": "Algorithme", - "aiAuto": "IA automatique", - "noAssignments": "Aucune affectation", - "assignedTo": "Affect\u00e9 \u00e0", - "assignedBy": "Affect\u00e9 par" - }, - "files": { - "title": "Fichiers", - "upload": "T\u00e9l\u00e9charger un fichier", - "download": "T\u00e9l\u00e9charger", - "delete": "Supprimer le fichier", - "fileName": "Nom du fichier", - "fileType": "Type de fichier", - "fileSize": "Taille du fichier", - "uploadDate": "Date de t\u00e9l\u00e9chargement", - "noFiles": "Aucun fichier t\u00e9l\u00e9charg\u00e9", - "dragAndDrop": "Glissez-d\u00e9posez les fichiers ici", - "maxSize": "Taille maximale du fichier : {size}", - "version": "Version", - "versionHistory": "Historique des versions", - "replaceFile": "Remplacer le fichier", - "bulkDownload": "T\u00e9l\u00e9chargement en masse" - }, - "settings": { - "title": "Param\u00e8tres", - "general": "G\u00e9n\u00e9ral", - "branding": "Image de marque", - "email": "E-mail", - "security": "S\u00e9curit\u00e9", - "ai": "Configuration IA", - "storage": "Stockage", - "language": "Langue", - "defaultLanguage": "Langue par d\u00e9faut", - "availableLanguages": "Langues disponibles", - "languageDescription": "Configurer les param\u00e8tres de langue de la plateforme", - "saved": "Param\u00e8tres enregistr\u00e9s avec succ\u00e8s", - "saveFailed": "\u00c9chec de l'enregistrement des param\u00e8tres" - }, - "liveVoting": { - "title": "Vote en direct", - "session": "Session", - "startVoting": "D\u00e9marrer le vote", - "stopVoting": "Arr\u00eater le vote", - "endSession": "Terminer la session", - "timeRemaining": "Temps restant", - "castVote": "Voter", - "voteSubmitted": "Vote soumis", - "results": "R\u00e9sultats", - "juryScore": "Note du jury", - "audienceScore": "Note du public", - "weightedTotal": "Total pond\u00e9r\u00e9", - "noVotes": "Aucun vote pour le moment", - "votingClosed": "Le vote est clos", - "presentationSettings": "Param\u00e8tres de pr\u00e9sentation", - "audienceVoting": "Vote du public" - }, - "mentor": { - "title": "Mentorat", - "myMentees": "Mes mentees", - "projectDetails": "D\u00e9tails du projet", - "sendMessage": "Envoyer un message", - "notes": "Notes", - "addNote": "Ajouter une note", - "milestones": "Jalons", - "completeMilestone": "Marquer comme termin\u00e9", - "activity": "Activit\u00e9", - "lastViewed": "Derni\u00e8re consultation", - "noMentees": "Aucun mentee assign\u00e9" - }, - "profile": { - "title": "Profil", - "editProfile": "Modifier le profil", - "name": "Nom complet", - "email": "E-mail", - "phone": "Num\u00e9ro de t\u00e9l\u00e9phone", - "country": "Pays", - "bio": "Biographie", - "expertise": "Domaines d'expertise", - "notifications": "Pr\u00e9f\u00e9rences de notification", - "digestFrequency": "Fr\u00e9quence du digest", - "availability": "Disponibilit\u00e9", - "workload": "Charge de travail pr\u00e9f\u00e9r\u00e9e", - "changePassword": "Changer le mot de passe", - "deleteAccount": "Supprimer le compte", - "deleteAccountConfirm": "Cette action est irr\u00e9versible. Toutes vos donn\u00e9es seront d\u00e9finitivement supprim\u00e9es." - }, - "onboarding": { - "welcome": "Bienvenue sur MOPC", - "setupProfile": "Configurons votre profil", - "step1": "Informations personnelles", - "step2": "Expertise et pr\u00e9f\u00e9rences", - "step3": "V\u00e9rification et finalisation", - "complete": "Terminer la configuration", - "skip": "Passer pour le moment" - }, - "errors": { - "generic": "Une erreur s'est produite. Veuillez r\u00e9essayer.", - "notFound": "Page non trouv\u00e9e", - "unauthorized": "Vous n'\u00eates pas autoris\u00e9 \u00e0 acc\u00e9der \u00e0 cette page", - "forbidden": "Acc\u00e8s refus\u00e9", - "serverError": "Erreur interne du serveur", - "networkError": "Erreur r\u00e9seau. V\u00e9rifiez votre connexion.", - "sessionExpired": "Votre session a expir\u00e9. Veuillez vous reconnecter.", - "validationError": "Veuillez v\u00e9rifier le formulaire pour les erreurs" - }, - "notifications": { - "title": "Notifications", - "markAllRead": "Tout marquer comme lu", - "noNotifications": "Aucune notification", - "viewAll": "Voir toutes les notifications" - }, - "coi": { - "title": "Conflit d'int\u00e9r\u00eats", - "declaration": "D\u00e9claration de COI", - "declareConflict": "D\u00e9clarer un conflit d'int\u00e9r\u00eats", - "noConflict": "Aucun conflit d'int\u00e9r\u00eats", - "hasConflict": "Conflit d\u00e9clar\u00e9", - "reason": "Raison du conflit", - "confirmDeclaration": "Je confirme que cette d\u00e9claration est exacte" - } -} diff --git a/next.config.ts b/next.config.ts index 4a4414e..c58ba04 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,5 +1,4 @@ import type { NextConfig } from 'next' -import createNextIntlPlugin from 'next-intl/plugin' const nextConfig: NextConfig = { output: 'standalone', @@ -18,6 +17,4 @@ const nextConfig: NextConfig = { }, } -const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts') - -export default withNextIntl(nextConfig) +export default nextConfig diff --git a/package-lock.json b/package-lock.json index 460a477..5b931b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -57,7 +57,6 @@ "motion": "^11.15.0", "next": "^15.1.0", "next-auth": "^5.0.0-beta.25", - "next-intl": "^4.8.2", "next-themes": "^0.4.6", "nodemailer": "^7.0.7", "openai": "^6.16.0", @@ -1004,67 +1003,6 @@ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, - "node_modules/@formatjs/ecma402-abstract": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-3.1.1.tgz", - "integrity": "sha512-jhZbTwda+2tcNrs4kKvxrPLPjx8QsBCLCUgrrJ/S+G9YrGHWLhAyFMMBHJBnBoOwuLHd7L14FgYudviKaxkO2Q==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "3.1.0", - "@formatjs/intl-localematcher": "0.8.1", - "decimal.js": "^10.6.0", - "tslib": "^2.8.1" - } - }, - "node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.1.tgz", - "integrity": "sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==", - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "3.1.0", - "tslib": "^2.8.1" - } - }, - "node_modules/@formatjs/fast-memoize": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.0.tgz", - "integrity": "sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" - } - }, - "node_modules/@formatjs/icu-messageformat-parser": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.1.tgz", - "integrity": "sha512-sSDmSvmmoVQ92XqWb499KrIhv/vLisJU8ITFrx7T7NZHUmMY7EL9xgRowAosaljhqnj/5iufG24QrdzB6X3ItA==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "3.1.1", - "@formatjs/icu-skeleton-parser": "2.1.1", - "tslib": "^2.8.1" - } - }, - "node_modules/@formatjs/icu-skeleton-parser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.1.tgz", - "integrity": "sha512-PSFABlcNefjI6yyk8f7nyX1DC7NHmq6WaCHZLySEXBrXuLOB2f935YsnzuPjlz+ibhb9yWTdPeVX1OVcj24w2Q==", - "license": "MIT", - "dependencies": { - "@formatjs/ecma402-abstract": "3.1.1", - "tslib": "^2.8.1" - } - }, - "node_modules/@formatjs/intl-localematcher": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz", - "integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==", - "license": "MIT", - "dependencies": { - "tslib": "2" - } - }, "node_modules/@handlewithcare/prosemirror-inputrules": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@handlewithcare/prosemirror-inputrules/-/prosemirror-inputrules-0.1.4.tgz", @@ -1916,301 +1854,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", - "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", - "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", - "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", - "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", - "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", - "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", - "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", - "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", - "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", - "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", - "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", - "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@playwright/test": { "version": "1.58.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0.tgz", @@ -4080,12 +3723,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@schummar/icu-type-parser": { - "version": "1.21.5", - "resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz", - "integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==", - "license": "MIT" - }, "node_modules/@shikijs/types": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", @@ -4114,172 +3751,6 @@ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", "license": "MIT" }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz", - "integrity": "sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz", - "integrity": "sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz", - "integrity": "sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz", - "integrity": "sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz", - "integrity": "sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz", - "integrity": "sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz", - "integrity": "sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz", - "integrity": "sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz", - "integrity": "sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz", - "integrity": "sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" - }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -4289,15 +3760,6 @@ "tslib": "^2.8.0" } }, - "node_modules/@swc/types": { - "version": "0.1.25", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz", - "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==", - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3" - } - }, "node_modules/@tailwindcss/node": { "version": "4.1.18", "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", @@ -6838,12 +6300,6 @@ } } }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "license": "MIT" - }, "node_modules/decimal.js-light": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", @@ -8687,21 +8143,6 @@ "node": ">=8.0.0" } }, - "node_modules/icu-minify": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.8.2.tgz", - "integrity": "sha512-LHBQV+skKkjZSPd590pZ7ZAHftUgda3eFjeuNwA8/15L8T8loCNBktKQyTlkodAU86KovFXeg/9WntlAo5wA5A==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/amannn" - } - ], - "license": "MIT", - "dependencies": { - "@formatjs/icu-messageformat-parser": "^3.4.0" - } - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -8800,18 +8241,6 @@ "node": ">=12" } }, - "node_modules/intl-messageformat": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.1.2.tgz", - "integrity": "sha512-ucSrQmZGAxfiBHfBRXW/k7UC8MaGFlEj4Ry1tKiDcmgwQm1y3EDl40u+4VNHYomxJQMJi9NEI3riDRlth96jKg==", - "license": "BSD-3-Clause", - "dependencies": { - "@formatjs/ecma402-abstract": "3.1.1", - "@formatjs/fast-memoize": "3.1.0", - "@formatjs/icu-messageformat-parser": "3.5.1", - "tslib": "^2.8.1" - } - }, "node_modules/iobuffer": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/iobuffer/-/iobuffer-5.4.0.tgz", @@ -8991,6 +8420,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9035,6 +8465,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -10848,15 +10279,6 @@ "dev": true, "license": "MIT" }, - "node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/next": { "version": "15.5.10", "resolved": "https://registry.npmjs.org/next/-/next-15.5.10.tgz", @@ -10965,93 +10387,6 @@ } } }, - "node_modules/next-intl": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.8.2.tgz", - "integrity": "sha512-GuuwyvyEI49/oehQbBXEoY8KSIYCzmfMLhmIwhMXTb+yeBmly1PnJcpgph3KczQ+HTJMXwXCmkizgtT8jBMf3A==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/amannn" - } - ], - "license": "MIT", - "dependencies": { - "@formatjs/intl-localematcher": "^0.5.4", - "@parcel/watcher": "^2.4.1", - "@swc/core": "^1.15.2", - "icu-minify": "^4.8.2", - "negotiator": "^1.0.0", - "next-intl-swc-plugin-extractor": "^4.8.2", - "po-parser": "^2.1.1", - "use-intl": "^4.8.2" - }, - "peerDependencies": { - "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0", - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/next-intl-swc-plugin-extractor": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.8.2.tgz", - "integrity": "sha512-sHDs36L1VZmFHj3tPHsD+KZJtnsRudHlNvT0ieIe3iFVn5OpGLTxW3d/Zc/2LXSj5GpGuR6wQeikbhFjU9tMQQ==", - "license": "MIT" - }, - "node_modules/next-intl/node_modules/@swc/core": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz", - "integrity": "sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.25" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.15.11", - "@swc/core-darwin-x64": "1.15.11", - "@swc/core-linux-arm-gnueabihf": "1.15.11", - "@swc/core-linux-arm64-gnu": "1.15.11", - "@swc/core-linux-arm64-musl": "1.15.11", - "@swc/core-linux-x64-gnu": "1.15.11", - "@swc/core-linux-x64-musl": "1.15.11", - "@swc/core-win32-arm64-msvc": "1.15.11", - "@swc/core-win32-ia32-msvc": "1.15.11", - "@swc/core-win32-x64-msvc": "1.15.11" - }, - "peerDependencies": { - "@swc/helpers": ">=0.5.17" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } - } - }, - "node_modules/next-intl/node_modules/@swc/helpers": { - "version": "0.5.18", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz", - "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "tslib": "^2.8.0" - } - }, "node_modules/next-themes": { "version": "0.4.6", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", @@ -11090,12 +10425,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT" - }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -11514,6 +10843,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -11566,12 +10896,6 @@ "node": ">=18" } }, - "node_modules/po-parser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.1.1.tgz", - "integrity": "sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==", - "license": "MIT" - }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -13988,27 +13312,6 @@ "react": "*" } }, - "node_modules/use-intl": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.8.2.tgz", - "integrity": "sha512-3VNXZgDnPFqhIYosQ9W1Hc6K5q+ZelMfawNbexdwL/dY7BTHbceLUBX5Eeex9lgogxTp0pf1SjHuhYNAjr9H3g==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/amannn" - } - ], - "license": "MIT", - "dependencies": { - "@formatjs/fast-memoize": "^3.1.0", - "@schummar/icu-type-parser": "1.21.5", - "icu-minify": "^4.8.2", - "intl-messageformat": "^11.1.0" - }, - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" - } - }, "node_modules/use-isomorphic-layout-effect": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz", diff --git a/package.json b/package.json index 4632519..4acfcc6 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,6 @@ "motion": "^11.15.0", "next": "^15.1.0", "next-auth": "^5.0.0-beta.25", - "next-intl": "^4.8.2", "next-themes": "^0.4.6", "nodemailer": "^7.0.7", "openai": "^6.16.0", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 75a7200..f61440b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,4 @@ import type { Metadata } from 'next' -import { NextIntlClientProvider } from 'next-intl' -import { getLocale, getMessages } from 'next-intl/server' import './globals.css' import { Providers } from './providers' import { Toaster } from 'sonner' @@ -16,20 +14,15 @@ export const metadata: Metadata = { }, } -export default async function RootLayout({ +export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { - const locale = await getLocale() - const messages = await getMessages() - return ( - + - - {children} - + {children} = { export function AdminSidebar({ user }: AdminSidebarProps) { const pathname = usePathname() - const tAuth = useTranslations('auth') const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false) const { status: sessionStatus } = useSession() const isAuthenticated = sessionStatus === 'authenticated' @@ -173,7 +170,6 @@ export function AdminSidebar({ user }: AdminSidebarProps) {
-
@@ -349,7 +344,7 @@ export function AdminSidebar({ user }: AdminSidebarProps) { className="flex cursor-pointer items-center gap-2.5 rounded-md px-2 py-2 text-destructive focus:bg-destructive/10 focus:text-destructive" > - {tAuth('signOut')} + Sign Out diff --git a/src/components/layouts/applicant-nav.tsx b/src/components/layouts/applicant-nav.tsx index dedd839..ebe9cd2 100644 --- a/src/components/layouts/applicant-nav.tsx +++ b/src/components/layouts/applicant-nav.tsx @@ -2,32 +2,30 @@ import { Home, Users, FileText, MessageSquare } from 'lucide-react' import { RoleNav, type NavItem, type RoleNavUser } from '@/components/layouts/role-nav' -import { useTranslations } from 'next-intl' interface ApplicantNavProps { user: RoleNavUser } export function ApplicantNav({ user }: ApplicantNavProps) { - const t = useTranslations('nav') const navigation: NavItem[] = [ { - name: t('dashboard'), + name: 'Dashboard', href: '/applicant', icon: Home, }, { - name: t('team'), + name: 'Team', href: '/applicant/team', icon: Users, }, { - name: t('documents'), + name: 'Documents', href: '/applicant/documents', icon: FileText, }, { - name: t('mentoring'), + name: 'Mentoring', href: '/applicant/mentor', icon: MessageSquare, }, diff --git a/src/components/layouts/jury-nav.tsx b/src/components/layouts/jury-nav.tsx index ab1dc34..91e6639 100644 --- a/src/components/layouts/jury-nav.tsx +++ b/src/components/layouts/jury-nav.tsx @@ -4,7 +4,6 @@ import { BookOpen, ClipboardList, GitCompare, Home, Trophy } from 'lucide-react' import { RoleNav, type NavItem, type RoleNavUser } from '@/components/layouts/role-nav' import { trpc } from '@/lib/trpc/client' import { Badge } from '@/components/ui/badge' -import { useTranslations } from 'next-intl' interface JuryNavProps { user: RoleNavUser @@ -43,30 +42,29 @@ function RemainingBadge() { } export function JuryNav({ user }: JuryNavProps) { - const t = useTranslations('nav') const navigation: NavItem[] = [ { - name: t('dashboard'), + name: 'Dashboard', href: '/jury', icon: Home, }, { - name: t('assignments'), + name: 'Assignments', href: '/jury/assignments', icon: ClipboardList, }, { - name: t('awards'), + name: 'Awards', href: '/jury/awards', icon: Trophy, }, { - name: t('compare'), + name: 'Compare', href: '/jury/compare', icon: GitCompare, }, { - name: t('learningHub'), + name: 'Learning Hub', href: '/jury/learning', icon: BookOpen, }, diff --git a/src/components/layouts/mentor-nav.tsx b/src/components/layouts/mentor-nav.tsx index c490918..e435ef1 100644 --- a/src/components/layouts/mentor-nav.tsx +++ b/src/components/layouts/mentor-nav.tsx @@ -2,27 +2,25 @@ import { BookOpen, Home, Users } from 'lucide-react' import { RoleNav, type NavItem, type RoleNavUser } from '@/components/layouts/role-nav' -import { useTranslations } from 'next-intl' interface MentorNavProps { user: RoleNavUser } export function MentorNav({ user }: MentorNavProps) { - const t = useTranslations('nav') const navigation: NavItem[] = [ { - name: t('dashboard'), + name: 'Dashboard', href: '/mentor', icon: Home, }, { - name: t('myProjects'), + name: 'My Projects', href: '/mentor/projects', icon: Users, }, { - name: t('learningHub'), + name: 'Learning Hub', href: '/mentor/resources', icon: BookOpen, }, diff --git a/src/components/layouts/observer-nav.tsx b/src/components/layouts/observer-nav.tsx index 3290443..d0b7eb8 100644 --- a/src/components/layouts/observer-nav.tsx +++ b/src/components/layouts/observer-nav.tsx @@ -2,22 +2,20 @@ import { BarChart3, Home } from 'lucide-react' import { RoleNav, type NavItem, type RoleNavUser } from '@/components/layouts/role-nav' -import { useTranslations } from 'next-intl' interface ObserverNavProps { user: RoleNavUser } export function ObserverNav({ user }: ObserverNavProps) { - const t = useTranslations('nav') const navigation: NavItem[] = [ { - name: t('dashboard'), + name: 'Dashboard', href: '/observer', icon: Home, }, { - name: t('reports'), + name: 'Reports', href: '/observer/reports', icon: BarChart3, }, diff --git a/src/components/layouts/role-nav.tsx b/src/components/layouts/role-nav.tsx index aa0d2b8..d98bb9f 100644 --- a/src/components/layouts/role-nav.tsx +++ b/src/components/layouts/role-nav.tsx @@ -4,7 +4,6 @@ import { useState, useEffect } from 'react' import Link from 'next/link' import { usePathname } from 'next/navigation' import { signOut, useSession } from 'next-auth/react' -import { useTranslations } from 'next-intl' import { cn } from '@/lib/utils' import { Button } from '@/components/ui/button' import { UserAvatar } from '@/components/shared/user-avatar' @@ -22,7 +21,6 @@ import { LogOut, Menu, Moon, Settings, Sun, User, X } from 'lucide-react' import { useTheme } from 'next-themes' import { Logo } from '@/components/shared/logo' import { NotificationBell } from '@/components/shared/notification-bell' -import { LanguageSwitcher } from '@/components/shared/language-switcher' export type NavItem = { name: string @@ -51,8 +49,6 @@ function isNavItemActive(pathname: string, href: string, basePath: string): bool export function RoleNav({ navigation, roleName, user, basePath, statusBadge }: RoleNavProps) { const pathname = usePathname() - const tCommon = useTranslations('common') - const tAuth = useTranslations('auth') const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false) const { status: sessionStatus } = useSession() const isAuthenticated = sessionStatus === 'authenticated' @@ -111,7 +107,6 @@ export function RoleNav({ navigation, roleName, user, basePath, statusBadge }: R )} )} - @@ -135,7 +130,7 @@ export function RoleNav({ navigation, roleName, user, basePath, statusBadge }: R - {tCommon('settings')} + Settings @@ -144,7 +139,7 @@ export function RoleNav({ navigation, roleName, user, basePath, statusBadge }: R className="text-destructive focus:text-destructive" > - {tAuth('signOut')} + Sign Out @@ -196,7 +191,7 @@ export function RoleNav({ navigation, roleName, user, basePath, statusBadge }: R onClick={() => signOut({ callbackUrl: '/login' })} > - {tAuth('signOut')} + Sign Out
diff --git a/src/components/shared/language-switcher.tsx b/src/components/shared/language-switcher.tsx deleted file mode 100644 index 4bad5d0..0000000 --- a/src/components/shared/language-switcher.tsx +++ /dev/null @@ -1,61 +0,0 @@ -'use client' - -import { useTransition } from 'react' -import { useLocale } from 'next-intl' -import { useRouter } from 'next/navigation' -import { Button } from '@/components/ui/button' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu' -import { Globe, Check } from 'lucide-react' - -const LANGUAGES = [ - { code: 'en', label: 'English', flag: 'EN' }, - { code: 'fr', label: 'Fran\u00e7ais', flag: 'FR' }, -] as const - -type LanguageCode = (typeof LANGUAGES)[number]['code'] - -export function LanguageSwitcher() { - const locale = useLocale() as LanguageCode - const router = useRouter() - const [isPending, startTransition] = useTransition() - - const currentLang = LANGUAGES.find((l) => l.code === locale) ?? LANGUAGES[0] - - const switchLanguage = (code: LanguageCode) => { - // Set cookie with 1 year expiry - document.cookie = `locale=${code};path=/;max-age=${365 * 24 * 60 * 60};samesite=lax` - // Refresh to re-run server components with new locale - startTransition(() => { - router.refresh() - }) - } - - return ( - - - - - - {LANGUAGES.map((lang) => ( - switchLanguage(lang.code)} - className="gap-2" - > - {lang.flag} - {lang.label} - {locale === lang.code && } - - ))} - - - ) -} diff --git a/src/i18n/request.ts b/src/i18n/request.ts deleted file mode 100644 index af7de87..0000000 --- a/src/i18n/request.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { getRequestConfig } from 'next-intl/server' -import { cookies } from 'next/headers' - -export const supportedLocales = ['en', 'fr'] as const -export type SupportedLocale = (typeof supportedLocales)[number] - -export const defaultLocale: SupportedLocale = 'en' - -export default getRequestConfig(async () => { - const store = await cookies() - const cookieLocale = store.get('locale')?.value - - // Validate the locale from cookie - const locale = supportedLocales.includes(cookieLocale as SupportedLocale) - ? (cookieLocale as SupportedLocale) - : defaultLocale - - return { - locale, - messages: (await import(`../../messages/${locale}.json`)).default, - } -})