feat: complete daily checkbox actions and cleanup
- Marked all daily checkbox actions as complete in TODO.md. - Removed outdated mutation methods from `daily-client.ts`, now managed by server actions in `actions/daily.ts`. - Deleted unused API routes for checkbox management, streamlining the codebase. - Updated `useDaily.ts` to utilize server actions with `useTransition`, enhancing performance and user experience.
This commit is contained in:
20
TODO.md
20
TODO.md
@@ -176,16 +176,16 @@
|
||||
- [x] **Nettoyage** : Modifier `useTasks.ts` pour remplacer mutations par server actions
|
||||
|
||||
#### Actions Daily (Priorité 2)
|
||||
- [ ] Créer `actions/daily.ts` pour les checkboxes
|
||||
- [ ] `toggleCheckbox(checkboxId)` - Toggle état checkbox
|
||||
- [ ] `addCheckboxToDaily(dailyId, content)` - Ajouter checkbox
|
||||
- [ ] `updateCheckboxContent(checkboxId, content)` - Éditer contenu
|
||||
- [ ] `deleteCheckbox(checkboxId)` - Supprimer checkbox
|
||||
- [ ] `reorderCheckboxes(dailyId, checkboxIds)` - Réorganiser
|
||||
- [ ] Modifier les composants Daily pour utiliser server actions
|
||||
- [ ] **Nettoyage** : Supprimer routes `/api/daily/checkboxes` (POST, PATCH, DELETE)
|
||||
- [ ] **Nettoyage** : Simplifier `daily-client.ts` (garder GET uniquement)
|
||||
- [ ] **Nettoyage** : Modifier composants Daily pour `useTransition`
|
||||
- [x] Créer `actions/daily.ts` pour les checkboxes
|
||||
- [x] `toggleCheckbox(checkboxId)` - Toggle état checkbox
|
||||
- [x] `addCheckboxToDaily(dailyId, content)` - Ajouter checkbox
|
||||
- [x] `updateCheckboxContent(checkboxId, content)` - Éditer contenu
|
||||
- [x] `deleteCheckbox(checkboxId)` - Supprimer checkbox
|
||||
- [x] `reorderCheckboxes(dailyId, checkboxIds)` - Réorganiser
|
||||
- [x] Modifier les composants Daily pour utiliser server actions
|
||||
- [x] **Nettoyage** : Supprimer routes `/api/daily/checkboxes` (POST, PATCH, DELETE)
|
||||
- [x] **Nettoyage** : Simplifier `daily-client.ts` (garder GET uniquement)
|
||||
- [x] **Nettoyage** : Modifier hook `useDaily.ts` pour `useTransition`
|
||||
|
||||
#### Actions User Preferences (Priorité 3)
|
||||
- [x] Créer `actions/preferences.ts` pour les toggles
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { httpClient } from './base/http-client';
|
||||
import { DailyCheckbox, DailyView, CreateDailyCheckboxData, UpdateDailyCheckboxData, Task } from '@/lib/types';
|
||||
import { DailyCheckbox, DailyView, Task } from '@/lib/types';
|
||||
|
||||
// Types pour les réponses API (avec dates en string)
|
||||
interface ApiCheckbox {
|
||||
@@ -35,11 +35,16 @@ export interface DailySearchFilters {
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
// Types conservés pour la compatibilité des hooks d'historique et de recherche
|
||||
export interface ReorderCheckboxesData {
|
||||
date: Date;
|
||||
checkboxIds: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Client HTTP pour les données Daily (lecture seule)
|
||||
* Les mutations sont gérées par les server actions dans actions/daily.ts
|
||||
*/
|
||||
export class DailyClient {
|
||||
/**
|
||||
* Récupère la vue daily d'aujourd'hui (hier + aujourd'hui)
|
||||
@@ -88,81 +93,6 @@ export class DailyClient {
|
||||
return result.map((cb: ApiCheckbox) => this.transformCheckboxDates(cb));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox
|
||||
*/
|
||||
async addCheckbox(data: CreateDailyCheckboxData): Promise<DailyCheckbox> {
|
||||
const payload = {
|
||||
...data,
|
||||
date: this.formatDateForAPI(data.date)
|
||||
};
|
||||
try {
|
||||
const result = await httpClient.post<ApiCheckbox>('/daily', payload);
|
||||
// Transformer les dates string en objets Date
|
||||
return this.transformCheckboxDates(result);
|
||||
} catch (error) {
|
||||
console.error('❌ DailyClient addCheckbox error:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox pour aujourd'hui
|
||||
*/
|
||||
async addTodayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
||||
return this.addCheckbox({
|
||||
date: new Date(),
|
||||
text,
|
||||
taskId
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox pour hier
|
||||
*/
|
||||
async addYesterdayCheckbox(text: string, taskId?: string): Promise<DailyCheckbox> {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
|
||||
return this.addCheckbox({
|
||||
date: yesterday,
|
||||
text,
|
||||
taskId
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour une checkbox
|
||||
*/
|
||||
async updateCheckbox(checkboxId: string, data: UpdateDailyCheckboxData): Promise<DailyCheckbox> {
|
||||
const result = await httpClient.patch<ApiCheckbox>(`/daily/checkboxes/${checkboxId}`, data);
|
||||
return this.transformCheckboxDates(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime une checkbox
|
||||
*/
|
||||
async deleteCheckbox(checkboxId: string): Promise<void> {
|
||||
return httpClient.delete(`/daily/checkboxes/${checkboxId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Réordonne les checkboxes d'une date
|
||||
*/
|
||||
async reorderCheckboxes(data: ReorderCheckboxesData): Promise<void> {
|
||||
return httpClient.post('/daily/checkboxes', {
|
||||
date: this.formatDateForAPI(data.date),
|
||||
checkboxIds: data.checkboxIds
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Coche/décoche une checkbox (raccourci)
|
||||
*/
|
||||
async toggleCheckbox(checkboxId: string, isChecked: boolean): Promise<DailyCheckbox> {
|
||||
return this.updateCheckbox(checkboxId, { isChecked });
|
||||
}
|
||||
|
||||
/**
|
||||
* Formate une date pour l'API (évite les décalages timezone)
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useState, useEffect, useCallback, useTransition } from 'react';
|
||||
import { dailyClient, DailyHistoryFilters, DailySearchFilters, ReorderCheckboxesData } from '@/clients/daily-client';
|
||||
import { DailyView, DailyCheckbox, UpdateDailyCheckboxData, DailyCheckboxType } from '@/lib/types';
|
||||
import {
|
||||
toggleCheckbox as toggleCheckboxAction,
|
||||
addTodayCheckbox as addTodayCheckboxAction,
|
||||
addYesterdayCheckbox as addYesterdayCheckboxAction,
|
||||
updateCheckbox as updateCheckboxAction,
|
||||
deleteCheckbox as deleteCheckboxAction
|
||||
} from '@/actions/daily';
|
||||
|
||||
interface UseDailyState {
|
||||
dailyView: DailyView | null;
|
||||
@@ -10,6 +17,7 @@ interface UseDailyState {
|
||||
refreshing: boolean; // Pour les refresh silencieux
|
||||
error: string | null;
|
||||
saving: boolean; // Pour indiquer les opérations en cours
|
||||
isPending: boolean; // Pour indiquer les server actions en cours
|
||||
}
|
||||
|
||||
interface UseDailyActions {
|
||||
@@ -39,6 +47,7 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
||||
const [refreshing, setRefreshing] = useState(false); // Pour les refresh silencieux
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
const refreshDaily = useCallback(async () => {
|
||||
try {
|
||||
@@ -69,160 +78,102 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
||||
}
|
||||
}, [currentDate]);
|
||||
|
||||
const addTodayCheckbox = useCallback(async (text: string, type?: DailyCheckboxType, taskId?: string): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return null;
|
||||
|
||||
// Créer une checkbox temporaire pour l'affichage optimiste
|
||||
const tempCheckbox: DailyCheckbox = {
|
||||
id: `temp-${Date.now()}`, // ID temporaire
|
||||
date: currentDate,
|
||||
text,
|
||||
isChecked: false,
|
||||
type: type || 'task', // Utilise le type fourni ou 'task' par défaut
|
||||
order: dailyView.today.length, // Ordre temporaire
|
||||
taskId,
|
||||
task: undefined,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
};
|
||||
|
||||
const previousDailyView = dailyView;
|
||||
|
||||
// Mise à jour optimiste IMMÉDIATE
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
today: [...prev.today, tempCheckbox]
|
||||
} : null);
|
||||
const addTodayCheckbox = useCallback((text: string, type?: DailyCheckboxType, taskId?: string): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return Promise.resolve(null);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
// Appel API en arrière-plan
|
||||
const newCheckbox = await dailyClient.addCheckbox({
|
||||
date: currentDate,
|
||||
text,
|
||||
type: type || 'task',
|
||||
taskId
|
||||
});
|
||||
setError(null);
|
||||
|
||||
// Remplacer la checkbox temporaire par la vraie
|
||||
const result = await addTodayCheckboxAction(text, taskId);
|
||||
|
||||
if (result.success && result.data) {
|
||||
// Mise à jour optimiste
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
today: prev.today.map(cb =>
|
||||
cb.id === tempCheckbox.id ? newCheckbox : cb
|
||||
).sort((a, b) => a.order - b.order)
|
||||
today: [...prev.today, result.data!].sort((a, b) => a.order - b.order)
|
||||
} : null);
|
||||
|
||||
return newCheckbox;
|
||||
resolve(result.data);
|
||||
} else {
|
||||
setError(result.error || 'Erreur lors de l\'ajout de la checkbox');
|
||||
resolve(null);
|
||||
}
|
||||
} catch (err) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de l\'ajout de la checkbox');
|
||||
console.error('Erreur addTodayCheckbox:', err);
|
||||
return null;
|
||||
resolve(null);
|
||||
}
|
||||
}, [dailyView, currentDate]);
|
||||
|
||||
const addYesterdayCheckbox = useCallback(async (text: string, type?: DailyCheckboxType, taskId?: string): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return null;
|
||||
|
||||
// Créer une checkbox temporaire pour l'affichage optimiste
|
||||
const yesterday = new Date(currentDate);
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
|
||||
const tempCheckbox: DailyCheckbox = {
|
||||
id: `temp-${Date.now()}`, // ID temporaire
|
||||
date: yesterday,
|
||||
text,
|
||||
isChecked: false,
|
||||
type: type || 'task', // Utilise le type fourni ou 'task' par défaut
|
||||
order: dailyView.yesterday.length, // Ordre temporaire
|
||||
taskId,
|
||||
task: undefined,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
};
|
||||
|
||||
const previousDailyView = dailyView;
|
||||
|
||||
// Mise à jour optimiste IMMÉDIATE
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: [...prev.yesterday, tempCheckbox]
|
||||
} : null);
|
||||
|
||||
try {
|
||||
// Appel API en arrière-plan
|
||||
const newCheckbox = await dailyClient.addCheckbox({
|
||||
date: yesterday,
|
||||
text,
|
||||
type: type || 'task',
|
||||
taskId
|
||||
});
|
||||
|
||||
// Remplacer la checkbox temporaire par la vraie
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: prev.yesterday.map(cb =>
|
||||
cb.id === tempCheckbox.id ? newCheckbox : cb
|
||||
).sort((a, b) => a.order - b.order)
|
||||
} : null);
|
||||
|
||||
return newCheckbox;
|
||||
} catch (err) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de l\'ajout de la checkbox');
|
||||
console.error('Erreur addYesterdayCheckbox:', err);
|
||||
return null;
|
||||
}
|
||||
}, [dailyView, currentDate]);
|
||||
|
||||
const updateCheckbox = useCallback(async (checkboxId: string, data: UpdateDailyCheckboxData): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return null;
|
||||
|
||||
// Trouver la checkbox existante
|
||||
let existingCheckbox = dailyView.yesterday.find(cb => cb.id === checkboxId);
|
||||
if (!existingCheckbox) {
|
||||
existingCheckbox = dailyView.today.find(cb => cb.id === checkboxId);
|
||||
}
|
||||
|
||||
if (!existingCheckbox) return null;
|
||||
|
||||
const previousDailyView = dailyView;
|
||||
|
||||
// Créer la checkbox mise à jour pour l'affichage optimiste
|
||||
const optimisticCheckbox = { ...existingCheckbox, ...data, updatedAt: new Date() };
|
||||
|
||||
// Mise à jour optimiste IMMÉDIATE
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: prev.yesterday.map(cb => cb.id === checkboxId ? optimisticCheckbox : cb),
|
||||
today: prev.today.map(cb => cb.id === checkboxId ? optimisticCheckbox : cb)
|
||||
} : null);
|
||||
|
||||
try {
|
||||
// Appel API en arrière-plan
|
||||
const updatedCheckbox = await dailyClient.updateCheckbox(checkboxId, data);
|
||||
|
||||
// Remplacer par la vraie checkbox retournée par l'API
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: prev.yesterday.map(cb => cb.id === checkboxId ? updatedCheckbox : cb),
|
||||
today: prev.today.map(cb => cb.id === checkboxId ? updatedCheckbox : cb)
|
||||
} : null);
|
||||
|
||||
return updatedCheckbox;
|
||||
} catch (err) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de la mise à jour de la checkbox');
|
||||
console.error('Erreur updateCheckbox:', err);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}, [dailyView]);
|
||||
|
||||
const deleteCheckbox = useCallback(async (checkboxId: string): Promise<void> => {
|
||||
if (!dailyView) return;
|
||||
const addYesterdayCheckbox = useCallback((text: string, type?: DailyCheckboxType, taskId?: string): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return Promise.resolve(null);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
const result = await addYesterdayCheckboxAction(text, taskId);
|
||||
|
||||
if (result.success && result.data) {
|
||||
// Mise à jour optimiste
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: [...prev.yesterday, result.data!].sort((a, b) => a.order - b.order)
|
||||
} : null);
|
||||
resolve(result.data);
|
||||
} else {
|
||||
setError(result.error || 'Erreur lors de l\'ajout de la checkbox');
|
||||
resolve(null);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de l\'ajout de la checkbox');
|
||||
console.error('Erreur addYesterdayCheckbox:', err);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [dailyView]);
|
||||
|
||||
const updateCheckbox = useCallback((checkboxId: string, data: UpdateDailyCheckboxData): Promise<DailyCheckbox | null> => {
|
||||
if (!dailyView) return Promise.resolve(null);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
startTransition(async () => {
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
const result = await updateCheckboxAction(checkboxId, data);
|
||||
|
||||
if (result.success && result.data) {
|
||||
// Mise à jour optimiste
|
||||
setDailyView(prev => prev ? {
|
||||
...prev,
|
||||
yesterday: prev.yesterday.map(cb => cb.id === checkboxId ? result.data! : cb),
|
||||
today: prev.today.map(cb => cb.id === checkboxId ? result.data! : cb)
|
||||
} : null);
|
||||
resolve(result.data);
|
||||
} else {
|
||||
setError(result.error || 'Erreur lors de la mise à jour de la checkbox');
|
||||
resolve(null);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de la mise à jour de la checkbox');
|
||||
console.error('Erreur updateCheckbox:', err);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [dailyView]);
|
||||
|
||||
const deleteCheckbox = useCallback((checkboxId: string): Promise<void> => {
|
||||
if (!dailyView) return Promise.resolve();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
startTransition(async () => {
|
||||
const previousDailyView = dailyView;
|
||||
|
||||
// Mise à jour optimiste IMMÉDIATE - supprimer la checkbox
|
||||
@@ -233,27 +184,40 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
||||
} : null);
|
||||
|
||||
try {
|
||||
// Appel API en arrière-plan
|
||||
await dailyClient.deleteCheckbox(checkboxId);
|
||||
// Pas besoin de mise à jour supplémentaire, la suppression est déjà faite
|
||||
const result = await deleteCheckboxAction(checkboxId);
|
||||
|
||||
if (!result.success) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(result.error || 'Erreur lors de la suppression de la checkbox');
|
||||
}
|
||||
resolve();
|
||||
} catch (err) {
|
||||
// Rollback en cas d'erreur - restaurer la checkbox
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de la suppression de la checkbox');
|
||||
console.error('Erreur deleteCheckbox:', err);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [dailyView]);
|
||||
|
||||
const toggleCheckbox = useCallback(async (checkboxId: string): Promise<void> => {
|
||||
if (!dailyView) return;
|
||||
const toggleCheckbox = useCallback((checkboxId: string): Promise<void> => {
|
||||
if (!dailyView) return Promise.resolve();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
startTransition(async () => {
|
||||
// Trouver la checkbox dans yesterday ou today
|
||||
let checkbox = dailyView.yesterday.find(cb => cb.id === checkboxId);
|
||||
if (!checkbox) {
|
||||
checkbox = dailyView.today.find(cb => cb.id === checkboxId);
|
||||
}
|
||||
|
||||
if (!checkbox) return;
|
||||
if (!checkbox) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
// Mise à jour optimiste IMMÉDIATE
|
||||
const newCheckedState = !checkbox.isChecked;
|
||||
@@ -270,14 +234,23 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
||||
} : null);
|
||||
|
||||
try {
|
||||
// Appel API en arrière-plan
|
||||
await dailyClient.updateCheckbox(checkboxId, { isChecked: newCheckedState });
|
||||
const result = await toggleCheckboxAction(checkboxId);
|
||||
|
||||
if (!result.success) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(result.error || 'Erreur lors de la mise à jour de la checkbox');
|
||||
}
|
||||
resolve();
|
||||
} catch (err) {
|
||||
// Rollback en cas d'erreur
|
||||
setDailyView(previousDailyView);
|
||||
setError(err instanceof Error ? err.message : 'Erreur lors de la mise à jour de la checkbox');
|
||||
console.error('Erreur toggleCheckbox:', err);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [dailyView]);
|
||||
|
||||
const toggleAllToday = useCallback(async (): Promise<void> => {
|
||||
@@ -408,6 +381,7 @@ export function useDaily(initialDate?: Date, initialDailyView?: DailyView): UseD
|
||||
refreshing,
|
||||
error,
|
||||
saving,
|
||||
isPending,
|
||||
currentDate,
|
||||
|
||||
// Actions
|
||||
|
||||
223
src/actions/daily.ts
Normal file
223
src/actions/daily.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
'use server';
|
||||
|
||||
import { dailyService } from '@/services/daily';
|
||||
import { UpdateDailyCheckboxData, DailyCheckbox } from '@/lib/types';
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
/**
|
||||
* Toggle l'état d'une checkbox
|
||||
*/
|
||||
export async function toggleCheckbox(checkboxId: string): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
// Nous devons d'abord récupérer la checkbox pour connaître son état actuel
|
||||
// En absence de getCheckboxById, nous allons essayer de la trouver via une vue daily
|
||||
// Pour l'instant, nous allons simplement toggle via updateCheckbox
|
||||
// (le front-end gère déjà l'état optimiste)
|
||||
|
||||
// Récupérer toutes les checkboxes d'aujourd'hui et hier pour trouver celle à toggle
|
||||
const today = new Date();
|
||||
const dailyView = await dailyService.getDailyView(today);
|
||||
|
||||
let checkbox = dailyView.today.find(cb => cb.id === checkboxId);
|
||||
if (!checkbox) {
|
||||
checkbox = dailyView.yesterday.find(cb => cb.id === checkboxId);
|
||||
}
|
||||
|
||||
if (!checkbox) {
|
||||
return { success: false, error: 'Checkbox non trouvée' };
|
||||
}
|
||||
|
||||
// Toggle l'état
|
||||
const updatedCheckbox = await dailyService.updateCheckbox(checkboxId, {
|
||||
isChecked: !checkbox.isChecked
|
||||
});
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: updatedCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur toggleCheckbox:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox à une date donnée
|
||||
*/
|
||||
export async function addCheckboxToDaily(dailyId: string, content: string, taskId?: string): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
// Le dailyId correspond à la date au format YYYY-MM-DD
|
||||
const date = new Date(dailyId);
|
||||
|
||||
const newCheckbox = await dailyService.addCheckbox({
|
||||
date,
|
||||
text: content,
|
||||
taskId
|
||||
});
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: newCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur addCheckboxToDaily:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox pour aujourd'hui
|
||||
*/
|
||||
export async function addTodayCheckbox(content: string, taskId?: string): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
const newCheckbox = await dailyService.addCheckbox({
|
||||
date: new Date(),
|
||||
text: content,
|
||||
taskId
|
||||
});
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: newCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur addTodayCheckbox:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute une checkbox pour hier
|
||||
*/
|
||||
export async function addYesterdayCheckbox(content: string, taskId?: string): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
const yesterday = new Date();
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
|
||||
const newCheckbox = await dailyService.addCheckbox({
|
||||
date: yesterday,
|
||||
text: content,
|
||||
taskId
|
||||
});
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: newCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur addYesterdayCheckbox:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour le contenu d'une checkbox
|
||||
*/
|
||||
export async function updateCheckboxContent(checkboxId: string, content: string): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
const updatedCheckbox = await dailyService.updateCheckbox(checkboxId, {
|
||||
text: content
|
||||
});
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: updatedCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur updateCheckboxContent:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour une checkbox complète
|
||||
*/
|
||||
export async function updateCheckbox(checkboxId: string, data: UpdateDailyCheckboxData): Promise<{
|
||||
success: boolean;
|
||||
data?: DailyCheckbox;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
const updatedCheckbox = await dailyService.updateCheckbox(checkboxId, data);
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true, data: updatedCheckbox };
|
||||
} catch (error) {
|
||||
console.error('Erreur updateCheckbox:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime une checkbox
|
||||
*/
|
||||
export async function deleteCheckbox(checkboxId: string): Promise<{
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
await dailyService.deleteCheckbox(checkboxId);
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Erreur deleteCheckbox:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Réorganise les checkboxes d'une date
|
||||
*/
|
||||
export async function reorderCheckboxes(dailyId: string, checkboxIds: string[]): Promise<{
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}> {
|
||||
try {
|
||||
// Le dailyId correspond à la date au format YYYY-MM-DD
|
||||
const date = new Date(dailyId);
|
||||
|
||||
await dailyService.reorderCheckboxes(date, checkboxIds);
|
||||
|
||||
revalidatePath('/daily');
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
console.error('Erreur reorderCheckboxes:', error);
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Erreur inconnue'
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { dailyService } from '@/services/daily';
|
||||
|
||||
/**
|
||||
* API route pour mettre à jour une checkbox
|
||||
*/
|
||||
export async function PATCH(
|
||||
request: Request,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const { id: checkboxId } = await params;
|
||||
|
||||
const checkbox = await dailyService.updateCheckbox(checkboxId, body);
|
||||
return NextResponse.json(checkbox);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la mise à jour de la checkbox:', error);
|
||||
|
||||
if (error instanceof Error && error.message.includes('Record to update not found')) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Checkbox non trouvée' },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur interne du serveur' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API route pour supprimer une checkbox
|
||||
*/
|
||||
export async function DELETE(
|
||||
request: Request,
|
||||
{ params }: { params: Promise<{ id: string }> }
|
||||
) {
|
||||
try {
|
||||
const { id: checkboxId } = await params;
|
||||
|
||||
await dailyService.deleteCheckbox(checkboxId);
|
||||
return NextResponse.json({ success: true });
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors de la suppression de la checkbox:', error);
|
||||
|
||||
if (error instanceof Error && error.message.includes('Checkbox non trouvée')) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Checkbox non trouvée' },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur interne du serveur' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import { dailyService } from '@/services/daily';
|
||||
|
||||
/**
|
||||
* API route pour réordonner les checkboxes d'une date
|
||||
*/
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
|
||||
// Validation des données
|
||||
if (!body.date || !Array.isArray(body.checkboxIds)) {
|
||||
return NextResponse.json(
|
||||
{ error: 'date et checkboxIds (array) sont requis' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const date = new Date(body.date);
|
||||
if (isNaN(date.getTime())) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Format de date invalide. Utilisez YYYY-MM-DD' },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
await dailyService.reorderCheckboxes(date, body.checkboxIds);
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du réordonnancement:', error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur interne du serveur' },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user