aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrián Oliva <adrian.oliva@cimat.mx>2023-05-21 19:09:15 -0600
committerAdrián Oliva <adrian.oliva@cimat.mx>2023-05-21 19:09:15 -0600
commitc5b628f17da1bfa17251ecf82fcb146751954b72 (patch)
tree041f3665fc8b60734649364245edee72fb18de61
parentf3852c1f5bea14e72e200389759f123b880ccfec (diff)
downloadToDo-App-FE-c5b628f17da1bfa17251ecf82fcb146751954b72.tar.gz
ToDo-App-FE-c5b628f17da1bfa17251ecf82fcb146751954b72.zip
First attempt at filtering to do's.
We have a separate list from the original `todos_list`. It saves all currently filtered to do's for the listing to be as easy as possible.
Diffstat (limited to '')
-rw-r--r--src/App.jsx2
-rw-r--r--src/ToDo-UI/ListToDo.jsx15
-rw-r--r--src/ToDo-UI/NewToDo.jsx2
-rw-r--r--src/ToDo-UI/Search.jsx62
-rw-r--r--src/features/todo/reducer.js47
5 files changed, 109 insertions, 19 deletions
diff --git a/src/App.jsx b/src/App.jsx
index 138c6b8..a77c0d2 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,10 +1,12 @@
import React from "react";
+import { Search } from "./ToDo-UI/Search";
import { NewToDo } from "./ToDo-UI/NewToDo";
import { ListToDos } from "./ToDo-UI/ListToDo";
function App() {
return (
<div>
+ <Search />
<NewToDo />
<ListToDos />
</div>
diff --git a/src/ToDo-UI/ListToDo.jsx b/src/ToDo-UI/ListToDo.jsx
index eed6e02..f2f9a3e 100644
--- a/src/ToDo-UI/ListToDo.jsx
+++ b/src/ToDo-UI/ListToDo.jsx
@@ -6,6 +6,7 @@ import {
edit_todo,
set_sort_todo,
sort_todo,
+ refresh_filtered_todos,
select_todos,
select_current_sorting,
} from "../features/todo/reducer";
@@ -50,6 +51,7 @@ function list_of_todos(edit_button, delete_button) {
})
);
dispatch(sort_todo());
+ dispatch(refresh_filtered_todos());
}
// Table contents
@@ -85,14 +87,15 @@ function list_of_todos(edit_button, delete_button) {
type="checkbox"
checked={item.done}
id={"list-todo-done-" + item.id}
- onChange={(e) =>
+ onChange={(e) => {
dispatch(
change_done({
id: item.id,
done: e.target.checked,
})
- )
- }
+ ),
+ dispatch(refresh_filtered_todos());
+ }}
></input>
</div>
</th>
@@ -170,6 +173,7 @@ export function ListToDos() {
})
);
dispatch(sort_todo());
+ dispatch(refresh_filtered_todos());
handle_exit_modal();
}
@@ -200,7 +204,10 @@ export function ListToDos() {
<button
type="button"
className="btn btn-outline-dark"
- onClick={(e) => dispatch(remove_todo(item.id))}
+ onClick={(e) => {
+ dispatch(remove_todo(item.id)),
+ dispatch(refresh_filtered_todos());
+ }}
>
Delete
</button>
diff --git a/src/ToDo-UI/NewToDo.jsx b/src/ToDo-UI/NewToDo.jsx
index 28d80dc..2fd70b8 100644
--- a/src/ToDo-UI/NewToDo.jsx
+++ b/src/ToDo-UI/NewToDo.jsx
@@ -3,6 +3,7 @@ import { useSelector, useDispatch } from "react-redux";
import {
add_todo,
sort_todo,
+ refresh_filtered_todos,
select_last_index,
} from "../features/todo/reducer";
@@ -64,6 +65,7 @@ export function NewToDo() {
})
);
dispatch(sort_todo());
+ dispatch(refresh_filtered_todos());
handle_exit_modal();
}
diff --git a/src/ToDo-UI/Search.jsx b/src/ToDo-UI/Search.jsx
index bb36dba..dec1f29 100644
--- a/src/ToDo-UI/Search.jsx
+++ b/src/ToDo-UI/Search.jsx
@@ -1,6 +1,25 @@
-import React from "react";
+import React, { useState } from "react";
+import { useSelector, useDispatch } from "react-redux";
+import { set_filters, refresh_filtered_todos } from "../features/todo/reducer";
export function Search() {
+ const dispatch = useDispatch();
+
+ const [search_name, set_search_name] = useState("");
+ const [search_priority, set_search_priority] = useState("All");
+ const [search_state, set_search_state] = useState("All");
+
+ function handle_search() {
+ dispatch(
+ set_filters({
+ name: search_name,
+ priority: search_priority,
+ state: search_state,
+ })
+ );
+ dispatch(refresh_filtered_todos());
+ }
+
return (
<div className="container mt-3" style={{ border: "2px solid black" }}>
<div className="row">
@@ -9,10 +28,9 @@ export function Search() {
Name
</span>
<input
- type="text"
className="form-control"
- aria-label="Name"
- aria-describedby="search-name"
+ type="text"
+ onChange={(e) => set_search_name(e.target.value)}
></input>
</div>
</div>
@@ -21,11 +39,19 @@ export function Search() {
<div className="col-sm-7">
<div className="input-group mb-3 mt-3">
<label className="input-group-text">Priority</label>
- <select className="form-select" id="search-priority">
- <option defaultValue>All</option>
- <option value="1">High</option>
- <option value="2">Medium</option>
- <option value="3">Low</option>
+ <select
+ className="form-select"
+ id="search-priority"
+ onChange={(e) =>
+ set_search_priority(e.target.value)
+ }
+ >
+ <option value="All" defaultValue>
+ All
+ </option>
+ <option value="High">High</option>
+ <option value="Medium">Medium</option>
+ <option value="Low">Low</option>
</select>
</div>
</div>
@@ -35,17 +61,27 @@ export function Search() {
<div className="col-sm-7">
<div className="input-group mb-3 mt-3">
<label className="input-group-text">State</label>
- <select className="form-select" id="search-priority">
- <option defaultValue>All</option>
+ <select
+ className="form-select"
+ id="search-priority"
+ onChange={(e) => set_search_state(e.target.value)}
+ >
+ <option value="All" defaultValue>
+ All
+ </option>
<option value="1">Done</option>
- <option value="2">Undone</option>
+ <option value="0">Undone</option>
</select>
</div>
</div>
<div className="col-sm-2">
<div className="d-grid gap-2 d-md-flex justify-content-md-end">
- <button type="button" className="btn btn-outline-dark">
+ <button
+ type="button"
+ className="btn btn-outline-dark"
+ onClick={handle_search}
+ >
Search
</button>
</div>
diff --git a/src/features/todo/reducer.js b/src/features/todo/reducer.js
index 5fafb6d..960ab97 100644
--- a/src/features/todo/reducer.js
+++ b/src/features/todo/reducer.js
@@ -3,9 +3,17 @@ import { createSlice } from "@reduxjs/toolkit";
export const todo_slice = createSlice({
name: "todo_list",
initialState: {
- todos: [],
last_id: 0,
+ todos: [],
+
current_sorting: "created_time",
+
+ filtered_todos: [],
+ current_filters: {
+ name: "",
+ priority: "All",
+ state: "All",
+ },
},
reducers: {
@@ -127,6 +135,39 @@ export const todo_slice = createSlice({
break;
}
},
+
+ set_filters: (state, action) => {
+ state.current_filters = {
+ name: action.payload.name,
+ priority: action.payload.priority,
+ state: action.payload.state, // True is "1" and False is "0".
+ };
+ },
+
+ refresh_filtered_todos: (state) => {
+ state.filtered_todos = [...state.todos];
+
+ // If name, filter by names.
+ if (state.current_filters.name.length != 0) {
+ state.filtered_todos = state.filtered_todos.filter((todo) =>
+ todo.text.includes(state.current_filters.name)
+ );
+ }
+
+ // If priority != all, filter by priorities.
+ if (state.current_filters.priority != "All") {
+ state.filtered_todos = state.filtered_todos.filter(
+ (todo) => todo.priority === state.current_filters.priority
+ );
+ }
+
+ // If state != All, filter by current state.
+ if (state.current_filters.state != "All") {
+ state.filtered_todos = state.filtered_todos.filter(
+ (todo) => todo.done == state.current_filters.state
+ );
+ }
+ },
},
});
@@ -137,9 +178,11 @@ export const {
edit_todo,
set_sort_todo,
sort_todo,
+ set_filters,
+ refresh_filtered_todos,
} = todo_slice.actions;
-export const select_todos = (state) => state.todo_list.todos;
+export const select_todos = (state) => state.todo_list.filtered_todos;
export const select_last_index = (state) => state.todo_list.last_id;
export const select_current_sorting = (state) =>
state.todo_list.current_sorting;