From 593ab2d7d4ef972594131b125d9320c618e54691 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adri=C3=A1n=20Oliva?= <adrian.oliva@cimat.mx>
Date: Wed, 17 May 2023 21:26:50 -0600
Subject: Redux used to add ToDos

WE MADE IT!! I don't know how, but it is functional. :'3
---
 src/App.jsx                          |   9 +-
 src/ToDo-UI/NewToDo.jsx              | 126 -------------------
 src/ToDo-UI/ToDoList.jsx             |  69 -----------
 src/app/store.js                     |  12 +-
 src/features/counter/Counter.jsx     |  30 -----
 src/features/counter/counterSlice.js |  25 ----
 src/features/todo/ToDo.jsx           | 233 +++++++++++++++++++++++++++++++++++
 src/features/todo/reducer.js         |  32 +++++
 8 files changed, 274 insertions(+), 262 deletions(-)
 delete mode 100644 src/ToDo-UI/NewToDo.jsx
 delete mode 100644 src/ToDo-UI/ToDoList.jsx
 delete mode 100644 src/features/counter/Counter.jsx
 delete mode 100644 src/features/counter/counterSlice.js
 create mode 100644 src/features/todo/ToDo.jsx
 create mode 100644 src/features/todo/reducer.js

(limited to 'src')

diff --git a/src/App.jsx b/src/App.jsx
index a151a22..625d6ae 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,16 +1,13 @@
 import React from "react";
-import { Counter } from "./features/counter/Counter";
+// import { Counter } from "./features/counter/Counter";
 import { Search } from "./ToDo-UI/Search";
-import { NewToDo } from "./ToDo-UI/NewToDo";
-import { ToDoList } from "./ToDo-UI/ToDoList";
+import { Reducer } from "./features/todo/ToDo";
 
 function App() {
     return (
         <div>
             <Search />
-            <NewToDo />
-            <ToDoList />
-            <Counter />
+            <Reducer />
         </div>
     );
 }
