@@ -124,7 +124,7 @@ const TaskList = () => {
124124
125125 // 現在実行中のタスクを取得(start_timeがあってend_timeがないタスク)
126126 const currentRunningTask = tasks . find (
127- ( task ) => task . start_time && ! task . end_time
127+ ( task ) => task . start_time && ! task . end_time ,
128128 ) ;
129129
130130 // ドラッグ&ドロップのセンサーを設定
@@ -394,148 +394,148 @@ const TaskList = () => {
394394
395395 return (
396396 < >
397- < div className = "space-y-6 pb-20" >
398- < div className = "flex items-center justify-between" >
399- < div >
400- { totalEstimatedMinutes > 0 && (
401- < p className = "text-sm text-muted-foreground mt-1" >
402- { totalEstimatedMinutes > 0 && (
403- < span className = "ml-2" >
404- 完了予定: { calculateEndTime ( totalEstimatedMinutes ) }
405- </ span >
406- ) }
407- </ p >
408- ) }
409- </ div >
410- < div className = "text-right" >
411- < Popover >
412- < PopoverTrigger asChild >
413- < Button
414- variant = { "outline" }
415- className = { cn (
416- "w-[240px] justify-start text-left font-normal" ,
417- ! selectedDate && "text-muted-foreground" ,
418- ) }
419- >
420- < Calendar className = "mr-2 h-4 w-4" />
421- { selectedDate ? (
422- format ( selectedDate , "PPP" , { locale : ja } )
423- ) : (
424- < span > 日付を選択</ span >
397+ < div className = "space-y-6 pb-20" >
398+ < div className = "flex items-center justify-between" >
399+ < div >
400+ { totalEstimatedMinutes > 0 && (
401+ < p className = "text-sm text-muted-foreground mt-1" >
402+ { totalEstimatedMinutes > 0 && (
403+ < span className = "ml-2" >
404+ 完了予定: { calculateEndTime ( totalEstimatedMinutes ) }
405+ </ span >
425406 ) }
426- </ Button >
427- </ PopoverTrigger >
428- < PopoverContent className = "w-auto p-0" align = "end" >
429- < CalendarComponent
430- mode = "single"
431- selected = { selectedDate }
432- onSelect = { setSelectedDate }
433- initialFocus
434- locale = { ja }
435- />
436- </ PopoverContent >
437- </ Popover >
438- </ div >
439- </ div >
440-
441- { /* クイックタスク追加フォーム */ }
442- < Card className = "border-dashed border-2" >
443- < CardContent className = "pt-6" >
444- < div className = "flex gap-3" >
445- < div className = "relative flex-1" >
446- < Input
447- placeholder = "新しいタスク名を入力"
448- value = { newTaskTitle }
449- onChange = { handleTaskTitleChange }
450- onKeyDown = { handleNewTaskKeyDown }
451- className = "w-full"
452- onBlur = { ( ) => {
453- // 少し遅延してから非表示にする(クリックイベントを処理するため)
454- setTimeout ( ( ) => setShowSuggestions ( false ) , 200 ) ;
455- } }
456- onFocus = { ( ) => {
457- if ( taskSuggestions . length > 0 ) {
458- setShowSuggestions ( true ) ;
459- }
460- } }
461- />
462- { showSuggestions && taskSuggestions . length > 0 && (
463- < div className = "absolute top-full left-0 right-0 z-50 mt-1 bg-white border border-gray-200 rounded-md shadow-lg max-h-48 overflow-y-auto" >
464- { taskSuggestions . map ( ( suggestion , index ) => (
465- < div
466- key = { suggestion }
467- className = { cn (
468- "px-3 py-2 cursor-pointer hover:bg-gray-100" ,
469- selectedSuggestionIndex === index &&
470- "bg-blue-50 text-blue-600" ,
471- ) }
472- onClick = { ( ) => selectSuggestion ( suggestion ) }
473- >
474- { suggestion }
475- </ div >
476- ) ) }
477- </ div >
478- ) }
479- </ div >
480- < Button onClick = { handleAddTask } disabled = { ! newTaskTitle . trim ( ) } >
481- クイック追加
482- </ Button >
483- </ div >
484- </ CardContent >
485- </ Card >
486-
487- < Card >
488- < CardHeader >
489- < CardTitle > タスク一覧</ CardTitle >
490- </ CardHeader >
491- < CardContent >
492- < Suspense
493- fallback = {
494- < p className = "text-center text-muted-foreground" >
495- タスクを読み込み中...
496407 </ p >
497- }
498- >
499- < div className = "space-y-4" >
500- { tasks . length > 0 ? (
501- < DndContext
502- sensors = { sensors }
503- collisionDetection = { closestCenter }
504- onDragEnd = { handleDragEnd }
408+ ) }
409+ </ div >
410+ < div className = "text-right" >
411+ < Popover >
412+ < PopoverTrigger asChild >
413+ < Button
414+ variant = { "outline" }
415+ className = { cn (
416+ "w-[240px] justify-start text-left font-normal" ,
417+ ! selectedDate && "text-muted-foreground" ,
418+ ) }
505419 >
506- < SortableContext
507- items = { tasks . map ( ( task ) => task . id ) }
508- strategy = { verticalListSortingStrategy }
509- >
510- { tasks . map ( ( task ) => (
511- < SortableTask
512- key = { task . id }
513- task = { task }
514- taskEdit = { taskEdit }
515- taskActions = { taskActions }
516- lastTaskEndTime = { lastTaskEndTime }
517- categories = { categories }
518- />
420+ < Calendar className = "mr-2 h-4 w-4" />
421+ { selectedDate ? (
422+ format ( selectedDate , "PPP" , { locale : ja } )
423+ ) : (
424+ < span > 日付を選択</ span >
425+ ) }
426+ </ Button >
427+ </ PopoverTrigger >
428+ < PopoverContent className = "w-auto p-0" align = "end" >
429+ < CalendarComponent
430+ mode = "single"
431+ selected = { selectedDate }
432+ onSelect = { setSelectedDate }
433+ initialFocus
434+ locale = { ja }
435+ />
436+ </ PopoverContent >
437+ </ Popover >
438+ </ div >
439+ </ div >
440+
441+ { /* クイックタスク追加フォーム */ }
442+ < Card className = "border-dashed border-2" >
443+ < CardContent className = "pt-6" >
444+ < div className = "flex gap-3" >
445+ < div className = "relative flex-1" >
446+ < Input
447+ placeholder = "新しいタスク名を入力"
448+ value = { newTaskTitle }
449+ onChange = { handleTaskTitleChange }
450+ onKeyDown = { handleNewTaskKeyDown }
451+ className = "w-full"
452+ onBlur = { ( ) => {
453+ // 少し遅延してから非表示にする(クリックイベントを処理するため)
454+ setTimeout ( ( ) => setShowSuggestions ( false ) , 200 ) ;
455+ } }
456+ onFocus = { ( ) => {
457+ if ( taskSuggestions . length > 0 ) {
458+ setShowSuggestions ( true ) ;
459+ }
460+ } }
461+ />
462+ { showSuggestions && taskSuggestions . length > 0 && (
463+ < div className = "absolute top-full left-0 right-0 z-50 mt-1 bg-white border border-gray-200 rounded-md shadow-lg max-h-48 overflow-y-auto" >
464+ { taskSuggestions . map ( ( suggestion , index ) => (
465+ < div
466+ key = { suggestion }
467+ className = { cn (
468+ "px-3 py-2 cursor-pointer hover:bg-gray-100" ,
469+ selectedSuggestionIndex === index &&
470+ "bg-blue-50 text-blue-600" ,
471+ ) }
472+ onClick = { ( ) => selectSuggestion ( suggestion ) }
473+ >
474+ { suggestion }
475+ </ div >
519476 ) ) }
520- </ SortableContext >
521- </ DndContext >
522- ) : (
477+ </ div >
478+ ) }
479+ </ div >
480+ < Button onClick = { handleAddTask } disabled = { ! newTaskTitle . trim ( ) } >
481+ クイック追加
482+ </ Button >
483+ </ div >
484+ </ CardContent >
485+ </ Card >
486+
487+ < Card >
488+ < CardHeader >
489+ < CardTitle > タスク一覧</ CardTitle >
490+ </ CardHeader >
491+ < CardContent >
492+ < Suspense
493+ fallback = {
523494 < p className = "text-center text-muted-foreground" >
524- タスクが見つかりません
495+ タスクを読み込み中...
525496 </ p >
526- ) }
527- </ div >
528- </ Suspense >
529- </ CardContent >
530- </ Card >
531- </ div >
532-
533- { /* 現在実行中のタスクフッター */ }
534- < CurrentTaskFooter
535- currentTask = { currentRunningTask || null }
536- categories = { categories }
537- onTaskTimer = { taskActions . handleTaskTimer }
538- />
497+ }
498+ >
499+ < div className = "space-y-4" >
500+ { tasks . length > 0 ? (
501+ < DndContext
502+ sensors = { sensors }
503+ collisionDetection = { closestCenter }
504+ onDragEnd = { handleDragEnd }
505+ >
506+ < SortableContext
507+ items = { tasks . map ( ( task ) => task . id ) }
508+ strategy = { verticalListSortingStrategy }
509+ >
510+ { tasks . map ( ( task ) => (
511+ < SortableTask
512+ key = { task . id }
513+ task = { task }
514+ taskEdit = { taskEdit }
515+ taskActions = { taskActions }
516+ lastTaskEndTime = { lastTaskEndTime }
517+ categories = { categories }
518+ />
519+ ) ) }
520+ </ SortableContext >
521+ </ DndContext >
522+ ) : (
523+ < p className = "text-center text-muted-foreground" >
524+ タスクが見つかりません
525+ </ p >
526+ ) }
527+ </ div >
528+ </ Suspense >
529+ </ CardContent >
530+ </ Card >
531+ </ div >
532+
533+ { /* 現在実行中のタスクフッター */ }
534+ < CurrentTaskFooter
535+ currentTask = { currentRunningTask || null }
536+ categories = { categories }
537+ onTaskTimer = { taskActions . handleTaskTimer }
538+ />
539539 </ >
540540 ) ;
541541} ;
0 commit comments