feat(gif-mood): drag-and-drop reorder + note footer centering

- Add drag-and-drop reordering (dnd-kit/sortable) for current user's GIFs with optimistic updates
- Add reorderGifMoodItems service + action with SSE broadcast
- Fix item sort order: orderBy order asc instead of createdAt
- Note footer: auto-resize textarea, vertically centered (1 or 2 lines), default 4 columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 16:32:21 +01:00
parent dc1cc47f18
commit ab00627a09
4 changed files with 221 additions and 33 deletions

View File

@@ -1,6 +1,6 @@
'use client';
import { memo, useState, useTransition } from 'react';
import { memo, useRef, useEffect, useState, useTransition } from 'react';
import { updateGifMoodItem, deleteGifMoodItem } from '@/actions/gif-mood';
import { IconClose } from '@/components/ui';
@@ -26,6 +26,14 @@ export const GifMoodCard = memo(function GifMoodCard({
const [itemVersion, setItemVersion] = useState(item);
const [isPending, startTransition] = useTransition();
const [imgError, setImgError] = useState(false);
const textareaRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
const el = textareaRef.current;
if (!el) return;
el.style.height = 'auto';
el.style.height = el.scrollHeight + 'px';
}, [note]);
if (itemVersion !== item) {
setItemVersion(item);
@@ -90,20 +98,21 @@ export const GifMoodCard = memo(function GifMoodCard({
{/* Note */}
{canEditThis ? (
<div className="px-3 pt-2 pb-3 bg-card">
<div className="px-3 bg-card flex items-center justify-center min-h-[2.75rem]">
<textarea
ref={textareaRef}
value={note}
onChange={(e) => setNote(e.target.value)}
onBlur={handleNoteBlur}
placeholder="Ajouter une note…"
rows={1}
className="w-full text-foreground/70 bg-transparent resize-none outline-none placeholder:text-muted/40 leading-relaxed text-center"
style={{ fontFamily: 'var(--font-caveat)', fontSize: '1.2rem' }}
className="w-full text-foreground/70 bg-transparent resize-none outline-none placeholder:text-muted/40 leading-snug text-center overflow-hidden"
style={{ fontFamily: 'var(--font-caveat)', fontSize: '1rem' }}
/>
</div>
) : note ? (
<div className="px-3 py-2.5 bg-card">
<p className="text-foreground/70 leading-relaxed text-center" style={{ fontFamily: 'var(--font-caveat)', fontSize: '1.2rem' }}>{note}</p>
<div className="px-3 bg-card flex items-center justify-center min-h-[2.75rem]">
<p className="text-foreground/70 leading-snug text-center" style={{ fontFamily: 'var(--font-caveat)', fontSize: '1rem' }}>{note}</p>
</div>
) : null}
</div>