Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Categories on the DOM #13

Open
wants to merge 6 commits into
base: complete
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 15 additions & 11 deletions src/Initialize/index.js
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import { getTodos } from '../api/data/todoData';
import Todo from '../components/Todo';
import CategorizedTodos from '../components/CategorizedTodos';
import TodoForm from '../components/TodoForm';

const Container = styled.div`
Expand All @@ -20,14 +20,21 @@ const Container = styled.div`
color: lightgrey;
text-align: center;
}
h4 {
color: lightgrey;
text-transform: uppercase;
font-size: medium;
}
`;

function Initialize() {
const [todos, setTodos] = useState([]);
const [editItem, setEditItem] = useState({});

useEffect(() => {
getTodos().then(setTodos);
getTodos().then((todoArray) => {
setTodos(todoArray);
});
}, []);

return (
Expand All @@ -36,16 +43,13 @@ function Initialize() {
<TodoForm obj={editItem} setTodos={setTodos} setEditItem={setEditItem} />
<div className="mt-5">
{todos.length ? (
todos.map((todo) => (
<Todo
key={todo.firebaseKey}
taco={todo}
setTodos={setTodos}
setEditItem={setEditItem}
/>
))
<CategorizedTodos
todos={todos}
setTodos={setTodos}
setEditItem={setEditItem}
/>
) : (
<h3>Add A You Do!</h3>
<h3>Add A YOU DO!</h3>
)}
</div>
</Container>
Expand Down
61 changes: 61 additions & 0 deletions src/components/CategorizedTodos.js
@@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import Todo from './Todo';

export default function CategorizedTodos({ todos, setTodos, setEditItem }) {
const [categorizedTodos, setCategorizedTodos] = useState({});

const categoryGroups = () => {
// const sortedObj = {};
// array.forEach((todo) => {
// // LOOKING to see if a key of item exists
// if (todo.category in sortedObj) {
// // if so, set the value of the key array to the spreaded object and the current todo
// sortedObj[todo.category] = [...sortedObj[todo.category], todo];
// } else {
// // if not, create the category and set the value as the current todo
// sortedObj[todo.category] = [todo];
// }
// });

// DOING THE SAME AS ABOVE USING REDUCE
const sortedObj = todos.reduce((todoObject, currentObject) => {
const main = todoObject;
// if the current category already exists, push the currentObject into the array...otherwise, set the value to an array and push the currentObject into it.
(main[currentObject.category] = main[currentObject.category] || []).push(
currentObject,
);
return main;
}, {});

setCategorizedTodos(sortedObj);
};

useEffect(() => {
categoryGroups();
}, [todos]);

return (
<div>
{Object.keys(categorizedTodos).map((category) => (
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The More You Know

You could also use Object.entries() It gives you access to the key and value in an array so you'd have to destructure like this.

Object.keys(categorizedTodos).map(([key, value]) => (

So on line 43 you don't have to grab the value using bracket notation. You'd instead do this

{value.map((todo) => (

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just looked it up, and the way you did it was more performant 🙃
https://gists.cwidanage.com/2018/06/how-to-iterate-over-object-entries-in.html

<div key={category}>
<h4>Category {category}</h4>
{categorizedTodos[category].map((todo) => (
<Todo
key={todo.firebaseKey}
taco={todo}
setTodos={setTodos}
setEditItem={setEditItem}
/>
))}
</div>
))}
</div>
);
}

CategorizedTodos.propTypes = {
todos: PropTypes.arrayOf(PropTypes.object).isRequired,
setTodos: PropTypes.func.isRequired,
setEditItem: PropTypes.func.isRequired,
};
19 changes: 16 additions & 3 deletions src/components/TodoForm.js
Expand Up @@ -6,6 +6,7 @@ import { createTodo, updateTodo } from '../api/data/todoData';
const initialState = {
name: '',
complete: false,
category: '',
uid: '',
};
export default function TodoForm({ obj, setTodos, setEditItem }) {
Expand All @@ -19,6 +20,7 @@ export default function TodoForm({ obj, setTodos, setEditItem }) {
name: obj.name,
firebaseKey: obj.firebaseKey,
complete: obj.complete,
category: obj.category,
date: obj.date,
uid: obj.uid,
});
Expand Down Expand Up @@ -60,9 +62,6 @@ export default function TodoForm({ obj, setTodos, setEditItem }) {
<div>
<form onSubmit={handleSubmit}>
<div className="mb-3 d-flex">
<label htmlFor="name" className="form-label visually-hidden">
Name
</label>
<input
className="form-control form-control-lg me-1"
type="text"
Expand All @@ -73,6 +72,19 @@ export default function TodoForm({ obj, setTodos, setEditItem }) {
placeholder="ADD A YOU-DO"
required
/>
<select
className="form-select form-select-lg me-1"
aria-label="category"
name="category"
value={formInput.category}
onChange={handleChange}
required
>
<option value="">Category</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<button className="btn btn-success" type="submit">
{obj.firebaseKey ? 'Update' : 'Submit'}
</button>
Expand All @@ -88,6 +100,7 @@ TodoForm.propTypes = {
complete: PropTypes.bool,
date: PropTypes.string,
firebaseKey: PropTypes.string,
category: PropTypes.string,
uid: PropTypes.string,
}),
setTodos: PropTypes.func.isRequired,
Expand Down