Docs and format: Update documentation for hooks and format code

Docs: begin work on updating documentation for hooks
This commit is contained in:
Aaron William Po
2023-05-03 00:07:24 -04:00
parent 196d09161a
commit 1971959ea4
16 changed files with 144 additions and 60 deletions

View File

@@ -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}
*/

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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) => {

View File

@@ -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);

View File

@@ -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(

View File

@@ -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,
};
};

View File

@@ -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) => {

View File

@@ -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 };
};

View File

@@ -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.');
}

View File

@@ -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) {

View File

@@ -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(

View File

@@ -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.

View File

@@ -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();

View File

@@ -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');

View File

@@ -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('');