Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion app/(internal-routes)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import { Dashboard } from '@/modules/dashboard'
import { DashboardShimmer } from '@/modules/dashboard/components/dashboard-shimmer'
import { Suspense } from 'react'

export default Dashboard
export default function DashboardPage() {
return (
<Suspense fallback={<DashboardShimmer />}>
<Dashboard />
</Suspense>
)
}
15 changes: 12 additions & 3 deletions components/todo-list-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,17 @@ const TodoListTableRow = ({ todo, showActions }: TodoListTableRowProps) => {
type TodoListTableBodyProps = {
tasks?: TTask[]
isLoading?: boolean
isPlaceholderData?: boolean
showActions?: boolean
}

const TodoListTableBody = ({ tasks, isLoading, showActions }: TodoListTableBodyProps) => {
if (isLoading) {
const TodoListTableBody = ({
tasks,
isLoading,
isPlaceholderData,
showActions,
}: TodoListTableBodyProps) => {
if (isLoading || isPlaceholderData) {
return (
<TableBody>
{new Array(5).fill(0).map((_, index) => (
Expand Down Expand Up @@ -137,6 +143,7 @@ export const TodoListTableRowShimmer = ({ showActions = true }: { showActions?:
type TodoListTableProps = {
tasks?: TTask[]
isLoading?: boolean
isPlaceholderData?: boolean
showActions?: boolean
includeDone?: boolean
onIncludeDoneChange?: (checked: boolean) => void
Expand All @@ -145,6 +152,7 @@ type TodoListTableProps = {
export const TodoListTable = ({
tasks,
isLoading,
isPlaceholderData,
showActions,
includeDone,
onIncludeDoneChange,
Expand Down Expand Up @@ -188,7 +196,7 @@ export const TodoListTable = ({
containerClassName="w-full lg:max-w-xs"
onChange={(e) => handleSearch(e.target.value)}
/>
{currentTab == DashboardTasksTableTabs.All && (
{currentTab !== DashboardTasksTableTabs.WatchList && (
<div className="flex px-4">
<Switch
id="includeDoneTasks"
Expand All @@ -208,6 +216,7 @@ export const TodoListTable = ({
<TodoListTableBody
tasks={filteredTasks}
isLoading={isLoading}
isPlaceholderData={isPlaceholderData}
showActions={showActions}
/>
</Table>
Expand Down
13 changes: 13 additions & 0 deletions modules/dashboard/components/dashboard-tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ type DashboardTabsProps = {
tasks: TTask[]
className?: string
includeDone: boolean
isPlaceholderData: boolean
onIncludeDoneChange: (checked: boolean) => void
}

export const DashboardTabs = ({
tasks,
className,
includeDone,
isPlaceholderData,
onIncludeDoneChange,
}: DashboardTabsProps) => {
const router = useRouter()
Expand All @@ -29,6 +31,16 @@ export const DashboardTabs = ({
const handleTabChange = (value: string) => {
const params = new URLSearchParams(searchParams)
params.set('tab', value)

if (value === TabsConstants.WatchList) {
params.delete('status')
} else {
if (includeDone) {
params.set('status', 'Done')
} else {
params.delete('status')
}
}
router.push(`${pathname}?${params.toString()}`)
}

Expand All @@ -53,6 +65,7 @@ export const DashboardTabs = ({
<TodoListTable
showActions
tasks={tasks}
isPlaceholderData={isPlaceholderData}
includeDone={includeDone}
onIncludeDoneChange={onIncludeDoneChange}
/>
Expand Down
11 changes: 10 additions & 1 deletion modules/dashboard/components/dashboard-watchlist-table.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
'use client'

import { TasksApi } from '@/api/tasks/tasks.api'
import { CommonPageError } from '@/components/common-page-error'
import { TodoListTable } from '@/components/todo-list-table'
import { useQuery } from '@tanstack/react-query'
import { useSearchParams } from 'next/navigation'
import { DashboardTasksTableTabs as TabsConstants } from '../constants'

export const DashboardWatchlistTable = () => {
const searchParams = useSearchParams()
const tab = searchParams.get('tab')
const status = searchParams.get('status')
const isInvalidCombination = tab === TabsConstants.WatchList && status === 'Done'

const { data, isLoading, isError } = useQuery({
queryKey: TasksApi.getWatchListTasks.key,
queryFn: TasksApi.getWatchListTasks.fn,
Expand All @@ -17,7 +26,7 @@ export const DashboardWatchlistTable = () => {
})),
})

if (isError) {
if (isError || isInvalidCombination) {
return <CommonPageError />
}
Comment on lines +29 to 31
Copy link

Choose a reason for hiding this comment

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

Incorrect Error Handling for Invalid URL Parameters category Error Handling

Tell me more
What is the issue?

Using CommonPageError for an invalid combination of URL parameters is inappropriate as it suggests a system error rather than a user navigation error.

Why this matters

Users encountering this error won't understand why they're seeing a generic error page when they've simply accessed an invalid URL combination. This could lead to confusion and unnecessary support tickets.

Suggested change ∙ Feature Preview

Create a specific error component for invalid URL parameters or redirect to a valid state:

if (isError) {
    return <CommonPageError />
}

if (isInvalidCombination) {
    return <div>Cannot view completed tasks in Watchlist view</div>
    // Or redirect to a valid state:
    // router.replace('/dashboard?tab=watchlist')
}
Provide feedback to improve future suggestions

Nice Catch Incorrect Not in Scope Not in coding standard Other

💬 Looking for more details? Reply to this comment to chat with Korbit.


Expand Down
38 changes: 31 additions & 7 deletions modules/dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,47 @@ import { TasksApi } from '@/api/tasks/tasks.api'
import { GetTaskReqDto } from '@/api/tasks/tasks.types'
import { CommonPageError } from '@/components/common-page-error'
import { PageContainer } from '@/components/page-container'
import { useQuery } from '@tanstack/react-query'
import { useState } from 'react'
import { keepPreviousData, useQuery } from '@tanstack/react-query'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useEffect, useRef, useState } from 'react'
import { DashboardHeader } from './components/dashboard-header'
import { DashboardShimmer } from './components/dashboard-shimmer'
import { DashboardTabs } from './components/dashboard-tabs'
import { DashboardWelcomeScreen } from './components/dashboard-welcome-screen'

export const Dashboard = () => {
const [includeDoneTasks, setIncludeDoneTasks] = useState(false)
const router = useRouter()
const pathname = usePathname()
const searchParams = useSearchParams()
const status = searchParams.get('status')
const isFirstLoad = useRef(true)

const queryParams: GetTaskReqDto | undefined = includeDoneTasks ? { status: 'DONE' } : undefined
const [includeDoneTasks, setIncludeDoneTasks] = useState(status === 'Done')
const handleIncludeDoneChange = (checked: boolean) => {
setIncludeDoneTasks(checked)

const params = new URLSearchParams(searchParams)
if (checked) {
params.set('status', 'Done')
} else {
params.delete('status')
}
router.push(`${pathname}?${params.toString()}`)
}

const { data, isLoading, isError } = useQuery({
const queryParams: GetTaskReqDto | undefined = includeDoneTasks ? { status: 'DONE' } : undefined
const { data, isLoading, isError, isPlaceholderData } = useQuery({
queryKey: TasksApi.getTasks.key(queryParams),
queryFn: () => TasksApi.getTasks.fn(queryParams),
placeholderData: keepPreviousData,
})
useEffect(() => {
if (!isLoading) {
isFirstLoad.current = false
}
}, [isLoading])

if (isLoading) {
if (isLoading && isFirstLoad.current) {
return <DashboardShimmer />
}

Expand All @@ -40,8 +63,9 @@ export const Dashboard = () => {
<div className="container mx-auto">
<DashboardTabs
tasks={data.tasks}
isPlaceholderData={isPlaceholderData}
includeDone={includeDoneTasks}
onIncludeDoneChange={setIncludeDoneTasks}
onIncludeDoneChange={handleIncludeDoneChange}
/>
</div>
</PageContainer>
Expand Down