Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
SKairinos committed Aug 8, 2024
1 parent 999993a commit 4144bb1
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 82 deletions.
37 changes: 0 additions & 37 deletions src/hooks/api.ts

This file was deleted.

83 changes: 83 additions & 0 deletions src/hooks/api.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { CircularProgress } from "@mui/material"
import type { TypedUseQuery } from "@reduxjs/toolkit/query/react"
import {
useState,
type Dispatch,
type ReactNode,
type SetStateAction,
} from "react"

import SyncError from "../components/SyncError"

export type Pagination = { page: number; limit: number; offset: number }
export type SetPagination = Dispatch<
SetStateAction<{ page: number; limit: number }>
>
export type UsePaginationOptions = Partial<{
page: number
limit: number
}>

export function usePagination(
options?: UsePaginationOptions,
): [Pagination, SetPagination] {
const { page = 0, limit = 150 } = options || {}

const [pagination, _setPagination] = useState<Pagination>({
page,
limit,
offset: page * limit,
})

const setPagination: SetPagination = value => {
_setPagination(({ page: previousPage, limit: previousLimit }) => {
let { page, limit } =
typeof value === "function"
? value({ page: previousPage, limit: previousLimit })
: value

if (limit !== previousLimit) page = 0

return { page, limit, offset: page * limit }
})
}

return [pagination, setPagination]
}

export type UseQueryManagerOptions = Partial<{
loading: ReactNode
error: ReactNode
}>

export function useQueryManager<QueryArg, ResultType>(
useQuery: TypedUseQuery<ResultType, QueryArg, any>,
arg: QueryArg,
children: (data: ResultType) => ReactNode,
options?: UseQueryManagerOptions,
): ReactNode {
const { data, isLoading, isSuccess, error } = useQuery(arg)

const {
loading: loadingNode = <CircularProgress />,
error: errorNode = <SyncError />,
} = options || {}

// An error occurred.
if (error) {
console.error(error)
return errorNode
}

// Busy calling the API.
if (isLoading) return loadingNode

// Called the API and got data.
if (data) return children(data)

// Called the API and did not get data.
if (isSuccess) throw Error("Expected to get data from API but got nothing.")

// Have yet to call the API.
return loadingNode
}
4 changes: 4 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
usePagination,
useQueryManager,
type Pagination,
type SetPagination,
type UsePaginationOptions,
type UseQueryManagerOptions,
} from "./api"
import {
useSession,
Expand All @@ -23,13 +25,15 @@ export {
useNavigate,
usePagination,
useParams,
useQueryManager,
useSearchParams,
useSession,
useSessionMetadata,
type Pagination,
type SessionMetadata,
type SetPagination,
type UsePaginationOptions,
type UseQueryManagerOptions,
type UseSessionChildren,
type UseSessionChildrenFunction,
type UseSessionOptions,
Expand Down
47 changes: 2 additions & 45 deletions src/utils/api.tsx → src/utils/api.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { CircularProgress } from "@mui/material"
import type {
FetchBaseQueryError,
TypedUseQuery,
} from "@reduxjs/toolkit/query/react"
import type { ReactNode } from "react"

import { SyncError } from "../components"
import type { FetchBaseQueryError } from "@reduxjs/toolkit/query/react"

import type { Optional, Required } from "./general"

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -247,40 +241,3 @@ export function tagData<Type extends string, M extends Model<any>>(
return []
}
}

export type UseQueryManagerOptions = Partial<{
loading: ReactNode
error: ReactNode
}>

export function useQueryManager<QueryArg, ResultType>(
useQuery: TypedUseQuery<ResultType, QueryArg, any>,
arg: QueryArg,
children: (data: ResultType) => ReactNode,
options?: UseQueryManagerOptions,
): ReactNode {
const { data, isLoading, isSuccess, error } = useQuery(arg)

const {
loading: loadingNode = <CircularProgress />,
error: errorNode = <SyncError />,
} = options || {}

// An error occurred.
if (error) {
console.error(error)
return errorNode
}

// Busy calling the API.
if (isLoading) return loadingNode

// Called the API and got data.
if (data) return children(data)

// Called the API and did not get data.
if (isSuccess) throw Error("Expected to get data from API but got nothing.")

// Have yet to call the API.
return loadingNode
}

0 comments on commit 4144bb1

Please sign in to comment.