aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrián Oliva <adrian.oliva@cimat.mx>2023-05-17 21:26:50 -0600
committerAdrián Oliva <adrian.oliva@cimat.mx>2023-05-17 21:26:50 -0600
commit593ab2d7d4ef972594131b125d9320c618e54691 (patch)
tree1d44587b3785f987e41d807370d8a04f27565170
parent163398f68444d278eb83543ba9798a6441c8af9f (diff)
downloadToDo-App-FE-593ab2d7d4ef972594131b125d9320c618e54691.tar.gz
ToDo-App-FE-593ab2d7d4ef972594131b125d9320c618e54691.zip
Redux used to add ToDos
WE MADE IT!! I don't know how, but it is functional. :'3
Diffstat (limited to '')
-rw-r--r--src/App.jsx9
-rw-r--r--src/ToDo-UI/NewToDo.jsx126
-rw-r--r--src/ToDo-UI/ToDoList.jsx69
-rw-r--r--src/app/store.js12
-rw-r--r--src/features/counter/Counter.jsx30
-rw-r--r--src/features/counter/counterSlice.js25
-rw-r--r--src/features/todo/ToDo.jsx233
-rw-r--r--src/features/todo/reducer.js32
8 files changed, 274 insertions, 262 deletions
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;