Skip to content

Commit 430c534

Browse files
fix: quitar zustand para manejar tareas y manejar todo con react query
1 parent e7562ed commit 430c534

6 files changed

Lines changed: 76 additions & 90 deletions

File tree

client/src/features/lists/components/ListItem.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { useEffect, useRef, useState } from 'react';
22
import { useNavigate, useParams } from 'react-router';
33
import { ListProps } from '@shared/types/list.types';
44
import { useAlertDialogStore } from '@/shared/store/dialogStore';
5-
import { useTaskStore } from '@/features/tasks/store/taskStore';
6-
import { getTaskCount } from '@/features/lists/utils/getTaskCount';
5+
import { useQueryClient } from '@tanstack/react-query';
6+
import { TaskProps } from '@shared/types/task.types';
77
import { Trash2 } from 'lucide-react';
88
import { Tooltip } from '@/shared/components/ui/tooltip';
99
import { replaceEmojis } from '@/shared/utils/replaceEmojis';
@@ -20,9 +20,8 @@ type ListItemProps = {
2020
const ListItem = ({ list }: ListItemProps) => {
2121
const { listId } = useParams();
2222
const navigate = useNavigate();
23-
const { tasks } = useTaskStore();
23+
const queryClient = useQueryClient();
2424
const inputRef = useRef(null!) as React.MutableRefObject<HTMLInputElement>;
25-
const [countTasks, setCountTasks] = useState(0);
2625
const [isFocused, setIsFocused] = useState(false);
2726
const { setOpen, setHandleDelete, setListTitle } = useAlertDialogStore();
2827
const [listName, setListName] = useState(list.name);
@@ -91,10 +90,6 @@ const ListItem = ({ list }: ListItemProps) => {
9190
setIsFocused(true);
9291
};
9392

94-
useEffect(() => {
95-
setCountTasks(getTaskCount(list, tasks, listId));
96-
}, [list, listId, tasks]);
97-
9893
useEffect(() => {
9994
if (listNameDebounced === list.name) return;
10095
setListTitle(listNameDebounced as string);
@@ -150,7 +145,11 @@ const ListItem = ({ list }: ListItemProps) => {
150145
data-testid='task-count'
151146
className='text-center inline-block group-hover:hidden align-middle text-xs text-neutral-500 dark:text-neutral-100'
152147
>
153-
<span className='w-full'>{countTasks}</span>
148+
<span className='w-full'>
149+
{list.listId === listId
150+
? (queryClient.getQueryData<TaskProps[]>(['tasks', listId]) ?? list.tasks ?? []).length
151+
: (list.tasks ?? []).length}
152+
</span>
154153
</span>
155154
</button>
156155
</Tooltip>

client/src/features/tasks/components/CreateTask.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { useEffect, useRef, useState } from 'react';
22
import { nanoid } from 'nanoid';
3-
import { useTaskStore } from '../store/taskStore';
43
import { useParams } from 'react-router';
54
import { replaceEmojis } from '@/shared/utils/replaceEmojis';
65
import { SIZE_ID } from '@/shared/constants/base';
@@ -15,7 +14,6 @@ import { useCreateTask as useCreateTaskMutation } from '@/features/tasks/hooks/u
1514

1615
const CreateTask = () => {
1716
const [taskName, setTaskName] = useState('');
18-
const { tasks } = useTaskStore();
1917
const { listId } = useParams();
2018
const [checked, setChecked] = useState(false);
2119
const inputRef = useRef(null!) as React.RefObject<HTMLInputElement>;
@@ -37,13 +35,10 @@ const CreateTask = () => {
3735
position: 0,
3836
};
3937

40-
// Shift existing tasks' positions
41-
const position = tasks.length > 0 ? 0 : 0;
42-
4338
setDate(undefined);
4439
setChecked(false);
4540
setTaskName('');
46-
createTaskMutation.mutate({ ...newTask, position });
41+
createTaskMutation.mutate({ ...newTask, position: 0 });
4742

4843
const body = createNotification({
4944
type: 'task',

client/src/features/tasks/components/TaskList.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect } from 'react';
22
import SortableList from '@/features/tasks/components/dnd/SortableList';
3-
import { useTaskStore } from '@/features/tasks/store/taskStore';
3+
import { useTasks } from '@/features/tasks/hooks/useTasks';
44
import { useNavigate, useParams } from 'react-router';
55
import { useAlertDialogStore } from '@/shared/store/dialogStore';
66
import { useLists } from '@/features/lists/hooks/useLists';
@@ -14,9 +14,9 @@ const EmptyList = () => {
1414
};
1515

1616
export const TaskList = () => {
17-
const { tasks, setTasks } = useTaskStore();
18-
const { lists } = useLists();
1917
const { listId } = useParams();
18+
const { tasks } = useTasks(listId);
19+
const { lists } = useLists();
2020
const { setListTitle } = useAlertDialogStore();
2121
const navigate = useNavigate();
2222

@@ -25,8 +25,7 @@ export const TaskList = () => {
2525
const findList = lists.find((l) => l.listId === listId);
2626
if (!findList && lists.length !== 0) navigate('/u/dashboard');
2727
setListTitle(findList?.name ?? '');
28-
setTasks(findList?.tasks || []);
29-
}, [listId, lists, navigate, setListTitle, setTasks]);
28+
}, [listId, lists, navigate, setListTitle]);
3029

3130
return tasks.length > 0 ? <SortableList /> : <EmptyList />;
3231
};

client/src/features/tasks/components/dnd/SortableList.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ import {
1010
DragStartEvent,
1111
} from '@dnd-kit/core';
1212
import { SortableContext, arrayMove, sortableKeyboardCoordinates } from '@dnd-kit/sortable';
13-
1413
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
1514
import { SortableOverlay } from './SortableOverlay';
1615
import { Virtuoso } from 'react-virtuoso';
1716
import { useParams } from 'react-router';
1817
import { useDragStore } from '@/features/tasks/store/dragStore';
19-
import { useTaskStore } from '@/features/tasks/store/taskStore';
2018
import SortableItem from './SortableItem';
21-
import { useReorderTasks } from '@/features/tasks/hooks/useTasks';
19+
import { useReorderTasks, useTasks } from '@/features/tasks/hooks/useTasks';
20+
import { useQueryClient } from '@tanstack/react-query';
21+
import { TaskProps } from '@shared/types/task.types';
2222

2323
type handleDragEndProps = {
2424
active: Active;
@@ -29,7 +29,8 @@ const SortableList = () => {
2929
const { listId } = useParams();
3030
const [active, setActive] = useState<Active | null>(null);
3131
const { setIsDragging } = useDragStore();
32-
const { tasks, setTasks } = useTaskStore();
32+
const { tasks } = useTasks(listId);
33+
const queryClient = useQueryClient();
3334
const reorderTasks = useReorderTasks();
3435

3536
const activeItem = useMemo(() => tasks.find((item) => item.id === active?.id), [active, tasks]);
@@ -50,13 +51,13 @@ const SortableList = () => {
5051
const handleDragEnd = ({ active, over }: handleDragEndProps) => {
5152
if (!listId) return;
5253
if (over && active.id !== over.id) {
53-
const previousTasks = [...tasks];
54-
const activeIndex = tasks.findIndex(({ id }) => id === active.id);
55-
const overIndex = tasks.findIndex(({ id }) => id === over.id);
56-
const newOrder = arrayMove(tasks, activeIndex, overIndex);
57-
setTasks(newOrder);
54+
const previousTasks = queryClient.getQueryData<TaskProps[]>(['tasks', listId]) ?? [];
55+
const activeIndex = previousTasks.findIndex(({ id }) => id === active.id);
56+
const overIndex = previousTasks.findIndex(({ id }) => id === over.id);
57+
const newOrder = arrayMove(previousTasks, activeIndex, overIndex);
58+
queryClient.setQueryData<TaskProps[]>(['tasks', listId], newOrder);
5859
const items = newOrder.map((task, index) => ({ id: task.id, position: index }));
59-
reorderTasks.mutate({ items, previousTasks });
60+
reorderTasks.mutate({ items, listId, previousTasks });
6061
}
6162
setActive(null);
6263
setIsDragging(false);

client/src/features/tasks/hooks/useTasks.ts

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
duplicateTask,
99
moveTask,
1010
} from '../services/taskService';
11-
import { useTaskStore } from '../store/taskStore';
1211
import { TaskProps } from '@shared/types/task.types';
1312

1413
export const useTasks = (listId?: string) => {
@@ -31,7 +30,8 @@ export const useCreateTask = () => {
3130
return useMutation({
3231
mutationFn: createTask,
3332
onMutate: (variables) => {
34-
const previous = [...useTaskStore.getState().tasks];
33+
const queryKey = ['tasks', variables.list_id];
34+
const previous = queryClient.getQueryData<TaskProps[]>(queryKey);
3535
const newTask: TaskProps = {
3636
id: variables.id,
3737
list_id: variables.list_id,
@@ -41,11 +41,11 @@ export const useCreateTask = () => {
4141
date: variables.date,
4242
position: variables.position,
4343
};
44-
useTaskStore.getState().addTask(newTask);
44+
queryClient.setQueryData<TaskProps[]>(queryKey, [newTask, ...(previous ?? [])]);
4545
return { previous };
4646
},
47-
onError: (_err, _vars, context) => {
48-
if (context?.previous) useTaskStore.getState().setTasks(context.previous);
47+
onError: (_err, variables, context) => {
48+
queryClient.setQueryData(['tasks', variables.list_id], context?.previous);
4949
},
5050
onSettled: (_data, _error, variables) => {
5151
queryClient.invalidateQueries({ queryKey: ['tasks', variables.list_id] });
@@ -59,14 +59,18 @@ export const useUpdateTask = () => {
5959
return useMutation({
6060
mutationFn: updateTask,
6161
onMutate: ({ taskId, body }) => {
62-
const previous = [...useTaskStore.getState().tasks];
63-
useTaskStore.getState().setTasks(
64-
previous.map((task) => (task.id === taskId ? { ...task, ...body } : task))
65-
);
66-
return { previous };
62+
const allCaches = queryClient.getQueriesData<TaskProps[]>({ queryKey: ['tasks'] });
63+
for (const [queryKey, tasks] of allCaches) {
64+
if (!tasks?.some((t) => t.id === taskId)) continue;
65+
queryClient.setQueryData<TaskProps[]>(
66+
queryKey,
67+
tasks.map((t) => (t.id === taskId ? { ...t, ...body } : t))
68+
);
69+
return { queryKey, previous: tasks };
70+
}
6771
},
6872
onError: (_err, _vars, context) => {
69-
if (context?.previous) useTaskStore.getState().setTasks(context.previous);
73+
if (context) queryClient.setQueryData(context.queryKey, context.previous);
7074
},
7175
onSettled: () => {
7276
queryClient.invalidateQueries({ queryKey: ['tasks'] });
@@ -80,12 +84,18 @@ export const useDeleteTask = () => {
8084
return useMutation({
8185
mutationFn: deleteTask,
8286
onMutate: (taskId) => {
83-
const previous = [...useTaskStore.getState().tasks];
84-
useTaskStore.getState().deleteTask(taskId);
85-
return { previous };
87+
const allCaches = queryClient.getQueriesData<TaskProps[]>({ queryKey: ['tasks'] });
88+
for (const [queryKey, tasks] of allCaches) {
89+
if (!tasks?.some((t) => t.id === taskId)) continue;
90+
queryClient.setQueryData<TaskProps[]>(
91+
queryKey,
92+
tasks.filter((t) => t.id !== taskId)
93+
);
94+
return { queryKey, previous: tasks };
95+
}
8696
},
8797
onError: (_err, _vars, context) => {
88-
if (context?.previous) useTaskStore.getState().setTasks(context.previous);
98+
if (context) queryClient.setQueryData(context.queryKey, context.previous);
8999
},
90100
onSettled: () => {
91101
queryClient.invalidateQueries({ queryKey: ['tasks'] });
@@ -97,41 +107,41 @@ export const useDeleteTask = () => {
97107
export const useReorderTasks = () => {
98108
const queryClient = useQueryClient();
99109
return useMutation({
100-
mutationFn: (variables: { items: { id: string; position: number }[]; previousTasks: TaskProps[] }) =>
110+
mutationFn: (variables: { items: { id: string; position: number }[]; listId: string; previousTasks: TaskProps[] }) =>
101111
reorderTasks(variables.items),
102112
onError: (_err, variables) => {
103-
useTaskStore.getState().setTasks(variables.previousTasks);
113+
queryClient.setQueryData(['tasks', variables.listId], variables.previousTasks);
104114
},
105-
onSettled: () => {
106-
queryClient.invalidateQueries({ queryKey: ['tasks'] });
115+
onSettled: (_data, _error, variables) => {
116+
queryClient.invalidateQueries({ queryKey: ['tasks', variables.listId] });
117+
queryClient.invalidateQueries({ queryKey: ['lists'] });
107118
},
108119
});
109120
};
110121

111122
export const useDuplicateTask = () => {
112123
const queryClient = useQueryClient();
113124
return useMutation({
114-
mutationFn: (variables: { taskId: string; tempTask: TaskProps }) =>
115-
duplicateTask(variables.taskId),
125+
mutationFn: (variables: { taskId: string; tempTask: TaskProps }) => duplicateTask(variables.taskId),
116126
onMutate: ({ tempTask }) => {
117-
const previous = [...useTaskStore.getState().tasks];
118-
useTaskStore.getState().addTask(tempTask);
127+
const queryKey = ['tasks', tempTask.list_id];
128+
const previous = queryClient.getQueryData<TaskProps[]>(queryKey);
129+
queryClient.setQueryData<TaskProps[]>(queryKey, [tempTask, ...(previous ?? [])]);
119130
return { previous, tempId: tempTask.id };
120131
},
121-
onSuccess: (data, _vars, context) => {
132+
onSuccess: (data, vars, context) => {
122133
if (context?.tempId && data.length > 0) {
123-
const current = useTaskStore.getState().tasks;
124-
const serverTask = data[0];
125-
useTaskStore.getState().setTasks(
126-
current.map((t) => (t.id === context.tempId ? serverTask : t))
134+
const queryKey = ['tasks', vars.tempTask.list_id];
135+
queryClient.setQueryData<TaskProps[]>(queryKey, (current) =>
136+
(current ?? []).map((t) => (t.id === context.tempId ? data[0] : t))
127137
);
128138
}
129139
},
130-
onError: (_err, _vars, context) => {
131-
if (context?.previous) useTaskStore.getState().setTasks(context.previous);
140+
onError: (_err, vars, context) => {
141+
queryClient.setQueryData(['tasks', vars.tempTask.list_id], context?.previous);
132142
},
133-
onSettled: () => {
134-
queryClient.invalidateQueries({ queryKey: ['tasks'] });
143+
onSettled: (_data, _error, variables) => {
144+
queryClient.invalidateQueries({ queryKey: ['tasks', variables.tempTask.list_id] });
135145
queryClient.invalidateQueries({ queryKey: ['lists'] });
136146
},
137147
});
@@ -142,12 +152,18 @@ export const useMoveTask = () => {
142152
return useMutation({
143153
mutationFn: moveTask,
144154
onMutate: ({ taskId }) => {
145-
const previous = [...useTaskStore.getState().tasks];
146-
useTaskStore.getState().deleteTask(taskId);
147-
return { previous };
155+
const allCaches = queryClient.getQueriesData<TaskProps[]>({ queryKey: ['tasks'] });
156+
for (const [queryKey, tasks] of allCaches) {
157+
if (!tasks?.some((t) => t.id === taskId)) continue;
158+
queryClient.setQueryData<TaskProps[]>(
159+
queryKey,
160+
tasks.filter((t) => t.id !== taskId)
161+
);
162+
return { queryKey, previous: tasks };
163+
}
148164
},
149165
onError: (_err, _vars, context) => {
150-
if (context?.previous) useTaskStore.getState().setTasks(context.previous);
166+
if (context) queryClient.setQueryData(context.queryKey, context.previous);
151167
},
152168
onSettled: () => {
153169
queryClient.invalidateQueries({ queryKey: ['tasks'] });

client/src/features/tasks/store/taskStore.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)