diff --git a/src/ToDo-UI/NewToDo.jsx b/src/ToDo-UI/NewToDo.jsx
deleted file mode 100644
index e5c1652..0000000
--- a/src/ToDo-UI/NewToDo.jsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import React from "react";
-
-export function NewToDo() {
-    return (
-        <>
-            <div className="container mt-3 mb-3">
-                <button
-                    type="button"
-                    className="btn btn-outline-dark"
-                    data-bs-toggle="modal"
-                    data-bs-target="#NewToDo"
-                >
-                    + New To Do
-                </button>
-            </div>
-
-            <div
-                className="modal fade"
-                id="NewToDo"
-                tabIndex="-1"
-                role="dialog"
-                aria-labelledby="New To Do Window"
-                aria-hidden="true"
-            >
-                <div
-                    className="modal-dialog modal-dialog-centered"
-                    role="document"
-                >
-                    <div className="modal-content">
-                        <div className="modal-header">
-                            <h5
-                                className="modal-title"
-                                id="exampleModalLongTitle"
-                            >
-                                Add a new to do
-                            </h5>
-                            <button
-                                type="button"
-                                className="close"
-                                data-bs-dismiss="modal"
-                                aria-label="Close"
-                            >
-                                <span aria-hidden="true">&times;</span>
-                            </button>
-                        </div>
-                        <div className="modal-body">
-                            <form>
-                                <div className="form-floating mb-3">
-                                    <input
-                                        className="form-control"
-                                        id="new-todo-id"
-                                        value="4"
-                                        disabled
-                                    />
-                                    <label htmlFor="floatingInput">ID</label>
-                                </div>
-                                <div className="form-floating mb-3">
-                                    <input
-                                        className="form-control"
-                                        placeholder="Text"
-                                        id="new-todo-text"
-                                    />
-                                    <label htmlFor="floatingInput">Text</label>
-                                </div>
-                                <div className="input-group mb-3">
-                                    <span className="input-group-text">
-                                        <i className="fa-regular fa-calendar"></i>
-                                    </span>
-                                    <div className="form-floating">
-                                        <input
-                                            className="form-control"
-                                            id="new-todo-due-date"
-                                            name="new-todo-due-date"
-                                            placeholder="Due date"
-                                        />
-                                        <label htmlFor="floatingInput">
-                                            Due Date
-                                        </label>
-                                    </div>
-                                </div>
-                                <div class="form-check mb-3">
-                                    <input
-                                        class="form-check-input"
-                                        type="checkbox"
-                                        value=""
-                                        id="flexCheckDefault"
-                                    />
-                                    <label
-                                        class="form-check-label"
-                                        for="flexCheckDefault"
-                                    >
-                                        Done
-                                    </label>
-                                </div>
-                                <div class="form-floating mb-3">
-                                    <select
-                                        class="form-select"
-                                        id="floatingSelect"
-                                        aria-label="Floating label select example"
-                                    >
-                                        <option selected>Low</option>
-                                        <option value="1">Medium</option>
-                                        <option value="2">High</option>
-                                    </select>
-                                    <label for="floatingSelect">Priority</label>
-                                </div>
-                            </form>
-                        </div>
-                        <div className="modal-footer">
-                            <button
-                                type="button"
-                                className="btn btn-secondary"
-                                data-bs-dismiss="modal"
-                            >
-                                Cancel
-                            </button>
-                            <button type="button" className="btn btn-primary">
-                                Add
-                            </button>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </>
-    );
-}
diff --git a/src/ToDo-UI/ToDoList.jsx b/src/ToDo-UI/ToDoList.jsx
deleted file mode 100644
index c6b2d92..0000000
--- a/src/ToDo-UI/ToDoList.jsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import React from "react";
-
-export function ToDoList() {
-    const todos = [
-        {
-            id: 1,
-            text: "Finish homework.",
-            due_date: "2023/05/29",
-            done: false,
-            priority: "high",
-            creation_date: "2023/05/11",
-        },
-    ];
-
-    return (
-        <div className="container">
-            <table className="table align-middle">
-                <thead>
-                    <tr>
-                        <th scope="col">#</th>
-                        <th scope="col">Name</th>
-                        <th scope="col">Priority</th>
-                        <th scope="col">Due Date</th>
-                        <th scope="col">Actions</th>
-                    </tr>
-                </thead>
-                <tbody className="table-group-divider">
-                    {todos.map((item) => (
-                        <tr>
-                            <th scope="row">
-                                <div className="form-check">
-                                    <input
-                                        className="form-check-input"
-                                        type="checkbox"
-                                        value={item.done ? "checked" : ""}
-                                        id="flexCheckChecked"
-                                    ></input>
-                                </div>
-                            </th>
-                            <td>{item.text}</td>
-                            <td>{item.priority}</td>
-                            <td>{item.due_date}</td>
-                            <td>
-                                <div
-                                    className="btn-group btn-group-sm"
-                                    role="group"
-                                    aria-label="Basic example"
-                                >
-                                    <button
-                                        type="button"
-                                        className="btn btn-outline-dark"
-                                    >
-                                        Edit
-                                    </button>
-                                    <button
-                                        type="button"
-                                        className="btn btn-outline-dark"
-                                    >
-                                        Delete
-                                    </button>
-                                </div>
-                            </td>
-                        </tr>
-                    ))}
-                </tbody>
-            </table>
-        </div>
-    );
-}
diff --git a/src/app/store.js b/src/app/store.js
index 012eb09..fc53cd1 100644
--- a/src/app/store.js
+++ b/src/app/store.js
@@ -1,8 +1,8 @@
-import { configureStore } from '@reduxjs/toolkit'
-import counterReducer from '../features/counter/counterSlice'
+import { configureStore } from "@reduxjs/toolkit";
+import todo_reducer from "../features/todo/reducer";
 
 export const store = configureStore({
-  reducer: {
-    counter: counterReducer,
-  },
-})
+    reducer: {
+        todo_list: todo_reducer,
+    },
+});
diff --git a/src/features/counter/Counter.jsx b/src/features/counter/Counter.jsx
deleted file mode 100644
index b8453b2..0000000
--- a/src/features/counter/Counter.jsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import React from 'react'
-import { useSelector, useDispatch } from 'react-redux'
-import { decrement, increment } from './counterSlice'
-
-export function Counter() {
-  const count = useSelector((state) => state.counter.value)
-  const dispatch = useDispatch()
-
-  return (
-    <div>
-      <h1>{count}</h1>
-      <div>
-        <button
-          aria-label="Increment value"
-          onClick={() => dispatch(increment())}
-          className='btn btn-outline-primary'
-        >
-          Increment
-        </button>
-        <button
-          aria-label="Decrement value"
-          onClick={() => dispatch(decrement())}
-          className='btn btn-outline-primary'
-        >
-          Decrement
-        </button>
-      </div>
-    </div>
-  )
-}
diff --git a/src/features/counter/counterSlice.js b/src/features/counter/counterSlice.js
deleted file mode 100644
index 4cb9993..0000000
--- a/src/features/counter/counterSlice.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { createSlice } from '@reduxjs/toolkit'
-
-export const counterSlice = createSlice({
-  name: 'counter',
-  initialState: {
-    value: 0,
-  },
-  reducers: {
-    increment: (state) => {
-      // Redux Toolkit allows us to write "mutating" logic in reducers. It
-      // doesn't actually mutate the state because it uses the Immer library,
-      // which detects changes to a "draft state" and produces a brand new
-      // immutable state based off those changes
-      state.value += 1;
-    },
-    decrement: (state) => {
-      state.value -= 1;
-    }
-  },
-})
-
-// Action creators are generated for each case reducer function
-export const { increment, decrement } = counterSlice.actions
-
-export default counterSlice.reducer
diff --git a/src/features/todo/ToDo.jsx b/src/features/todo/ToDo.jsx
new file mode 100644
index 0000000..c956ba1
--- /dev/null
+++ b/src/features/todo/ToDo.jsx
@@ -0,0 +1,233 @@
+import React, { useState } from "react";
+import { useSelector, useDispatch } from "react-redux";
+import { add_todo, select_todos } from "./reducer";
+
+export function Reducer() {
+    const my_todos = useSelector(select_todos);
+    const dispatch = useDispatch();
+    const [new_text, set_new_text] = useState("");
+    const [new_done, set_new_done] = useState(false);
+    const [new_priority, set_new_priority] = useState("Low");
+
+    function handle_exit_modal() {
+        // https://stackoverflow.com/questions/27826381/clearing-form-input-fields-in-bootstrap
+        $("form").get(0).reset(); // Reset form
+
+        set_new_text("");
+        set_new_done(false);
+        set_new_priority("Low");
+
+        console.log("CLEANED.");
+    }
+
+    return (
+        <>
+            <div className="container mt-3 mb-3">
+                <button
+                    type="button"
+                    className="btn btn-outline-dark"
+                    data-bs-toggle="modal"
+                    data-bs-target="#NewToDo"
+                >
+                    + New To Do
+                </button>
+            </div>
+
+            <div
+                className="modal fade"
+                id="NewToDo"
+                tabIndex="-1"
+                role="dialog"
+                aria-labelledby="New To Do Window"
+                aria-hidden="true"
+            >
+                <div
+                    className="modal-dialog modal-dialog-centered"
+                    role="document"
+                >
+                    <div className="modal-content">
+                        <div className="modal-header">
+                            <h5
+                                className="modal-title"
+                                id="exampleModalLongTitle"
+                            >
+                                Add a new to do
+                            </h5>
+                            <button
+                                type="button"
+                                className="close"
+                                data-bs-dismiss="modal"
+                                aria-label="Close"
+                                onClick={handle_exit_modal}
+                            >
+                                <span aria-hidden="true">&times;</span>
+                            </button>
+                        </div>
+                        <div className="modal-body">
+                            <form>
+                                <div className="form-floating mb-3">
+                                    <input
+                                        className="form-control"
+                                        id="new-todo-id"
+                                        value="4"
+                                        disabled
+                                    />
+                                    <label htmlFor="floatingInput">ID</label>
+                                </div>
+                                <div className="form-floating mb-3">
+                                    <input
+                                        className="form-control"
+                                        placeholder="Text"
+                                        id="new-todo-text"
+                                        onChange={(e) =>
+                                            set_new_text(e.target.value)
+                                        }
+                                    />
+                                    <label htmlFor="floatingInput">Text</label>
+                                </div>
+                                <div className="input-group mb-3">
+                                    <span className="input-group-text">
+                                        <i className="fa-regular fa-calendar"></i>
+                                    </span>
+                                    <div className="form-floating">
+                                        <input
+                                            className="form-control"
+                                            id="new-todo-due-date"
+                                            name="new-todo-due-date"
+                                            placeholder="Due date"
+                                        />
+                                        <label htmlFor="floatingInput">
+                                            Due Date
+                                        </label>
+                                    </div>
+                                </div>
+                                <div className="form-check mb-3">
+                                    <input
+                                        className="form-check-input"
+                                        type="checkbox"
+                                        value=""
+                                        id="flexCheckDefault"
+                                        onChange={(e) =>
+                                            set_new_done(e.target.checked)
+                                        }
+                                    />
+                                    <label
+                                        className="form-check-label"
+                                        htmlFor="flexCheckDefault"
+                                    >
+                                        Done
+                                    </label>
+                                </div>
+                                <div className="form-floating mb-3">
+                                    <select
+                                        className="form-select"
+                                        id="floatingSelect"
+                                        aria-label="Floating label select example"
+                                        onChange={(e) =>
+                                            set_new_priority(e.target.value)
+                                        }
+                                    >
+                                        <option value="Low" defaultValue>
+                                            Low
+                                        </option>
+                                        <option value="Medium">Medium</option>
+                                        <option value="High">High</option>
+                                    </select>
+                                    <label htmlFor="floatingSelect">
+                                        Priority
+                                    </label>
+                                </div>
+                            </form>
+                        </div>
+                        <div className="modal-footer">
+                            <button
+                                type="button"
+                                className="btn btn-secondary"
+                                data-bs-dismiss="modal"
+                                onClick={handle_exit_modal}
+                            >
+                                Cancel
+                            </button>
+                            <button
+                                type="button"
+                                className="btn btn-primary"
+                                onClick={() => {
+                                    dispatch(
+                                        add_todo({
+                                            text: new_text,
+                                            // Cannot update date on change. :'(
+                                            due_date:
+                                                document.getElementById(
+                                                    "new-todo-due-date"
+                                                ).value,
+                                            done: new_done,
+                                            priority: new_priority,
+                                            creation_date:
+                                                new Date().toString(),
+                                        })
+                                    ),
+                                        handle_exit_modal();
+                                }}
+                                data-bs-dismiss="modal"
+                            >
+                                Add
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div className="container">
+                <table className="table align-middle">
+                    <thead>
+                        <tr>
+                            <th scope="col">#</th>
+                            <th scope="col">Name</th>
+                            <th scope="col">Priority</th>
+                            <th scope="col">Due Date</th>
+                            <th scope="col">Actions</th>
+                        </tr>
+                    </thead>
+                    <tbody className="table-group-divider">
+                        {my_todos.map((item) => (
+                            <tr key={item.id}>
+                                <th scope="row">
+                                    <div className="form-check">
+                                        <input
+                                            className="form-check-input"
+                                            type="checkbox"
+                                            checked={item.done}
+                                            id="flexCheckChecked"
+                                        ></input>
+                                    </div>
+                                </th>
+                                <td>{item.text}</td>
+                                <td>{item.priority}</td>
+                                <td>{item.due_date}</td>
+                                <td>
+                                    <div
+                                        className="btn-group btn-group-sm"
+                                        role="group"
+                                        aria-label="Basic example"
+                                    >
+                                        <button
+                                            type="button"
+                                            className="btn btn-outline-dark"
+                                        >
+                                            Edit
+                                        </button>
+                                        <button
+                                            type="button"
+                                            className="btn btn-outline-dark"
+                                        >
+                                            Delete
+                                        </button>
+                                    </div>
+                                </td>
+                            </tr>
+                        ))}
+                    </tbody>
+                </table>
+            </div>
+        </>
+    );
+}
diff --git a/src/features/todo/reducer.js b/src/features/todo/reducer.js
new file mode 100644
index 0000000..29422e9
--- /dev/null
+++ b/src/features/todo/reducer.js
@@ -0,0 +1,32 @@
+import { createSlice } from "@reduxjs/toolkit";
+
+export const todo_slice = createSlice({
+    name: "todo_list",
+    initialState: {
+        todos: [],
+        last_id: 0,
+    },
+
+    reducers: {
+        add_todo: (state, action) => {
+            state.todos = [
+                ...state.todos,
+                {
+                    id: ++state.last_id,
+                    text: action.payload.text,
+                    due_date: action.payload.due_date,
+                    done: action.payload.done,
+                    priority: action.payload.priority,
+                    creation_date: action.payload.creation_date,
+                },
+            ];
+            console.log(state.todos);
+        },
+    },
+});
+
+export const { add_todo } = todo_slice.actions;
+
+export const select_todos = (state) => state.todo_list.todos;
+
+export default todo_slice.reducer;
-- 
cgit v1.2.3