about summary refs log tree commit diff
path: root/users/wpcarro/website/goals/src/App.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'users/wpcarro/website/goals/src/App.tsx')
-rw-r--r--users/wpcarro/website/goals/src/App.tsx132
1 files changed, 132 insertions, 0 deletions
diff --git a/users/wpcarro/website/goals/src/App.tsx b/users/wpcarro/website/goals/src/App.tsx
new file mode 100644
index 0000000000..53195d9af9
--- /dev/null
+++ b/users/wpcarro/website/goals/src/App.tsx
@@ -0,0 +1,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;