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
/** @jsxImportSource https://esm.sh/react */
import confetti from "https://esm.sh/canvas-confetti@1.6.0";
import React, { useEffect, useState } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
const routineTasks = [
{ name: "Feed fish", timed: false },
{ name: "Unpack bags", timed: false },
{ name: "Do homework", timed: false },
{ name: "Get mom or dad to check homework", timed: false, requiresParent: true },
{ name: "Return homework folder to backpack", timed: false },
{ name: "Clean table of homework items", timed: false },
{ name: "Move your stuff from living room to bedroom", timed: false },
{ name: "Clean room", timed: true, duration: 10 * 60 },
{ name: "Take a shower", timed: false },
{ name: "Clean up shower", timed: false },
{ name: "Eat dinner", timed: false },
{ name: "Brush teeth", timed: true, duration: 2 * 60 },
{ name: "Get clothes ready for tomorrow", timed: false },
{ name: "Get mom or dad to check my list", timed: false, requiresParent: true },
];
// Simple hash function for the password
const simpleHash = (str) => {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32-bit integer
}
return hash;
};
// You would set this to a hashed version of your actual password
const PARENT_PASSWORD_HASH = simpleHash("1234"); // Example password
const TimerComponent = ({ duration, onComplete }) => {
const [timeLeft, setTimeLeft] = useState(duration);
const [isRunning, setIsRunning] = useState(false);
useEffect(() => {
let timer;
if (isRunning && timeLeft > 0) {
timer = setInterval(() => {
setTimeLeft((prevTime) => {
if (prevTime <= 1) {
clearInterval(timer);
setIsRunning(false);
onComplete();
return 0;
}
return prevTime - 1;
});
}, 1000);
}
return () => clearInterval(timer);
}, [isRunning, timeLeft, onComplete]);
const toggleTimer = () => setIsRunning(!isRunning);
const resetTimer = () => {
setIsRunning(false);
setTimeLeft(duration);
};
const minutes = Math.floor(timeLeft / 60);
const seconds = timeLeft % 60;
return (
<div className="flex items-center space-x-2">
<span>{`${minutes}:${seconds.toString().padStart(2, "0")}`}</span>
<button onClick={toggleTimer} className="p-1 rounded-full bg-gray-200 hover:bg-gray-300">
{isRunning ? "⏸️" : "▶️"}
</button>
<button onClick={resetTimer} className="p-1 rounded-full bg-gray-200 hover:bg-gray-300">
🔄
</button>
</div>
);
};
function App() {
const [completedTasks, setCompletedTasks] = useState([]);
const [timerStates, setTimerStates] = useState(routineTasks.map(task => ({
isComplete: false,
timeLeft: task.timed ? task.duration : 0,
})));
const [parentPassword, setParentPassword] = useState("");
const [showPasswordPrompt, setShowPasswordPrompt] = useState(false);
const [currentTaskIndex, setCurrentTaskIndex] = useState(null);
const [passwordError, setPasswordError] = useState(false);
const shootConfetti = () => {
const count = 500;
const defaults = {
origin: { y: 0.7 },
shapes: ["star"],
ticks: 300,
};
function fire(particleRatio, opts) {