mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 10:42:08 +00:00
Docs and format: Update documentation for hooks and format code
Docs: begin work on updating documentation for hooks
This commit is contained in:
@@ -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}
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
|
||||
|
||||
@@ -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.');
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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('');
|
||||
|
||||
Reference in New Issue
Block a user