feat: enhance DailyClient and useDaily hook for improved checkbox handling

- Added new API response types (`ApiCheckbox`, `ApiDailyView`, `ApiHistoryItem`) for better type safety.
- Updated `getTodaysDailyView`, `getDailyView`, and `getHistory` methods to utilize new types and transform date strings into Date objects.
- Refactored `addCheckbox` and `updateCheckbox` methods to handle checkbox creation and updates with improved error handling.
- Optimized `DailyAddForm` for better UX by removing unnecessary loading states and implementing optimistic UI updates.
- Enhanced `useDaily` hook to support checkbox type management and rollback on errors during updates.
- Updated `DailyPageClient` to leverage new checkbox handling methods for adding tasks.
This commit is contained in:
Julien Froidefond
2025-09-15 22:30:56 +02:00
parent adfef551ab
commit 4b27047e63
4 changed files with 239 additions and 107 deletions

View File

@@ -14,25 +14,23 @@ interface DailyAddFormProps {
export function DailyAddForm({ onAdd, disabled = false, placeholder = "Ajouter une tâche..." }: DailyAddFormProps) {
const [newCheckboxText, setNewCheckboxText] = useState('');
const [selectedType, setSelectedType] = useState<DailyCheckboxType>('task');
const [addingCheckbox, setAddingCheckbox] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const handleAddCheckbox = async () => {
const handleAddCheckbox = () => {
if (!newCheckboxText.trim()) return;
setAddingCheckbox(true);
try {
await onAdd(newCheckboxText.trim(), selectedType); // Pas de taskId lors de l'ajout
setNewCheckboxText('');
// Garder le type sélectionné pour enchaîner les créations du même type
// setSelectedType('task'); // <- Supprimé pour garder la sélection
// Garder le focus sur l'input pour enchainer les entrées
setTimeout(() => {
inputRef.current?.focus();
}, 100);
} finally {
setAddingCheckbox(false);
}
const text = newCheckboxText.trim();
// Vider et refocus IMMÉDIATEMENT pour l'UX optimiste
setNewCheckboxText('');
inputRef.current?.focus();
// Lancer l'ajout en arrière-plan (fire and forget)
onAdd(text, selectedType).catch(error => {
console.error('Erreur lors de l\'ajout:', error);
// En cas d'erreur, on pourrait restaurer le texte
// setNewCheckboxText(text);
});
};
const handleKeyPress = (e: React.KeyboardEvent) => {
@@ -61,7 +59,7 @@ export function DailyAddForm({ onAdd, disabled = false, placeholder = "Ajouter u
? 'border-l-green-500 bg-green-100 dark:bg-green-900/40 text-green-900 dark:text-green-100 font-medium'
: 'border-l-green-300 hover:border-l-green-400 opacity-70 hover:opacity-90'
}`}
disabled={addingCheckbox || disabled}
disabled={disabled}
>
Tâche
</Button>
@@ -75,7 +73,7 @@ export function DailyAddForm({ onAdd, disabled = false, placeholder = "Ajouter u
? 'border-l-blue-500 bg-blue-100 dark:bg-blue-900/40 text-blue-900 dark:text-blue-100 font-medium'
: 'border-l-blue-300 hover:border-l-blue-400 opacity-70 hover:opacity-90'
}`}
disabled={addingCheckbox || disabled}
disabled={disabled}
>
🗓 Réunion
</Button>
@@ -90,17 +88,17 @@ export function DailyAddForm({ onAdd, disabled = false, placeholder = "Ajouter u
value={newCheckboxText}
onChange={(e) => setNewCheckboxText(e.target.value)}
onKeyDown={handleKeyPress}
disabled={addingCheckbox || disabled}
disabled={disabled}
className="flex-1 min-w-[300px]"
/>
<Button
onClick={handleAddCheckbox}
disabled={!newCheckboxText.trim() || addingCheckbox || disabled}
disabled={!newCheckboxText.trim() || disabled}
variant="primary"
size="sm"
className="min-w-[40px]"
>
{addingCheckbox ? '...' : '+'}
+
</Button>
</div>
</div>