Skip to content

Commit

Permalink
feat: reorder todos by status
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiasprima committed Mar 21, 2024
1 parent 4a98c79 commit ea390d5
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
14 changes: 12 additions & 2 deletions src/app/api/apiSlice.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const apiSlice = createApi({
// https://todolistapi-kcjj.onrender.com
reducerPath: 'api',
baseQuery: fetchBaseQuery({ baseUrl: 'https://todolistapi-kcjj.onrender.com' }),
baseQuery: fetchBaseQuery({ baseUrl: 'http://localhost:8080' }),
tagTypes: ['Todos'],
endpoints: (builder) => ({
getTodos: builder.query({
Expand Down Expand Up @@ -40,6 +41,14 @@ export const apiSlice = createApi({
body: id
}),
invalidatesTags: ['Todos']
}),
reorderTodo: builder.mutation({
query: (todos)=> ({
url: '/todos/reorder',
method: 'PATCH',
body: todos
}),
invalidatesTags: ['Todos']
})
})
})
Expand All @@ -49,5 +58,6 @@ export const {
useAddTodoMutation,
useUpdateTodoMutation,
useDoneTodoMutation,
useDeleteTodoMutation
useDeleteTodoMutation,
useReorderTodoMutation
} = apiSlice
44 changes: 38 additions & 6 deletions src/features/todos/TodoList.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faPlus, faTrash, faUpload, faXmark } from '@fortawesome/free-solid-svg-icons'
import { faPlus, faXmark } from '@fortawesome/free-solid-svg-icons'
import { useState, useEffect } from 'react'
import {
useGetTodosQuery,
useAddTodoMutation,
useUpdateTodoMutation,
useDoneTodoMutation,
useDeleteTodoMutation
useDeleteTodoMutation,
useReorderTodoMutation,
} from '../../app/api/apiSlice'

const TodoList = () => {
const [ todoWithoutDB, setTodoWithoutDB ] = useState([])
const [ newTodo, setNewTodo ] = useState('')
const [moveDoneToEnd, setMoveDoneToEnd] = useState(false);

const {
data: todos,
isLoading,
isSuccess,
isError,
error
refetch: refetchTodos
} = useGetTodosQuery()
const [ addTodo ] = useAddTodoMutation()
const [ doneTodo ] = useDoneTodoMutation()
const [ deleteTodo ] = useDeleteTodoMutation()
const [ reorderTodo ] = useReorderTodoMutation()

// Effect to load todos from local storage if there is cache
useEffect(() => {
Expand Down Expand Up @@ -76,11 +78,29 @@ const TodoList = () => {
setTodoWithoutDB(prevTodos => prevTodos.filter(todo => todo._id !== id))
}

// Handle Moving Done Todos to Bottom of the list
const handleMoveDoneToEnd = async () => {
if(todos){
await reorderTodo(todos);
await refetchTodos();
} else {
setMoveDoneToEnd((prevMoveDoneToEnd) => !prevMoveDoneToEnd)
setTodoWithoutDB((prevTodos) => {
// Handle moving done todos without db
const doneTodos = prevTodos.filter((todo)=> todo.status)
const undoneTodos = prevTodos.filter((todo)=> !todo.status)
return moveDoneToEnd ? [...undoneTodos, ...doneTodos] :
[...doneTodos, ...undoneTodos]
})
}

}

const newItemSection =
<div className="new-item-section">
<form onSubmit={handleSubmit}>
<label htmlFor="new-todo">Add to list</label>
<div className="new-todo">
<div className="new-todo">
<input
type="text"
id="new-todo"
Expand All @@ -98,7 +118,16 @@ const TodoList = () => {
if (isLoading) {
content = <p>Loading ...</p>
} else if (isSuccess){
content = todos.map(todo => {
let sortedTodos = todos;
if (todos.length> 1){
sortedTodos = todos.slice().sort((a, b) => {
if (a.order !== 0 && b.order !==0){
return b.order - a.order
}
return a.order - b.order
})
}
content = sortedTodos.map(todo => {
return (
<article key={todo._id}>
<div className="todo">
Expand Down Expand Up @@ -158,6 +187,9 @@ const TodoList = () => {
{content}
</div>
<hr />
<button className="toggle-move" onClick={handleMoveDoneToEnd}>
Move done things to end
</button>
<div className="bottom-section">
<p>Add to list</p>
{newItemSection}
Expand Down

0 comments on commit ea390d5

Please sign in to comment.