feat: enhance user preferences management with userId integration

- Added `userId` field to `UserPreferences` model in Prisma schema for user-specific preferences.
- Implemented migration to populate existing preferences with the first user.
- Updated user preferences service methods to handle user-specific data retrieval and updates.
- Modified API routes and components to ensure user authentication and fetch preferences based on the authenticated user.
- Enhanced session management in various components to load user preferences accordingly.
This commit is contained in:
Julien Froidefond
2025-09-30 22:15:44 +02:00
parent 17b86b6087
commit 30aaca4877
23 changed files with 381 additions and 124 deletions

View File

@@ -4,6 +4,8 @@ import { userPreferencesService } from '@/services/core/user-preferences';
import { KanbanFilters, ViewPreferences, ColumnVisibility, TaskStatus } from '@/lib/types';
import { Theme } from '@/lib/theme-config';
import { revalidatePath } from 'next/cache';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
/**
* Met à jour les préférences de vue
@@ -13,7 +15,12 @@ export async function updateViewPreferences(updates: Partial<ViewPreferences>):
error?: string;
}> {
try {
await userPreferencesService.updateViewPreferences(updates);
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
await userPreferencesService.updateViewPreferences(session.user.id, updates);
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -33,7 +40,12 @@ export async function updateKanbanFilters(updates: Partial<KanbanFilters>): Prom
error?: string;
}> {
try {
await userPreferencesService.updateKanbanFilters(updates);
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
await userPreferencesService.updateKanbanFilters(session.user.id, updates);
revalidatePath('/kanban');
return { success: true };
} catch (error) {
@@ -53,13 +65,18 @@ export async function updateColumnVisibility(updates: Partial<ColumnVisibility>)
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const newColumnVisibility: ColumnVisibility = {
...preferences.columnVisibility,
...updates
};
await userPreferencesService.saveColumnVisibility(newColumnVisibility);
await userPreferencesService.saveColumnVisibility(session.user.id, newColumnVisibility);
revalidatePath('/kanban');
return { success: true };
} catch (error) {
@@ -79,10 +96,15 @@ export async function toggleObjectivesVisibility(): Promise<{
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const showObjectives = !preferences.viewPreferences.showObjectives;
await userPreferencesService.updateViewPreferences({ showObjectives });
await userPreferencesService.updateViewPreferences(session.user.id, { showObjectives });
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -102,10 +124,15 @@ export async function toggleObjectivesCollapse(): Promise<{
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const collapseObjectives = !preferences.viewPreferences.collapseObjectives;
await userPreferencesService.updateViewPreferences({ collapseObjectives });
await userPreferencesService.updateViewPreferences(session.user.id, { collapseObjectives });
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -125,7 +152,12 @@ export async function setTheme(theme: Theme): Promise<{
error?: string;
}> {
try {
await userPreferencesService.updateViewPreferences({ theme });
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
await userPreferencesService.updateViewPreferences(session.user.id, { theme });
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -145,10 +177,15 @@ export async function toggleTheme(): Promise<{
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const newTheme = preferences.viewPreferences.theme === 'dark' ? 'light' : 'dark';
await userPreferencesService.updateViewPreferences({ theme: newTheme });
await userPreferencesService.updateViewPreferences(session.user.id, { theme: newTheme });
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -168,13 +205,18 @@ export async function toggleFontSize(): Promise<{
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const fontSizes: ('small' | 'medium' | 'large')[] = ['small', 'medium', 'large'];
const currentIndex = fontSizes.indexOf(preferences.viewPreferences.fontSize);
const nextIndex = (currentIndex + 1) % fontSizes.length;
const newFontSize = fontSizes[nextIndex];
await userPreferencesService.updateViewPreferences({ fontSize: newFontSize });
await userPreferencesService.updateViewPreferences(session.user.id, { fontSize: newFontSize });
revalidatePath('/');
return { success: true };
} catch (error) {
@@ -194,7 +236,12 @@ export async function toggleColumnVisibility(status: TaskStatus): Promise<{
error?: string;
}> {
try {
const preferences = await userPreferencesService.getAllPreferences();
const session = await getServerSession(authOptions);
if (!session?.user?.id) {
return { success: false, error: 'Non authentifié' };
}
const preferences = await userPreferencesService.getAllPreferences(session.user.id);
const hiddenStatuses = new Set(preferences.columnVisibility.hiddenStatuses);
if (hiddenStatuses.has(status)) {
@@ -203,7 +250,7 @@ export async function toggleColumnVisibility(status: TaskStatus): Promise<{
hiddenStatuses.add(status);
}
await userPreferencesService.saveColumnVisibility({
await userPreferencesService.saveColumnVisibility(session.user.id, {
hiddenStatuses: Array.from(hiddenStatuses)
});