Compare commits

..

2 Commits

View File

@@ -35,7 +35,14 @@ export const TodoPage: React.FC = () => {
const [addingDate, setAddingDate] = useState<string | null>(null)
const [newTodoContent, setNewTodoContent] = useState('')
const [isInitialLoad, setIsInitialLoad] = useState(true)
const inputRef = useRef<HTMLInputElement>(null)
const inputRef = useRef<HTMLTextAreaElement>(null)
const editInputRef = useRef<HTMLTextAreaElement>(null)
const adjustTextAreaHeight = (el: HTMLTextAreaElement) => {
const baseHeight = 28 // 1.75rem = 28px
el.style.height = baseHeight + 'px'
el.style.height = Math.max(el.scrollHeight, baseHeight) + 'px'
}
const loadTodoData = useCallback(async (year: number, month: number, isInitial: boolean = false) => {
if (isInitial) {
@@ -62,9 +69,16 @@ export const TodoPage: React.FC = () => {
useEffect(() => {
if (addingDate && inputRef.current) {
inputRef.current.focus()
adjustTextAreaHeight(inputRef.current)
}
}, [addingDate])
useEffect(() => {
if (editingItem && editInputRef.current) {
adjustTextAreaHeight(editInputRef.current)
}
}, [editingItem])
const handlePrevMonth = () => {
if (currentMonth === 1) {
setCurrentMonth(12)
@@ -134,7 +148,18 @@ export const TodoPage: React.FC = () => {
if (!editingItem) return
const { date, index } = editingItem
const newContent = editContent.trim()
if (!newContent) return
if (!newContent) {
try {
const data = await deleteTodoItem(currentYear, currentMonth, date, index)
setDayTodos(data.dayTodos)
} catch (error) {
console.error('Failed to delete TODO:', error)
} finally {
setEditingItem(null)
setEditContent('')
}
return
}
try {
const data = await updateTodoItem(currentYear, currentMonth, date, index, newContent)
@@ -266,11 +291,11 @@ export const TodoPage: React.FC = () => {
)}
</div>
<div className="pl-2 space-y-1">
<div className="pl-2 space-y-2">
{dayTodo?.items.map((item, index) => (
<div
key={item.id}
className="flex items-center gap-3 group h-7"
className="flex items-center gap-3 group"
>
<button
onClick={() => canEdit && handleToggleTodo(date, index, !item.completed)}
@@ -288,18 +313,23 @@ export const TodoPage: React.FC = () => {
</button>
{editingItem?.date === date && editingItem?.index === index ? (
<input
type="text"
<textarea
ref={editInputRef}
value={editContent}
onChange={(e) => setEditContent(e.target.value)}
onChange={(e) => {
setEditContent(e.target.value)
adjustTextAreaHeight(e.target)
}}
onKeyDown={handleEditKeyDown}
onBlur={handleSaveEdit}
autoFocus
className="flex-1 px-2 py-0.5 bg-transparent border border-gray-300 dark:border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-gray-400 text-gray-800 dark:text-gray-200"
rows={1}
className="flex-1 px-2 bg-transparent border border-gray-300 dark:border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-gray-400 text-gray-800 dark:text-gray-200 resize-none overflow-hidden align-top"
style={{ height: '1.75rem' }}
/>
) : (
<span
onDoubleClick={() => canEdit && handleStartEdit(date, index, item.content)}
onDoubleClick={() => canEdit && !item.completed && handleStartEdit(date, index, item.content)}
className={`flex-1 ${canEdit ? 'cursor-pointer' : 'cursor-default'
} ${item.completed
? 'text-gray-400 dark:text-gray-500 line-through'
@@ -310,7 +340,7 @@ export const TodoPage: React.FC = () => {
</span>
)}
{canEdit && (
{canEdit && !item.completed && (
<button
onClick={() => handleDeleteTodo(date, index)}
className="p-1 opacity-0 group-hover:opacity-100 hover:bg-red-100 dark:hover:bg-red-900/30 rounded transition-all text-red-500"
@@ -322,19 +352,23 @@ export const TodoPage: React.FC = () => {
))}
{canEdit && addingDate === date && (
<div className="flex items-center gap-3 h-7">
<div className="flex items-center gap-3">
<div className="w-4 h-4 rounded-full border-2 border-gray-400 dark:border-gray-500 shrink-0" />
<input
<textarea
ref={inputRef}
type="text"
value={newTodoContent}
onChange={(e) => setNewTodoContent(e.target.value)}
onChange={(e) => {
setNewTodoContent(e.target.value)
adjustTextAreaHeight(e.target)
}}
onKeyDown={(e) => handleKeyDown(e, date)}
onBlur={() => {
handleAddTodo(date, false)
}}
placeholder="输入任务内容..."
className="flex-1 px-2 py-0.5 bg-transparent border border-gray-300 dark:border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-gray-400 text-gray-800 dark:text-gray-200 placeholder-gray-400"
rows={1}
className="flex-1 px-2 bg-transparent border border-gray-300 dark:border-gray-600 rounded focus:outline-none focus:ring-2 focus:ring-gray-400 text-gray-800 dark:text-gray-200 placeholder-gray-400 resize-none overflow-hidden align-top"
style={{ height: '1.75rem' }}
/>
</div>
)}