From 1971959ea41f5e86c7fbfdeed2b765c349542117 Mon Sep 17 00:00:00 2001 From: Aaron William Po Date: Wed, 3 May 2023 00:07:24 -0400 Subject: [PATCH] Docs and format: Update documentation for hooks and format code Docs: begin work on updating documentation for hooks --- src/hooks/auth/useRedirectIfLoggedIn.ts | 9 +++++--- src/hooks/auth/useUser.ts | 12 ++++++----- .../beer-comments/useBeerPostComments.ts | 19 ++++++++++++----- .../beer-likes/useBeerPostLikeCount.ts | 8 +++++-- .../beer-likes/useCheckIfUserLikesBeerPost.ts | 15 ++++++------- .../beer-posts/useBeerPostSearch.ts | 8 ++++--- .../data-fetching/beer-posts/useBeerPosts.ts | 21 +++++++++++++------ .../beer-posts/useBeerPostsByBrewery.ts | 11 +++++++++- .../useBreweryPostComments.ts | 19 +++++++++++------ .../useCheckIfUserLikesBreweryPost.ts | 14 ++++++++++++- .../useGetBreweryPostLikeCount.ts | 16 ++++++++++---- .../brewery-posts/useBreweryPosts.ts | 16 +++++++++----- src/hooks/utilities/useGeolocation.ts | 3 +-- src/hooks/utilities/useNavbar.ts | 5 ++++- src/hooks/utilities/useTheme.ts | 17 +++++++++------ src/hooks/utilities/useTimeDistance.ts | 11 +++++++--- 16 files changed, 144 insertions(+), 60 deletions(-) diff --git a/src/hooks/auth/useRedirectIfLoggedIn.ts b/src/hooks/auth/useRedirectIfLoggedIn.ts index d8d444e..ee6d16a 100644 --- a/src/hooks/auth/useRedirectIfLoggedIn.ts +++ b/src/hooks/auth/useRedirectIfLoggedIn.ts @@ -3,9 +3,12 @@ import { useRouter } from 'next/router'; import { useContext } from 'react'; /** - * Custom React hook that redirects the user to the home page if they are logged in. This - * hook is used to prevent logged in users from accessing the login and signup pages. Must - * be used under the UserContext provider. + * Custom React hook that redirects the user to the home page if they are logged in. + * + * This hook is used to prevent logged in users from accessing the login and signup pages + * by redirecting them to the home page. + * + * This hook should only be used in a component that is under the UserContext provider. * * @returns {void} */ diff --git a/src/hooks/auth/useUser.ts b/src/hooks/auth/useUser.ts index 10a5359..86c4a9f 100644 --- a/src/hooks/auth/useUser.ts +++ b/src/hooks/auth/useUser.ts @@ -5,11 +5,13 @@ import useSWR from 'swr'; /** * A custom React hook that fetches the current user's data from the server. * - * @returns An object containing the current user's data, a boolean indicating if the - * request is currently loading, and an error object if an error occurred during the - * request. - * @throws When the user is not logged in, the server returns an error status code, or if - * the response data fails to validate against the expected schema. + * @returns An object with the following properties: + * + * - `user`: The current user's data. + * - `isLoading`: A boolean indicating whether the request is still in progress. + * - `error`: An error object if the user is not logged in, if the response data fails to + * validate against the expected schema, or if the server returns an error. + * - `mutate`: A function that can be used to mutate the current user's data. */ const useUser = () => { const { diff --git a/src/hooks/data-fetching/beer-comments/useBeerPostComments.ts b/src/hooks/data-fetching/beer-comments/useBeerPostComments.ts index 126ac8c..32e39ba 100644 --- a/src/hooks/data-fetching/beer-comments/useBeerPostComments.ts +++ b/src/hooks/data-fetching/beer-comments/useBeerPostComments.ts @@ -16,22 +16,31 @@ interface UseBeerPostCommentsProps { * @param props.pageNum - The page number of the comments to fetch. * @param props.id - The ID of the beer post to fetch comments for. * @param props.pageSize - The number of comments to fetch per page. - * @returns An object containing the fetched comments, the total number of comment pages, - * a boolean indicating if the request is currently loading, and a function to mutate - * the data. + * @returns An object with the following properties: + * + * - `comments`: The comments for the beer post. + * - `isLoading`: A boolean indicating whether the comments are being fetched. + * - `error`: The error that occurred while fetching the comments. + * - `mutate`: A function to mutate the comments. + * - `size`: The number of pages of comments that have been fetched. + * - `setSize`: A function to set the number of pages of comments that have been fetched. + * - `isLoadingMore`: A boolean indicating whether more comments are being fetched. + * - `isAtEnd`: A boolean indicating whether all comments have been fetched. + * - `pageCount`: The total number of pages of comments. */ const useBeerPostComments = ({ id, pageSize }: UseBeerPostCommentsProps) => { const fetcher = async (url: string) => { const response = await fetch(url); + const json = await response.json(); const count = response.headers.get('X-Total-Count'); - const parsed = APIResponseValidationSchema.safeParse(json); + const parsed = APIResponseValidationSchema.safeParse(json); if (!parsed.success) { throw new Error(parsed.error.message); } - const parsedPayload = z.array(CommentQueryResult).safeParse(parsed.data.payload); + const parsedPayload = z.array(CommentQueryResult).safeParse(parsed.data.payload); if (!parsedPayload.success) { throw new Error(parsedPayload.error.message); } diff --git a/src/hooks/data-fetching/beer-likes/useBeerPostLikeCount.ts b/src/hooks/data-fetching/beer-likes/useBeerPostLikeCount.ts index 513c06d..2300ef2 100644 --- a/src/hooks/data-fetching/beer-likes/useBeerPostLikeCount.ts +++ b/src/hooks/data-fetching/beer-likes/useBeerPostLikeCount.ts @@ -6,8 +6,12 @@ import useSWR from 'swr'; * Custom hook to fetch the like count for a beer post from the server. * * @param beerPostId - The ID of the beer post to fetch the like count for. - * @returns An object with the current like count, as well as metadata about the current - * state of the request. + * @returns An object with the following properties: + * + * - `error`: The error that occurred while fetching the like count. + * - `isLoading`: A boolean indicating whether the like count is being fetched. + * - `mutate`: A function to mutate the like count. + * - `likeCount`: The like count for the beer post. */ const useGetBeerPostLikeCount = (beerPostId: string) => { diff --git a/src/hooks/data-fetching/beer-likes/useCheckIfUserLikesBeerPost.ts b/src/hooks/data-fetching/beer-likes/useCheckIfUserLikesBeerPost.ts index ce44b6c..3425ed3 100644 --- a/src/hooks/data-fetching/beer-likes/useCheckIfUserLikesBeerPost.ts +++ b/src/hooks/data-fetching/beer-likes/useCheckIfUserLikesBeerPost.ts @@ -9,22 +9,23 @@ import { z } from 'zod'; * data from the server. * * @param beerPostId The ID of the beer post to check for likes. - * @returns An object containing a boolean indicating if the user has liked the beer post, - * an error object if an error occurred during the request, and a boolean indicating if - * the request is currently loading. - * @throws When the user is not logged in, the server returns an error status code, or if - * the response data fails to validate against the expected schema. + * @returns An object with the following properties: + * + * - `error`: The error that occurred while fetching the data. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `mutate`: A function to mutate the data. + * - `isLiked`: A boolean indicating whether the current user has liked the beer post. */ const useCheckIfUserLikesBeerPost = (beerPostId: string) => { const { user } = useContext(UserContext); const { data, error, isLoading, mutate } = useSWR( `/api/beers/${beerPostId}/like/is-liked`, - async () => { + async (url) => { if (!user) { throw new Error('User is not logged in.'); } - const response = await fetch(`/api/beers/${beerPostId}/like/is-liked`); + const response = await fetch(url); const json = await response.json(); const parsed = APIResponseValidationSchema.safeParse(json); diff --git a/src/hooks/data-fetching/beer-posts/useBeerPostSearch.ts b/src/hooks/data-fetching/beer-posts/useBeerPostSearch.ts index 3f20ea2..d07e606 100644 --- a/src/hooks/data-fetching/beer-posts/useBeerPostSearch.ts +++ b/src/hooks/data-fetching/beer-posts/useBeerPostSearch.ts @@ -5,9 +5,11 @@ import { z } from 'zod'; * A custom React hook that searches for beer posts that match a given query string. * * @param query The search query string to match beer posts against. - * @returns An object containing an array of search results matching the query, an error - * object if an error occurred during the search, and a boolean indicating if the - * request is currently loading. + * @returns An object with the following properties: + * + * - `searchResults`: The beer posts that match the search query. + * - `searchError`: The error that occurred while fetching the data. + * - `isLoading`: A boolean indicating whether the data is being fetched. */ const useBeerPostSearch = (query: string | undefined) => { const { data, isLoading, error } = useSWR( diff --git a/src/hooks/data-fetching/beer-posts/useBeerPosts.ts b/src/hooks/data-fetching/beer-posts/useBeerPosts.ts index 7ec1f4b..043a35e 100644 --- a/src/hooks/data-fetching/beer-posts/useBeerPosts.ts +++ b/src/hooks/data-fetching/beer-posts/useBeerPosts.ts @@ -8,7 +8,16 @@ import { z } from 'zod'; * * @param options The options to use when fetching beer posts. * @param options.pageSize The number of beer posts to fetch per page. - * @returns An object containing the beer posts, page count, and loading state. + * @returns An object with the following properties: + * + * - `beerPosts`: The beer posts fetched from the API. + * - `error`: The error that occurred while fetching the data. + * - `isAtEnd`: A boolean indicating whether all data has been fetched. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `isLoadingMore`: A boolean indicating whether more data is being fetched. + * - `pageCount`: The total number of pages of data. + * - `setSize`: A function to set the size of the data. + * - `size`: The size of the data. */ const useBeerPosts = ({ pageSize }: { pageSize: number }) => { const fetcher = async (url: string) => { @@ -49,13 +58,13 @@ const useBeerPosts = ({ pageSize }: { pageSize: number }) => { return { beerPosts, - pageCount, - size, - setSize, + error: error as unknown, + isAtEnd, isLoading, isLoadingMore, - isAtEnd, - error: error as unknown, + pageCount, + setSize, + size, }; }; diff --git a/src/hooks/data-fetching/beer-posts/useBeerPostsByBrewery.ts b/src/hooks/data-fetching/beer-posts/useBeerPostsByBrewery.ts index c0762cb..c1627fb 100644 --- a/src/hooks/data-fetching/beer-posts/useBeerPostsByBrewery.ts +++ b/src/hooks/data-fetching/beer-posts/useBeerPostsByBrewery.ts @@ -14,7 +14,16 @@ interface UseBeerPostsByBreweryParams { * @param options The options to use when fetching beer posts. * @param options.pageSize The number of beer posts to fetch per page. * @param options.breweryId The ID of the brewery to fetch beer posts for. - * @returns An object containing the beer posts, page count, and loading state. + * @returns An object with the following properties: + * + * - `beerPosts`: The beer posts fetched from the API. + * - `error`: The error that occurred while fetching the data. + * - `isAtEnd`: A boolean indicating whether all data has been fetched. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `isLoadingMore`: A boolean indicating whether more data is being fetched. + * - `pageCount`: The total number of pages of data. + * - `setSize`: A function to set the size of the data. + * - `size`: The size of the data. */ const UseBeerPostsByBrewery = ({ pageSize, breweryId }: UseBeerPostsByBreweryParams) => { const fetcher = async (url: string) => { diff --git a/src/hooks/data-fetching/brewery-comments/useBreweryPostComments.ts b/src/hooks/data-fetching/brewery-comments/useBreweryPostComments.ts index bb87859..d90dc1a 100644 --- a/src/hooks/data-fetching/brewery-comments/useBreweryPostComments.ts +++ b/src/hooks/data-fetching/brewery-comments/useBreweryPostComments.ts @@ -15,28 +15,35 @@ interface UseBreweryPostCommentsProps { * @param props.pageNum - The page number of the comments to fetch. * @param props.id - The ID of the brewery post to fetch comments for. * @param props.pageSize - The number of comments to fetch per page. - * @returns An object containing the fetched comments, the total number of comment pages, - * a boolean indicating if the request is currently loading, and a function to mutate - * the data. + * @returns An object with the following properties: + * + * - `comments`: The comments fetched from the API. + * - `error`: The error that occurred while fetching the data. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `isLoadingMore`: A boolean indicating whether more data is being fetched. + * - `isAtEnd`: A boolean indicating whether all data has been fetched. + * - `mutate`: A function to mutate the data. + * - `pageCount`: The total number of pages of data. + * - `setSize`: A function to set the size of the data. + * - `size`: The size of the data. */ const useBreweryPostComments = ({ id, pageSize }: UseBreweryPostCommentsProps) => { const fetcher = async (url: string) => { const response = await fetch(url); const json = await response.json(); const count = response.headers.get('X-Total-Count'); - const parsed = APIResponseValidationSchema.safeParse(json); + const parsed = APIResponseValidationSchema.safeParse(json); if (!parsed.success) { throw new Error(parsed.error.message); } - const parsedPayload = z.array(CommentQueryResult).safeParse(parsed.data.payload); + const parsedPayload = z.array(CommentQueryResult).safeParse(parsed.data.payload); if (!parsedPayload.success) { throw new Error(parsedPayload.error.message); } const pageCount = Math.ceil(parseInt(count as string, 10) / pageSize); - return { comments: parsedPayload.data, pageCount }; }; diff --git a/src/hooks/data-fetching/brewery-likes/useCheckIfUserLikesBreweryPost.ts b/src/hooks/data-fetching/brewery-likes/useCheckIfUserLikesBreweryPost.ts index 7574d55..910ca43 100644 --- a/src/hooks/data-fetching/brewery-likes/useCheckIfUserLikesBreweryPost.ts +++ b/src/hooks/data-fetching/brewery-likes/useCheckIfUserLikesBreweryPost.ts @@ -4,6 +4,18 @@ import { useContext } from 'react'; import useSWR from 'swr'; import { z } from 'zod'; +/** + * A custom React hook that checks if the current user likes a given brewery post. + * + * @param breweryPostId - The ID of the brewery post to check. + * @returns An object with the following properties: + * + * - `isLiked`: A boolean indicating whether the current user likes the brewery post. + * - `error`: The error that occurred while fetching the data. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `mutate`: A function to mutate the data. + */ + const useCheckIfUserLikesBreweryPost = (breweryPostId: string) => { const { user } = useContext(UserContext); const { data, error, isLoading, mutate } = useSWR( @@ -15,8 +27,8 @@ const useCheckIfUserLikesBreweryPost = (breweryPostId: string) => { const response = await fetch(`/api/breweries/${breweryPostId}/like/is-liked`); const json = await response.json(); + const parsed = APIResponseValidationSchema.safeParse(json); - if (!parsed.success) { throw new Error('Invalid API response.'); } diff --git a/src/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount.ts b/src/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount.ts index 0a1a20e..c2ba167 100644 --- a/src/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount.ts +++ b/src/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount.ts @@ -2,6 +2,17 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchem import useSWR from 'swr'; import { z } from 'zod'; +/** + * A custom React hook that fetches the number of likes a brewery post has. + * + * @param breweryPostId + * @returns An object with the following properties: + * + * - `likeCount`: The number of likes the brewery post has. + * - `error`: The error that occurred while fetching the data. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `mutate`: A function to mutate the data. + */ const useGetBreweryPostLikeCount = (breweryPostId: string) => { const { error, mutate, data, isLoading } = useSWR( `/api/breweries/${breweryPostId}/like`, @@ -10,15 +21,12 @@ const useGetBreweryPostLikeCount = (breweryPostId: string) => { const json = await response.json(); const parsed = APIResponseValidationSchema.safeParse(json); - if (!parsed.success) { throw new Error('Failed to parse API response'); } const parsedPayload = z - .object({ - likeCount: z.number(), - }) + .object({ likeCount: z.number() }) .safeParse(parsed.data.payload); if (!parsedPayload.success) { diff --git a/src/hooks/data-fetching/brewery-posts/useBreweryPosts.ts b/src/hooks/data-fetching/brewery-posts/useBreweryPosts.ts index 9f12c06..18127ee 100644 --- a/src/hooks/data-fetching/brewery-posts/useBreweryPosts.ts +++ b/src/hooks/data-fetching/brewery-posts/useBreweryPosts.ts @@ -8,7 +8,16 @@ import { z } from 'zod'; * * @param options The options to use when fetching brewery posts. * @param options.pageSize The number of brewery posts to fetch per page. - * @returns An object containing the brewery posts, page count, and loading state. + * @returns An object with the following properties: + * + * - `breweryPosts`: The brewery posts fetched from the API. + * - `error`: The error that occurred while fetching the data. + * - `isAtEnd`: A boolean indicating whether all data has been fetched. + * - `isLoading`: A boolean indicating whether the data is being fetched. + * - `isLoadingMore`: A boolean indicating whether more data is being fetched. + * - `pageCount`: The total number of pages of data. + * - `setSize`: A function to set the size of the data. + * - `size`: The size of the data. */ const useBreweryPosts = ({ pageSize }: { pageSize: number }) => { const fetcher = async (url: string) => { @@ -31,10 +40,7 @@ const useBreweryPosts = ({ pageSize }: { pageSize: number }) => { } const pageCount = Math.ceil(parseInt(count as string, 10) / pageSize); - return { - breweryPosts: parsedPayload.data, - pageCount, - }; + return { breweryPosts: parsedPayload.data, pageCount }; }; const { data, error, isLoading, setSize, size } = useSWRInfinite( diff --git a/src/hooks/utilities/useGeolocation.ts b/src/hooks/utilities/useGeolocation.ts index 277d248..8e0cea0 100644 --- a/src/hooks/utilities/useGeolocation.ts +++ b/src/hooks/utilities/useGeolocation.ts @@ -4,8 +4,7 @@ import { useEffect, useState } from 'react'; * A custom React Hook that retrieves and monitors the user's geolocation using the * browser's built-in `navigator.geolocation` API. * - * @returns An object containing the user's geolocation information and any errors that - * might occur. The object has the following properties: + * @returns An object with the following properties: * * - `coords` - The user's current geolocation coordinates, or null if the geolocation could * not be retrieved. diff --git a/src/hooks/utilities/useNavbar.ts b/src/hooks/utilities/useNavbar.ts index 73f90e8..c718a14 100644 --- a/src/hooks/utilities/useNavbar.ts +++ b/src/hooks/utilities/useNavbar.ts @@ -11,7 +11,10 @@ interface Page { * A custom hook that returns the current URL and the pages to display in the navbar. It * uses the user context to determine whether the user is authenticated or not. * - * @returns An object containing the current URL and the pages to display in the navbar. + * @returns An object with the following properties: + * + * - `currentURL`: The current URL. + * - `pages`: The pages to display in the navbar. */ const useNavbar = () => { const router = useRouter(); diff --git a/src/hooks/utilities/useTheme.ts b/src/hooks/utilities/useTheme.ts index 6aa0595..23c3b83 100644 --- a/src/hooks/utilities/useTheme.ts +++ b/src/hooks/utilities/useTheme.ts @@ -2,13 +2,18 @@ import { useState, useEffect } from 'react'; import useMediaQuery from './useMediaQuery'; /** - * A custom hook to manage the theme of the app. If a preferred theme is not set in - * localStorage, it will use what the user's browser prefers as determined by the - * prefers-color-scheme media query. If the user changes their preferred theme, it will be - * saved in localStorage and used in subsequent visits. + * A custom hook to manage the theme of the app. * - * @returns ThemeState.theme - The current theme of the app. - * @returns ThemeState.setTheme - A setter function to change the theme of the app. + * If a preferred theme is not set in localStorage, it will use what the user's browser + * prefers as determined by the prefers-color-scheme media query. + * + * If the user changes their preferred theme, it will be saved in localStorage and used in + * subsequent visits. + * + * @returns An object with the following properties: + * + * - `theme`: The current theme of the app. + * - `setTheme`: A function to set the theme of the app. */ const useTheme = () => { const [theme, setTheme] = useState<'light' | 'dark'>('light'); diff --git a/src/hooks/utilities/useTimeDistance.ts b/src/hooks/utilities/useTimeDistance.ts index 9d4f01b..f93a18b 100644 --- a/src/hooks/utilities/useTimeDistance.ts +++ b/src/hooks/utilities/useTimeDistance.ts @@ -2,12 +2,17 @@ import formatDistanceStrict from 'date-fns/formatDistanceStrict'; import { useState, useEffect } from 'react'; /** - * Returns the time distance between the provided date and the current time, using the - * `date-fns` `formatDistanceStrict` function. This hook ensures that the same result is - * calculated on both the server and client, preventing hydration errors. + * A custom hook to calculate the time distance between the provided date and the current + * time. + * + * This hook uses the date-fns library to calculate the time distance. + * + * This hook ensures that the same result is calculated on both the server and client, + * preventing hydration errors. * * @param createdAt The date to calculate the time distance from. * @returns The time distance between the provided date and the current time. + * @see https://date-fns.org/v2.30.0/docs/formatDistanceStrict */ const useTimeDistance = (createdAt: Date) => { const [timeDistance, setTimeDistance] = useState('');