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
130
131
132
|
import React from "react";
function ProgressBar(props: {
done: number;
total: number;
units: string;
color: string;
}) {
const { done, total, units, color } = props;
const width = Math.floor((done / total) * 100);
const rest = 100 - width;
let [fg, bg] = [`bg-${color}-600`, `bg-${color}-100`];
if (color === "white") {
[fg, bg] = ["bg-gray-600", "bg-gray-100"];
}
return (
<div className={`relative ${bg} h-5`}>
<div
className={`${fg} h-5 absolute top-0 left-0`}
style={{ width: `${width}%` }}
></div>
<p className="absolute text-xs pl-1 pt-1">
{done} of {total} {units}
</p>
</div>
);
}
function Goal(props: {
subject: string;
goal: string;
done: number;
total: number;
units: string;
color: string;
}) {
const { subject, goal, done, total, units, color } = props;
const width = "6em";
const Tr = (props: {
label: string;
value: string;
valueComponent?: React.ReactElement;
}) => (
<tr className="flex py-2">
<td className="text-gray-600" style={{ width: width }}>
{props.label}
</td>
<td className="flex-1">
{props.valueComponent ? props.valueComponent : props.value}
</td>
</tr>
);
return (
<table className="w-full mb-10">
<tbody>
<Tr label="Subject" value={subject} />
<Tr label="Goal" value={goal} />
<Tr
label="Progress"
value={goal}
valueComponent={
<ProgressBar
done={done}
total={total}
units={units}
color={color}
/>
}
/>
</tbody>
</table>
);
}
function Copy(props: { children: React.ReactNode }) {
return <p className="pb-4 leading-loose">{props.children}</p>;
}
function App() {
return (
<div className="container mx-auto font-mono">
<section>
<h1 className="text-center pt-12 pb-6">Goals</h1>
<Copy>
For me, a goal is something that is difficult for me to complete but
easy for me to measure. I tend to add new goals as time progresses,
mistakenly assuming that I can support additional goals for free. To
counterbalance my tendancy to casually accumulate goals, I aim to only
have three goals; I will not add a new goal until I complete an
existing goal. I created and published this page to clarify that idea.
</Copy>
<Copy>
Here are my current goals and the progress I have made towards
achieving them.
</Copy>
</section>
<section className="pt-4">
<Goal
subject="Meditation"
goal="Meditate for 10,000 hours"
done={100}
total={10000}
units="hrs"
color="purple"
/>
<Goal
subject="Debt"
goal="Pay my student debt balance"
done={30000}
total={70000}
units="USD"
color="green"
/>
<Goal
subject="Brazilian Jiu Jitsu"
goal="Train until an instructor gives me a black belt"
done={1}
total={5}
units="belts"
color="white"
/>
</section>
</div>
);
}
export default App;
|