-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCurrentTaskFooter.tsx
More file actions
129 lines (116 loc) · 3.8 KB
/
CurrentTaskFooter.tsx
File metadata and controls
129 lines (116 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { useEffect, useState } from "react";
import { Task, Category } from "@/types/task";
import { Square, Pause } from "lucide-react";
import { Button } from "@/components/ui/button";
import { formatTimeAsHHmm } from "@/lib/utils";
interface CurrentTaskFooterProps {
currentTask: Task | null;
categories: Category[];
onTaskTimer: (taskId: string, action: "start" | "stop" | "complete") => void;
onPauseTask: (task: Task) => void;
}
export const CurrentTaskFooter = ({
currentTask,
categories,
onTaskTimer,
onPauseTask,
}: CurrentTaskFooterProps) => {
const [currentTime, setCurrentTime] = useState(new Date());
const [elapsedTime, setElapsedTime] = useState(0);
// 1秒ごとに現在時刻を更新
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(new Date());
}, 1000);
return () => clearInterval(timer);
}, []);
// 経過時間を計算
useEffect(() => {
if (currentTask?.start_time) {
const startTime = new Date(currentTask.start_time);
const elapsed = Math.floor(
(currentTime.getTime() - startTime.getTime()) / 1000,
);
setElapsedTime(elapsed);
} else {
setElapsedTime(0);
}
}, [currentTask?.start_time, currentTime]);
// 経過時間をフォーマット
const formatElapsedTime = (seconds: number) => {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
if (hours > 0) {
return `${hours}:${minutes.toString().padStart(2, "0")}:${secs.toString().padStart(2, "0")}`;
}
return `${minutes}:${secs.toString().padStart(2, "0")}`;
};
if (!currentTask) {
return null;
}
const category = categories.find((cat) => cat.id === currentTask.category_id);
const categoryColor = category?.color || "#6b7280";
return (
<div
className="fixed bottom-0 left-0 right-0 bg-white border-t shadow-lg p-4 z-50"
style={{ borderTopColor: categoryColor }}
>
<div className="max-w-4xl mx-auto flex items-center justify-between">
<div className="flex items-center gap-4">
<div
className="w-3 h-3 rounded-full animate-pulse"
style={{ backgroundColor: categoryColor }}
/>
<div>
<p className="font-medium text-gray-900">{currentTask.title}</p>
<div className="flex items-center gap-2 text-sm text-gray-600">
{category && (
<span style={{ color: categoryColor }}>{category.name}</span>
)}
<span>•</span>
<span>開始: {formatTimeAsHHmm(currentTask.start_time!)}</span>
</div>
</div>
</div>
<div className="flex items-center gap-4">
<div className="text-right">
<p
className="text-2xl font-mono font-bold"
style={{ color: categoryColor }}
>
{formatElapsedTime(elapsedTime)}
</p>
<p className="text-xs text-gray-500">経過時間</p>
</div>
<Button
size="sm"
variant="outline"
onClick={() => onPauseTask(currentTask)}
className="hover:bg-orange-50"
style={{
color: "#ea580c",
borderColor: "#ea580c",
}}
>
<Pause className="h-4 w-4 mr-1" />
中断
</Button>
<Button
size="sm"
variant="outline"
onClick={() => onTaskTimer(currentTask.id, "stop")}
className="hover:bg-red-50"
style={{
color: "#dc2626",
borderColor: "#dc2626",
}}
>
<Square className="h-4 w-4 mr-1" />
停止
</Button>
</div>
</div>
</div>
);
};