about summary refs log tree commit diff
path: root/website/days-of-week-habits/src
diff options
context:
space:
mode:
Diffstat (limited to 'website/days-of-week-habits/src')
-rw-r--r--website/days-of-week-habits/src/App.tsx62
-rw-r--r--website/days-of-week-habits/src/index.css3
-rw-r--r--website/days-of-week-habits/src/index.html11
-rw-r--r--website/days-of-week-habits/src/index.tsx12
-rw-r--r--website/days-of-week-habits/src/store.ts151
5 files changed, 239 insertions, 0 deletions
diff --git a/website/days-of-week-habits/src/App.tsx b/website/days-of-week-habits/src/App.tsx
new file mode 100644
index 000000000000..61bfdfa8cd72
--- /dev/null
+++ b/website/days-of-week-habits/src/App.tsx
@@ -0,0 +1,62 @@
+import React, { useEffect } from "react";
+import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
+import { useDispatch } from "react-redux";
+import { actions, useTypedSelector } from "./store";
+import { Link } from "react-router-dom";
+import humanizeDuration from "humanize-duration";
+import type { Task, Habit } from "./store";
+
+const days = [
+  "Monday",
+  "Tuesday",
+  "Wednesday",
+  "Thursday",
+  "Friday",
+  "Saturday",
+  "Sunday",
+];
+
+const postItColor = "yellow";
+
+const PostIt = (props: { day: number; tasks: Task[] }) => (
+  <div className={`bg-${postItColor}-300 mr-2 mb-2 w-1/5 px-4 pb-4`}>
+    <h2 className="text-center py-4">{days[props.day]}</h2>
+    {props.tasks.map((task) => (
+      <ol key={task.label}>
+        <li className="py-2">
+          <span className={`text-${postItColor}-600 pr-2`}>
+            [{humanizeDuration(task.duration)}]
+          </span>
+          {task.label}
+        </li>
+      </ol>
+    ))}
+  </div>
+);
+
+const App: React.FC = () => {
+  const dispatch = useDispatch();
+  const { isLoading, habits } = useTypedSelector((state) => ({
+    isLoading: state.isLoading,
+    habits: state.habits,
+  }));
+
+  return (
+    <Router>
+      <Switch>
+        <Route exact path="/">
+          <div className="mx-auto font-mono">
+            <h1 className="text-center my-8">Habits</h1>
+            <ol className="flex">
+              {habits.map((habit) => (
+                <PostIt key={habit.day} day={habit.day} tasks={habit.tasks} />
+              ))}
+            </ol>
+          </div>
+        </Route>
+      </Switch>
+    </Router>
+  );
+};
+
+export default App;
diff --git a/website/days-of-week-habits/src/index.css b/website/days-of-week-habits/src/index.css
new file mode 100644
index 000000000000..b5c61c956711
--- /dev/null
+++ b/website/days-of-week-habits/src/index.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/website/days-of-week-habits/src/index.html b/website/days-of-week-habits/src/index.html
new file mode 100644
index 000000000000..91752af916a4
--- /dev/null
+++ b/website/days-of-week-habits/src/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="stylesheet" href="./index.css" />
+  </head>
+  <body>
+    <div id="mount"></div>
+    <script src="./index.tsx"></script>
+  </body>
+</html>
diff --git a/website/days-of-week-habits/src/index.tsx b/website/days-of-week-habits/src/index.tsx
new file mode 100644
index 000000000000..dc28dc4a9cc8
--- /dev/null
+++ b/website/days-of-week-habits/src/index.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+import ReactDOM from "react-dom";
+import App from "./App";
+import { Provider } from "react-redux";
+import store from "./store";
+
+ReactDOM.render(
+  <Provider store={store}>
+    <App />
+  </Provider>,
+  document.getElementById("mount")
+);
diff --git a/website/days-of-week-habits/src/store.ts b/website/days-of-week-habits/src/store.ts
new file mode 100644
index 000000000000..2bcb802580e6
--- /dev/null
+++ b/website/days-of-week-habits/src/store.ts
@@ -0,0 +1,151 @@
+import { createSlice, configureStore, PayloadAction } from "@reduxjs/toolkit";
+import { useSelector, TypedUseSelectorHook } from "react-redux";
+
+// Monday    0
+// Tuesday   1
+// Wednesday 2
+// Thursday  3
+// Friday    4
+// Saturday  5
+// Sunday    6
+type Day = number;
+
+export interface Task {
+  label: string;
+  // Number of milliseconds
+  duration: number;
+}
+
+export interface Habit {
+  day: Day;
+  tasks: Task[];
+}
+
+export interface State {
+  isLoading: boolean;
+  habits: Habit[];
+}
+
+const minute: number = 1000 * 60;
+const hour: number = minute * 60;
+
+/*******************************************************************************
+ * Tasks
+ ******************************************************************************/
+
+const jiuJitsu: Task = {
+  label: "Jiu Jitsu",
+  duration: hour,
+};
+
+const hotYoga: Task = {
+  label: "Hot Pod Yoga",
+  duration: hour,
+};
+
+const shave: Task = {
+  label: "Shave",
+  duration: 10 * minute,
+};
+
+const vacuum: Task = {
+  label: "Vacuum",
+  duration: 15 * minute,
+};
+
+const nap: Task = {
+  label: "Nap",
+  duration: hour,
+};
+
+const trimNails: Task = {
+  label: "Trim Nails",
+  duration: 5 * minute,
+};
+
+const trash: Task = {
+  label: "Take out trash",
+  duration: 5 * minute,
+};
+
+const scheduleLaundry: Task = {
+  label: "Schedule laundry pick-up",
+  duration: 5 * minute,
+};
+
+/*******************************************************************************
+ * Days
+ ******************************************************************************/
+
+const monday: Habit = {
+  day: 0,
+  tasks: [jiuJitsu],
+};
+
+const tuesday: Habit = {
+  day: 1,
+  tasks: [
+    {
+      label: "Work from 6PS",
+      duration: hour * 8,
+    },
+    jiuJitsu,
+  ],
+};
+
+const wednesday: Habit = {
+  day: 2,
+  tasks: [
+    hotYoga,
+    shave,
+    {
+      label: "Clean apartment sinks",
+      duration: 15 * minute,
+    },
+  ],
+};
+
+const thursday: Habit = {
+  day: 3,
+  tasks: [],
+};
+
+const friday: Habit = {
+  day: 4,
+  tasks: [hotYoga],
+};
+
+const saturday: Habit = {
+  day: 5,
+  tasks: [vacuum, nap],
+};
+
+const sunday: Habit = {
+  day: 6,
+  tasks: [jiuJitsu, nap, shave, trimNails, trash, scheduleLaundry],
+};
+
+/*******************************************************************************
+ * State
+ ******************************************************************************/
+
+const initialState: State = {
+  isLoading: true,
+  habits: [monday, tuesday, wednesday, thursday, friday, saturday, sunday],
+};
+
+export const { actions, reducer } = createSlice({
+  name: "application",
+  initialState,
+  reducers: {
+    toggleIsLoading: (state) => ({ ...state, isLoading: !state.isLoading }),
+  },
+});
+
+/**
+ * Defining and consuming this allows us to avoid annotating State in all of our
+ * selectors.
+ */
+export const useTypedSelector: TypedUseSelectorHook<State> = useSelector;
+
+export default configureStore({ reducer });