refactor(ui): unify low-level controls and expand design system
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m57s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 2m57s
This commit is contained in:
@@ -4,7 +4,7 @@ import { forwardRef, useState, useTransition, useRef, ReactNode } from 'react';
|
||||
import type { WeeklyCheckInCategory } from '@prisma/client';
|
||||
import { createWeeklyCheckInItem } from '@/actions/weekly-checkin';
|
||||
import { WEEKLY_CHECK_IN_BY_CATEGORY, EMOTION_BY_TYPE } from '@/lib/types';
|
||||
import { IconPlus, InlineFormActions } from '@/components/ui';
|
||||
import { IconPlus, InlineAddItem } from '@/components/ui';
|
||||
import { Select } from '@/components/ui/Select';
|
||||
|
||||
interface WeeklyCheckInSectionProps {
|
||||
@@ -44,17 +44,6 @@ export const WeeklyCheckInSection = forwardRef<HTMLDivElement, WeeklyCheckInSect
|
||||
});
|
||||
}
|
||||
|
||||
function handleKeyDown(e: React.KeyboardEvent) {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
handleAdd();
|
||||
} else if (e.key === 'Escape') {
|
||||
setIsAdding(false);
|
||||
setNewContent('');
|
||||
setNewEmotion('NONE');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
@@ -93,53 +82,31 @@ export const WeeklyCheckInSection = forwardRef<HTMLDivElement, WeeklyCheckInSect
|
||||
|
||||
{/* Add Form */}
|
||||
{isAdding && (
|
||||
<div
|
||||
className="rounded-lg border border-border bg-card p-2 shadow-sm"
|
||||
onBlur={(e) => {
|
||||
// Don't close if focus moves to another element in this container
|
||||
const currentTarget = e.currentTarget;
|
||||
const relatedTarget = e.relatedTarget as Node | null;
|
||||
if (relatedTarget && currentTarget.contains(relatedTarget)) {
|
||||
return;
|
||||
}
|
||||
// Only add on blur if content is not empty
|
||||
if (newContent.trim()) {
|
||||
handleAdd();
|
||||
} else {
|
||||
setIsAdding(false);
|
||||
setNewContent('');
|
||||
setNewEmotion('NONE');
|
||||
}
|
||||
<InlineAddItem
|
||||
value={newContent}
|
||||
onChange={setNewContent}
|
||||
onSubmit={handleAdd}
|
||||
onCancel={() => {
|
||||
setIsAdding(false);
|
||||
setNewContent('');
|
||||
setNewEmotion('NONE');
|
||||
}}
|
||||
>
|
||||
<textarea
|
||||
autoFocus
|
||||
value={newContent}
|
||||
onChange={(e) => setNewContent(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder={`Décrivez ${config.title.toLowerCase()}...`}
|
||||
className="w-full resize-none rounded border-0 bg-transparent p-1 text-sm text-foreground placeholder:text-muted focus:outline-none focus:ring-0"
|
||||
rows={2}
|
||||
disabled={isPending}
|
||||
/>
|
||||
<div className="mt-2 flex items-center justify-between gap-2">
|
||||
isPending={isPending}
|
||||
placeholder={`Décrivez ${config.title.toLowerCase()}...`}
|
||||
extra={
|
||||
<div className="mt-2">
|
||||
<Select
|
||||
value={newEmotion}
|
||||
onChange={(e) => setNewEmotion(e.target.value as typeof newEmotion)}
|
||||
className="text-xs flex-1"
|
||||
className="text-xs"
|
||||
options={Object.values(EMOTION_BY_TYPE).map((em) => ({
|
||||
value: em.emotion,
|
||||
label: `${em.icon} ${em.label}`,
|
||||
}))}
|
||||
/>
|
||||
<InlineFormActions
|
||||
onCancel={() => { setIsAdding(false); setNewContent(''); setNewEmotion('NONE'); }}
|
||||
onSubmit={handleAdd}
|
||||
isPending={isPending}
|
||||
disabled={!newContent.trim()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user