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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user