Skip to content

Commit

Permalink
Move day view to dynamic route
Browse files Browse the repository at this point in the history
/tasks is now /tasks/day, this way its easier to implement the same
navigation that we have for week and month, also the loading state for
it was added.
  • Loading branch information
negreirosleo committed Feb 21, 2024
1 parent 51da043 commit 03fc47c
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 26 deletions.
7 changes: 6 additions & 1 deletion frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ const nextConfig = {
return [
{
source: '/',
destination: '/tasks',
destination: '/tasks/day',
permanent: true
},
{
source: '/tasks',
destination: '/tasks/day',
permanent: true
}
]
Expand Down
12 changes: 7 additions & 5 deletions frontend/src/app/tasks/__tests__/components/CreateTask.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { screen, renderWithUser, act } from '@/test-utils/test-utils'
import { useCreateTask } from '../../hooks/useCreateTask'
import { useGetTasks } from '../../hooks/useGetTasks'
import { useGetCurrentUser } from '@/hooks/useGetCurrentUser/useGetCurrentUser'
import { CreateTaskFormProvider } from '../../providers/CreateTaskFormProvider'
import { useDateParam } from '../../hooks/useDateParam'
import { CreateTaskFormProvider } from '../../day/[[...date]]/providers/CreateTaskFormProvider'

jest.mock('../../hooks/useCreateTask')
jest.mock('../../hooks/useGetTasks')
jest.mock('../../hooks/useDateParam')

jest.mock('@/hooks/useGetCurrentUser/useGetCurrentUser')

Expand Down Expand Up @@ -60,14 +62,14 @@ const setupTaskForm = () => {

describe('TaskForm', () => {
beforeEach(() => {
;(useCreateTask as jest.Mock).mockReturnValue({ addTask: () => {} })
;(useGetTasks as jest.Mock).mockReturnValue({ tasks: [] })
;(useGetCurrentUser as jest.Mock).mockReturnValue({ id: 0 })

jest.useFakeTimers()
jest.spyOn(global, 'setInterval')
jest.setSystemTime(new Date('January 01, 2023 23:15:00'))
window.localStorage.clear()
;(useCreateTask as jest.Mock).mockReturnValue({ addTask: () => {} })
;(useGetTasks as jest.Mock).mockReturnValue({ tasks: [] })
;(useGetCurrentUser as jest.Mock).mockReturnValue({ id: 0 })
;(useDateParam as jest.Mock).mockReturnValue({ date: new Date('January 01, 2023') })
})

afterEach(() => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/app/tasks/__tests__/components/TaskBox.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { renderWithUser, screen } from '@/test-utils/test-utils'
import { TaskBox } from '../../components/TaskBox'
import { useDeleteTask } from '../../hooks/useDeleteTask'
import { useCreateTaskForm } from '../../hooks/useCreateTaskForm'
import { useCreateTaskForm } from '../../day/[[...date]]/hooks/useCreateTaskForm'

jest.mock('../../hooks/useDeleteTask')
jest.mock('../../hooks/useCreateTaskForm')
jest.mock('../../day/[[...date]]/hooks/useCreateTaskForm')

const setupTaskBox = () => {
const task = {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/tasks/components/CreateTask.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { TextArea } from '@/ui/TextArea/TextArea'
import { Play16Filled, RecordStop24Regular } from '@fluentui/react-icons'

import { TimePicker } from '../components/TimePicker'
import { useCreateTaskForm } from '../hooks/useCreateTaskForm'
import { useCreateTaskForm } from '../day/[[...date]]/hooks/useCreateTaskForm'
import { useTaskFormTimer } from '../hooks/useTaskFormTimer'

import { Project } from '@/domain/Project'
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/app/tasks/components/TaskBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { getTimeDifference, convertTimeToMinutes } from '../utils/time'
import { EditTask } from './EditTask'
import { DeleteTask } from './DeleteTask'
import { SaveTemplateModal } from './SaveTemplateModal'
import { useCreateTaskForm } from '../hooks/useCreateTaskForm'
import { useCreateTaskForm } from '../day/[[...date]]/hooks/useCreateTaskForm'
import { IconButton } from './IconButton'
import { styled } from '@mui/joy'

Expand Down
6 changes: 4 additions & 2 deletions frontend/src/app/tasks/components/TaskList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import Box from '@mui/joy/Box'
import { Box, Skeleton } from '@mui/joy'

import { Project } from '@/domain/Project'
import { TaskType } from '@/domain/TaskType'
Expand All @@ -16,7 +16,7 @@ type TaskListProps = {
}

export const TaskList = ({ projects, taskTypes, sx }: TaskListProps) => {
const { tasks } = useGetTasks()
const { tasks, isLoading } = useGetTasks()

return (
<Box
Expand All @@ -26,9 +26,11 @@ export const TaskList = ({ projects, taskTypes, sx }: TaskListProps) => {
flexDirection: 'column',
gap: '16px',
listStyle: 'none',
position: 'relative',
...sx
}}
>
<Skeleton width="100%" height="96px" loading={isLoading} />
{tasks.map((task) => (
<TaskBox projects={projects} taskTypes={taskTypes} key={task.id} task={task} />
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { Project } from '@/domain/Project'
import { TaskType } from '@/domain/TaskType'
import { Template } from '@/domain/Template'

import { TaskList } from './components/TaskList'
import { CreateTask } from './components/CreateTask'
import { TaskList } from '../../components/TaskList'
import { CreateTask } from '../../components/CreateTask'
import { CreateTaskFormProvider } from './providers/CreateTaskFormProvider'

type DayViewProps = {
Expand Down
44 changes: 44 additions & 0 deletions frontend/src/app/tasks/day/[[...date]]/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use client'

import Box from '@mui/joy/Box'

import Divider from '@mui/joy/Divider'
import { Skeleton } from '@mui/joy'

import { CreateTask } from '../../components/CreateTask'
import { CreateTaskFormProvider } from './providers/CreateTaskFormProvider'

export default function Loading() {
return (
<Box
sx={{
display: 'grid',
gridTemplateAreas: {
xs: "'divider-1 divider-1''select-template start-timer''divider-2 divider-2''create-task-form create-task-form''task-list task-list'",
sm: "'divider-1 divider-1''select-template start-timer''divider-2 divider-2''create-task-form task-list'"
},
gridTemplateColumns: {
xs: '1fr',
sm: '558px 558px'
},
columnGap: '30px',
rowGap: '16px',
margin: '0 auto',
maxWidth: '1146px',
width: '100%'
}}
>
<Divider sx={{ gridArea: 'divider-1' }} />

<CreateTaskFormProvider>
<CreateTask projects={[]} taskTypes={[]} templates={[]} />

<Divider sx={{ gridArea: 'divider-2' }} />

<Box sx={{ gridArea: 'task-list', position: 'relative' }}>
<Skeleton width="100%" height="96px" />
</Box>
</CreateTaskFormProvider>
</Box>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { makeGetTemplates } from '@/infra/template/getTemplates'
import { serverFetch } from '@/infra/lib/serverFetch'
import { authOptions } from '@/app/api/auth/[...nextauth]/authOptions'
import { getServerSession } from 'next-auth'
import { unstable_cache } from 'next/cache'

const getPageData = async () => {
const getPageData = unstable_cache(async () => {
const apiClient = await serverFetch()
const session = await getServerSession(authOptions)
const { id: userId } = session!.user
Expand All @@ -16,7 +17,7 @@ const getPageData = async () => {
const getTemplates = makeGetTemplates(apiClient)

return await Promise.all([getProjects(), getTaskTypes(), getTemplates({ userId })])
}
}, ['day-view'])

export default async function Tasks() {
const [projects, taskTypes, templates] = await getPageData()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { format } from 'date-fns'
import { useCallback, useState, createContext, PropsWithChildren, RefObject, useMemo } from 'react'
import {
useCallback,
useState,
createContext,
PropsWithChildren,
RefObject,
useMemo,
useEffect
} from 'react'

import { useForm } from '@/hooks/useForm/useForm'
import { useGetCurrentUser } from '@/hooks/useGetCurrentUser/useGetCurrentUser'

import { useCreateTask } from '../hooks/useCreateTask'
import { useCreateTask } from '../../../hooks/useCreateTask'

import { Template } from '@/domain/Template'

import { TaskIntent, Task } from '@/domain/Task'
import { useDateParam } from '../../../hooks/useDateParam'

type CreateTaskFormContext = {
task: TaskIntent
Expand All @@ -28,6 +37,7 @@ export const CreateTaskFormProvider = ({ children }: PropsWithChildren) => {
const { id: userId } = useGetCurrentUser()
const { addTask, isLoading } = useCreateTask()
const [template, setTemplate] = useState<Template | null>(null)
const { date } = useDateParam()

const { formState, handleChange, resetForm, setFormState, formRef } = useForm<TaskIntent>({
initialValues: {
Expand All @@ -38,10 +48,14 @@ export const CreateTaskFormProvider = ({ children }: PropsWithChildren) => {
description: '',
startTime: '',
endTime: '',
date: format(new Date(), 'yyyy-MM-dd')
date: format(date, 'yyyy-MM-dd')
}
})

useEffect(() => {
handleChange('date', format(date, 'yyyy-MM-dd'))
}, [date, handleChange])

const handleSubmit = useCallback(() => {
addTask({ task: formState, handleSuccess: resetForm })
}, [addTask, formState, resetForm])
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/app/tasks/hooks/useCreateTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { useClientFetch } from '@/infra/lib/useClientFetch'
import { useGetCurrentUser } from '@/hooks/useGetCurrentUser/useGetCurrentUser'
import { useGetTasks } from './useGetTasks'
import { BaseError } from '@/_lib/errors/BaseError'
import { revalidateTag } from 'next/cache'
import { useDateParam } from './useDateParam'
import { format } from 'date-fns'

export const useCreateTask = () => {
const apiClient = useClientFetch()
Expand All @@ -15,16 +16,16 @@ export const useCreateTask = () => {
const { showError, showSuccess } = useAlert()
const { id: userId } = useGetCurrentUser()
const { tasks } = useGetTasks()
const { date } = useDateParam()

const { mutate, isLoading } = useMutation(
({ task }: { task: TaskIntent; handleSuccess: () => void }) => createTask(task, tasks),
{
onSuccess: (_, { handleSuccess }) => {
handleSuccess()
queryClient.invalidateQueries(['tasks', userId])
queryClient.invalidateQueries(['workSummary', userId])
queryClient.invalidateQueries(['tasks', userId, format(date, 'yyyy-MM-dd')])
showSuccess('Task added succesfully')
revalidateTag('tags')
},
onError: (e) => {
if (e instanceof BaseError) {
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/app/tasks/loading.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/src/ui/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const Sidebar = ({ expanded, toggleSidebar }: SidebarProps) => {
spacing={2}
>
<Box component="li">
<NavLink href="/tasks">
<NavLink href="/tasks/day">
<TaskListSquareAdd24Filled color="white" />
<Typography textColor="white">Tasks</Typography>
</NavLink>
Expand Down

0 comments on commit 03fc47c

Please sign in to comment.