Updated all api calls to use new apiCallFactory.
This commit is contained in:
parent
c54d3832a3
commit
a3376a8cc1
@ -1,27 +1,21 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import { ApiError } from './ApiError'
|
import Refresh from '../types/Refresh'
|
||||||
import ExpiredTokenError from './ExpiredTokenError'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import { addBearer } from './util'
|
|
||||||
|
|
||||||
export interface AddStarDeps {
|
export interface AddStarDeps {
|
||||||
accessToken: AccessToken
|
accessToken: AccessToken
|
||||||
|
refresh: Refresh
|
||||||
username: string
|
username: string
|
||||||
slug: string
|
slug: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const addStar = async ({ slug, accessToken, username }: AddStarDeps): Promise<void> => {
|
const doAddStar = apiCallFactory<void>('POST')
|
||||||
const headers = new Headers()
|
|
||||||
addBearer(headers, accessToken)
|
const addStar = ({ accessToken, refresh, username, slug }: AddStarDeps) =>
|
||||||
const response = await fetch(import.meta.env.VITE_MME_API_URL + `/recipes/${username}/${slug}/star`, {
|
doAddStar({
|
||||||
headers,
|
accessToken,
|
||||||
method: 'POST',
|
endpoint: `/recipes/${username}/${slug}/star`,
|
||||||
mode: 'cors'
|
refresh
|
||||||
})
|
})
|
||||||
if (response.status === 401) {
|
|
||||||
throw new ExpiredTokenError()
|
|
||||||
} else if (!response.ok) {
|
|
||||||
throw new ApiError(response.status, response.statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default addStar
|
export default addStar
|
||||||
|
@ -2,38 +2,87 @@ import AccessToken from '../types/AccessToken'
|
|||||||
import Refresh from '../types/Refresh'
|
import Refresh from '../types/Refresh'
|
||||||
import { ApiError } from './ApiError'
|
import { ApiError } from './ApiError'
|
||||||
|
|
||||||
export interface ApiCallDeps {
|
|
||||||
accessToken: AccessToken | null
|
|
||||||
endpoint: string
|
|
||||||
query?: string
|
|
||||||
refresh: Refresh
|
|
||||||
signal: AbortSignal
|
|
||||||
body?: any
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
||||||
|
|
||||||
const getApiCallFactory =
|
export type ApiCallFactoryDeps<T> = WithHandleJson<T> | WithHandleResponse<T>
|
||||||
(method: Method) =>
|
|
||||||
<T>(handleBody?: (raw: any) => T) =>
|
export interface WithHandleJson<T> {
|
||||||
async ({ accessToken, endpoint, refresh, signal, body }: ApiCallDeps): Promise<T> => {
|
handleJson: (raw: any) => T
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WithHandleResponse<T> {
|
||||||
|
handleResponse: (response: Response) => Promise<T> | T
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiCallDeps = {
|
||||||
|
accessToken: AccessToken | null
|
||||||
|
refresh: Refresh
|
||||||
|
signal?: AbortSignal
|
||||||
|
body?: any
|
||||||
|
} & (WithEndpoint | WithUrl)
|
||||||
|
|
||||||
|
export interface WithEndpoint {
|
||||||
|
endpoint: string
|
||||||
|
query?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WithUrl {
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiCall<T> = (deps: ApiCallDeps) => Promise<T>
|
||||||
|
|
||||||
|
export interface ApiCallFactory<T> {
|
||||||
|
(method: Method): ApiCall<void>
|
||||||
|
(method: Method, handleBody: (raw: any) => T): ApiCall<T>
|
||||||
|
(method: Method, deps: ApiCallFactoryDeps<T>): ApiCall<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleResult = async <T>(
|
||||||
|
handleBodyOrDeps: ((raw: any) => T) | ApiCallFactoryDeps<T>,
|
||||||
|
response: Response
|
||||||
|
): Promise<T> => {
|
||||||
|
if (typeof handleBodyOrDeps === 'function') {
|
||||||
|
return handleBodyOrDeps(await response.json())
|
||||||
|
} else {
|
||||||
|
const deps = handleBodyOrDeps
|
||||||
|
if ('handleResponse' in deps) {
|
||||||
|
return deps.handleResponse(response)
|
||||||
|
} else {
|
||||||
|
return deps.handleJson(await response.json())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiCallFactory = <T>(
|
||||||
|
method: Method,
|
||||||
|
handleBodyOrDeps?: ((raw: any) => T) | ApiCallFactoryDeps<T>
|
||||||
|
): ApiCall<typeof handleBodyOrDeps extends undefined ? void : T> => {
|
||||||
|
return (async (deps: ApiCallDeps): Promise<void | T> => {
|
||||||
|
const { accessToken, refresh, signal } = deps
|
||||||
const headers = new Headers()
|
const headers = new Headers()
|
||||||
if (accessToken) {
|
if (accessToken) {
|
||||||
headers.set('Authorization', `Bearer ${accessToken.token}`)
|
headers.set('Authorization', `Bearer ${accessToken.token}`)
|
||||||
}
|
}
|
||||||
if (body) {
|
if (deps.body) {
|
||||||
headers.set('Content-type', 'application/json')
|
headers.set('Content-type', 'application/json')
|
||||||
}
|
}
|
||||||
const url = import.meta.env.VITE_MME_API_URL + endpoint
|
const url =
|
||||||
|
'url' in deps
|
||||||
|
? deps.url
|
||||||
|
: deps.query
|
||||||
|
? import.meta.env.VITE_MME_API_URL + deps.endpoint + '?' + deps.query
|
||||||
|
: import.meta.env.VITE_MME_API_URL + deps.endpoint
|
||||||
|
const body = deps.body ? JSON.stringify(deps.body) : undefined
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
body: body ? JSON.stringify(body) : undefined,
|
body,
|
||||||
signal,
|
signal,
|
||||||
headers,
|
headers,
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
method
|
method
|
||||||
})
|
})
|
||||||
if (response.ok && handleBody) {
|
if (response.ok && handleBodyOrDeps) {
|
||||||
return handleBody(await response.json())
|
return handleResult(handleBodyOrDeps, response)
|
||||||
} else if (response.status === 401) {
|
} else if (response.status === 401) {
|
||||||
const newToken = await refresh()
|
const newToken = await refresh()
|
||||||
if (newToken === null) {
|
if (newToken === null) {
|
||||||
@ -41,22 +90,21 @@ const getApiCallFactory =
|
|||||||
}
|
}
|
||||||
headers.set('Authorization', `Bearer ${newToken.token}`)
|
headers.set('Authorization', `Bearer ${newToken.token}`)
|
||||||
const retry = await fetch(url, {
|
const retry = await fetch(url, {
|
||||||
|
body,
|
||||||
signal,
|
signal,
|
||||||
headers,
|
headers,
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
method
|
method
|
||||||
})
|
})
|
||||||
if (retry.ok && handleBody) {
|
if (retry.ok && handleBodyOrDeps) {
|
||||||
return handleBody(await retry.json())
|
return handleResult(handleBodyOrDeps, retry)
|
||||||
} else {
|
} else if (!retry.ok) {
|
||||||
throw new ApiError(retry.status, retry.statusText)
|
throw new ApiError(retry.status, retry.statusText)
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!response.ok) {
|
||||||
throw new ApiError(response.status, response.statusText)
|
throw new ApiError(response.status, response.statusText)
|
||||||
}
|
}
|
||||||
}
|
}) as ApiCall<T>
|
||||||
|
}
|
||||||
|
|
||||||
export const getCallFactory = getApiCallFactory('GET')
|
export default apiCallFactory
|
||||||
export const postCallFactory = getApiCallFactory('POST')
|
|
||||||
export const putCallFactory = getApiCallFactory('PUT')
|
|
||||||
export const deleteCallFactory = getApiCallFactory('DELETE')
|
|
||||||
|
@ -1,31 +1,24 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import { ApiError } from './ApiError'
|
import Refresh from '../types/Refresh'
|
||||||
import ExpiredTokenError from './ExpiredTokenError'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import { addBearer } from './util'
|
|
||||||
|
|
||||||
export interface GetImageDeps {
|
export interface GetImageDeps {
|
||||||
accessToken: AccessToken | null
|
accessToken: AccessToken | null
|
||||||
|
refresh: Refresh
|
||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const getImage = async ({ accessToken, signal, url }: GetImageDeps): Promise<string> => {
|
const doGetImage = apiCallFactory('GET', {
|
||||||
const headers = new Headers()
|
handleResponse: async res => URL.createObjectURL(await res.blob())
|
||||||
if (accessToken !== null) {
|
})
|
||||||
addBearer(headers, accessToken)
|
|
||||||
}
|
const getImage = async ({ accessToken, refresh, signal, url }: GetImageDeps) =>
|
||||||
const response = await fetch(url, {
|
doGetImage({
|
||||||
headers,
|
accessToken,
|
||||||
mode: 'cors',
|
refresh,
|
||||||
signal
|
signal,
|
||||||
|
url
|
||||||
})
|
})
|
||||||
if (response.ok) {
|
|
||||||
return URL.createObjectURL(await response.blob())
|
|
||||||
} else if (response.status === 401) {
|
|
||||||
throw new ExpiredTokenError()
|
|
||||||
} else {
|
|
||||||
throw new ApiError(response.status, response.statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default getImage
|
export default getImage
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import { ApiError } from './ApiError'
|
import Refresh from '../types/Refresh'
|
||||||
import ExpiredTokenError from './ExpiredTokenError'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import GetRecipeView, {
|
import GetRecipeView, {
|
||||||
GetRecipeViewWithRawText,
|
GetRecipeViewWithRawText,
|
||||||
RawGetRecipeView,
|
|
||||||
RawGetRecipeViewWithRawText,
|
|
||||||
toGetRecipeView,
|
toGetRecipeView,
|
||||||
toGetRecipeViewWithRawText
|
toGetRecipeViewWithRawText
|
||||||
} from './types/GetRecipeView'
|
} from './types/GetRecipeView'
|
||||||
import { addBearer } from './util'
|
|
||||||
|
|
||||||
export interface GetRecipeCommonDeps {
|
export interface GetRecipeCommonDeps {
|
||||||
accessToken: AccessToken | null
|
accessToken: AccessToken | null
|
||||||
username: string
|
refresh: Refresh
|
||||||
slug: string
|
slug: string
|
||||||
abortSignal: AbortSignal
|
signal: AbortSignal
|
||||||
|
username: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GetRecipeDeps extends GetRecipeCommonDeps {
|
export interface GetRecipeDeps extends GetRecipeCommonDeps {
|
||||||
@ -30,33 +28,33 @@ export interface GetRecipe {
|
|||||||
(deps: GetRecipeDepsIncludeRawText): Promise<GetRecipeViewWithRawText>
|
(deps: GetRecipeDepsIncludeRawText): Promise<GetRecipeViewWithRawText>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const doGetRecipe = apiCallFactory('GET', toGetRecipeView)
|
||||||
|
const doGetRecipeIncludeRawText = apiCallFactory('GET', toGetRecipeViewWithRawText)
|
||||||
|
|
||||||
const getRecipe = (async ({
|
const getRecipe = (async ({
|
||||||
accessToken,
|
accessToken,
|
||||||
username,
|
includeRawText,
|
||||||
|
refresh,
|
||||||
slug,
|
slug,
|
||||||
abortSignal,
|
signal,
|
||||||
includeRawText
|
username
|
||||||
}: GetRecipeDeps | GetRecipeDepsIncludeRawText): Promise<GetRecipeView | GetRecipeViewWithRawText> => {
|
}: GetRecipeDeps | GetRecipeDepsIncludeRawText): Promise<GetRecipeView | GetRecipeViewWithRawText> => {
|
||||||
const headers = new Headers()
|
const endpoint = `/recipes/${username}/${slug}`
|
||||||
if (accessToken !== null) {
|
if (includeRawText) {
|
||||||
addBearer(headers, accessToken)
|
return doGetRecipeIncludeRawText({
|
||||||
}
|
accessToken,
|
||||||
const query = includeRawText ? '?includeRawText=true' : ''
|
endpoint,
|
||||||
const response = await fetch(import.meta.env.VITE_MME_API_URL + `/recipes/${username}/${slug}${query}`, {
|
query: 'includeRawText=true',
|
||||||
signal: abortSignal,
|
refresh,
|
||||||
headers,
|
signal
|
||||||
mode: 'cors'
|
})
|
||||||
})
|
|
||||||
if (response.ok) {
|
|
||||||
if (includeRawText) {
|
|
||||||
return toGetRecipeViewWithRawText((await response.json()) as RawGetRecipeViewWithRawText)
|
|
||||||
} else {
|
|
||||||
return toGetRecipeView((await response.json()) as RawGetRecipeView)
|
|
||||||
}
|
|
||||||
} else if (response.status === 401) {
|
|
||||||
throw new ExpiredTokenError()
|
|
||||||
} else {
|
} else {
|
||||||
throw new ApiError(response.status, response.statusText)
|
return doGetRecipe({
|
||||||
|
accessToken,
|
||||||
|
endpoint,
|
||||||
|
refresh,
|
||||||
|
signal
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}) as GetRecipe
|
}) as GetRecipe
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import Refresh from '../types/Refresh'
|
import Refresh from '../types/Refresh'
|
||||||
import { getCallFactory } from './apiCallFactory'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import { toRecipeInfosView } from './types/RecipeInfosView'
|
import { toRecipeInfosView } from './types/RecipeInfosView'
|
||||||
|
|
||||||
export interface GetRecipeInfosDeps {
|
export interface GetRecipeInfosDeps {
|
||||||
@ -11,7 +11,7 @@ export interface GetRecipeInfosDeps {
|
|||||||
signal: AbortSignal
|
signal: AbortSignal
|
||||||
}
|
}
|
||||||
|
|
||||||
const doGetRecipeInfos = getCallFactory(toRecipeInfosView)
|
const doGetRecipeInfos = apiCallFactory('GET', toRecipeInfosView)
|
||||||
|
|
||||||
const getRecipeInfos = ({ accessToken, pageNumber, pageSize, refresh, signal }: GetRecipeInfosDeps) =>
|
const getRecipeInfos = ({ accessToken, pageNumber, pageSize, refresh, signal }: GetRecipeInfosDeps) =>
|
||||||
doGetRecipeInfos({
|
doGetRecipeInfos({
|
||||||
|
@ -1,27 +1,21 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import { ApiError } from './ApiError'
|
import Refresh from '../types/Refresh'
|
||||||
import ExpiredTokenError from './ExpiredTokenError'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import { addBearer } from './util'
|
|
||||||
|
|
||||||
export interface RemoveStarDeps {
|
export interface RemoveStarDeps {
|
||||||
accessToken: AccessToken
|
accessToken: AccessToken
|
||||||
|
refresh: Refresh
|
||||||
username: string
|
username: string
|
||||||
slug: string
|
slug: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeStar = async ({ accessToken, username, slug }: RemoveStarDeps) => {
|
const doRemoveStar = apiCallFactory<void>('DELETE')
|
||||||
const headers = new Headers()
|
|
||||||
addBearer(headers, accessToken)
|
const removeStar = ({ accessToken, refresh, username, slug }: RemoveStarDeps) =>
|
||||||
const response = await fetch(import.meta.env.VITE_MME_API_URL + `/recipes/${username}/${slug}/star`, {
|
doRemoveStar({
|
||||||
headers,
|
accessToken,
|
||||||
method: 'DELETE',
|
endpoint: `/recipes/${username}/${slug}/star`,
|
||||||
mode: 'cors'
|
refresh
|
||||||
})
|
})
|
||||||
if (response.status === 401) {
|
|
||||||
throw new ExpiredTokenError()
|
|
||||||
} else if (!response.ok) {
|
|
||||||
throw new ApiError(response.status, response.statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default removeStar
|
export default removeStar
|
||||||
|
@ -1,43 +1,31 @@
|
|||||||
import AccessToken from '../types/AccessToken'
|
import AccessToken from '../types/AccessToken'
|
||||||
import { ApiError } from './ApiError'
|
import Refresh from '../types/Refresh'
|
||||||
import ExpiredTokenError from './ExpiredTokenError'
|
import apiCallFactory from './apiCallFactory'
|
||||||
import {
|
import { GetRecipeViewWithRawText, toGetRecipeViewWithRawText } from './types/GetRecipeView'
|
||||||
GetRecipeViewWithRawText,
|
|
||||||
RawGetRecipeViewWithRawText,
|
|
||||||
toGetRecipeViewWithRawText
|
|
||||||
} from './types/GetRecipeView'
|
|
||||||
import UpdateRecipeSpec from './types/UpdateRecipeSpec'
|
import UpdateRecipeSpec from './types/UpdateRecipeSpec'
|
||||||
import { addBearer } from './util'
|
|
||||||
|
|
||||||
export interface UpdateRecipeDeps {
|
export interface UpdateRecipeDeps {
|
||||||
spec: UpdateRecipeSpec
|
spec: UpdateRecipeSpec
|
||||||
accessToken: AccessToken
|
accessToken: AccessToken
|
||||||
|
refresh: Refresh
|
||||||
username: string
|
username: string
|
||||||
slug: string
|
slug: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateRecipe = async ({
|
const doUpdateRecipe = apiCallFactory('POST', toGetRecipeViewWithRawText)
|
||||||
|
|
||||||
|
const updateRecipe = ({
|
||||||
spec,
|
spec,
|
||||||
accessToken,
|
accessToken,
|
||||||
|
refresh,
|
||||||
username,
|
username,
|
||||||
slug
|
slug
|
||||||
}: UpdateRecipeDeps): Promise<GetRecipeViewWithRawText> => {
|
}: UpdateRecipeDeps): Promise<GetRecipeViewWithRawText> =>
|
||||||
const headers = new Headers()
|
doUpdateRecipe({
|
||||||
addBearer(headers, accessToken)
|
accessToken,
|
||||||
headers.set('Content-type', 'application/json')
|
body: spec,
|
||||||
const response = await fetch(import.meta.env.VITE_MME_API_URL + `/recipes/${username}/${slug}`, {
|
endpoint: `/recipes/${username}/${slug}`,
|
||||||
headers,
|
refresh
|
||||||
method: 'POST',
|
|
||||||
mode: 'cors',
|
|
||||||
body: JSON.stringify(spec)
|
|
||||||
})
|
})
|
||||||
if (response.ok) {
|
|
||||||
return toGetRecipeViewWithRawText((await response.json()) as RawGetRecipeViewWithRawText)
|
|
||||||
} else if (response.status === 401) {
|
|
||||||
throw new ExpiredTokenError()
|
|
||||||
} else {
|
|
||||||
throw new ApiError(response.status, response.statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default updateRecipe
|
export default updateRecipe
|
||||||
|
@ -7,6 +7,7 @@ import UpdateRecipeSpec, { fromFullRecipeView } from '../../api/types/UpdateReci
|
|||||||
import updateRecipe from '../../api/updateRecipe'
|
import updateRecipe from '../../api/updateRecipe'
|
||||||
import { useAuth } from '../../AuthProvider'
|
import { useAuth } from '../../AuthProvider'
|
||||||
import classes from './edit-recipe.module.css'
|
import classes from './edit-recipe.module.css'
|
||||||
|
import { useRefresh } from '../../RefreshProvider'
|
||||||
|
|
||||||
interface ControlProps {
|
interface ControlProps {
|
||||||
id: string
|
id: string
|
||||||
@ -88,6 +89,7 @@ export interface EditRecipeProps {
|
|||||||
const EditRecipe = ({ username, slug }: EditRecipeProps) => {
|
const EditRecipe = ({ username, slug }: EditRecipeProps) => {
|
||||||
const { accessToken } = useAuth()
|
const { accessToken } = useAuth()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
const refresh = useRefresh()
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// if (auth.token === null) {
|
// if (auth.token === null) {
|
||||||
@ -106,10 +108,11 @@ const EditRecipe = ({ username, slug }: EditRecipeProps) => {
|
|||||||
queryFn: ({ signal }) =>
|
queryFn: ({ signal }) =>
|
||||||
getRecipe({
|
getRecipe({
|
||||||
accessToken,
|
accessToken,
|
||||||
username,
|
includeRawText: true,
|
||||||
|
refresh,
|
||||||
slug,
|
slug,
|
||||||
abortSignal: signal,
|
signal,
|
||||||
includeRawText: true
|
username
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
queryClient
|
queryClient
|
||||||
@ -144,6 +147,7 @@ const EditRecipe = ({ username, slug }: EditRecipeProps) => {
|
|||||||
return updateRecipe({
|
return updateRecipe({
|
||||||
spec,
|
spec,
|
||||||
accessToken,
|
accessToken,
|
||||||
|
refresh,
|
||||||
username,
|
username,
|
||||||
slug
|
slug
|
||||||
})
|
})
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { QueryObserverSuccessResult, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { QueryObserverSuccessResult, useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
|
import { useNavigate } from '@tanstack/react-router'
|
||||||
import addStar from '../../api/addStar'
|
import addStar from '../../api/addStar'
|
||||||
import { ApiError } from '../../api/ApiError'
|
import { ApiError } from '../../api/ApiError'
|
||||||
import getImage from '../../api/getImage'
|
import getImage from '../../api/getImage'
|
||||||
@ -9,8 +10,8 @@ import GetRecipeView from '../../api/types/GetRecipeView'
|
|||||||
import { useAuth } from '../../AuthProvider'
|
import { useAuth } from '../../AuthProvider'
|
||||||
import RecipeVisibilityIcon from '../../components/recipe-visibility-icon/RecipeVisibilityIcon'
|
import RecipeVisibilityIcon from '../../components/recipe-visibility-icon/RecipeVisibilityIcon'
|
||||||
import UserIconAndName from '../../components/user-icon-and-name/UserIconAndName'
|
import UserIconAndName from '../../components/user-icon-and-name/UserIconAndName'
|
||||||
|
import { useRefresh } from '../../RefreshProvider'
|
||||||
import classes from './recipe.module.css'
|
import classes from './recipe.module.css'
|
||||||
import { useNavigate } from '@tanstack/react-router'
|
|
||||||
|
|
||||||
interface EditButtonProps {
|
interface EditButtonProps {
|
||||||
username: string
|
username: string
|
||||||
@ -53,14 +54,16 @@ interface RecipeStarButtonProps {
|
|||||||
const RecipeStarButton = ({ username, slug, isStarred, starCount }: RecipeStarButtonProps) => {
|
const RecipeStarButton = ({ username, slug, isStarred, starCount }: RecipeStarButtonProps) => {
|
||||||
const { accessToken } = useAuth()
|
const { accessToken } = useAuth()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const refresh = useRefresh()
|
||||||
|
|
||||||
const addStarMutation = useMutation({
|
const addStarMutation = useMutation({
|
||||||
mutationFn: () => {
|
mutationFn: () => {
|
||||||
if (accessToken !== null) {
|
if (accessToken !== null) {
|
||||||
return addStar({
|
return addStar({
|
||||||
accessToken,
|
accessToken,
|
||||||
slug,
|
refresh,
|
||||||
username
|
username,
|
||||||
|
slug
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
@ -76,6 +79,7 @@ const RecipeStarButton = ({ username, slug, isStarred, starCount }: RecipeStarBu
|
|||||||
if (accessToken !== null) {
|
if (accessToken !== null) {
|
||||||
return removeStar({
|
return removeStar({
|
||||||
accessToken,
|
accessToken,
|
||||||
|
refresh,
|
||||||
slug,
|
slug,
|
||||||
username
|
username
|
||||||
})
|
})
|
||||||
@ -113,16 +117,18 @@ export interface RecipeProps {
|
|||||||
const Recipe = ({ username, slug }: RecipeProps) => {
|
const Recipe = ({ username, slug }: RecipeProps) => {
|
||||||
const { accessToken } = useAuth()
|
const { accessToken } = useAuth()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
const refresh = useRefresh()
|
||||||
|
|
||||||
const recipeQuery = useQuery(
|
const recipeQuery = useQuery(
|
||||||
{
|
{
|
||||||
queryKey: ['recipes', username, slug],
|
queryKey: ['recipes', username, slug],
|
||||||
queryFn: ({ signal: abortSignal }) =>
|
queryFn: ({ signal }) =>
|
||||||
getRecipe({
|
getRecipe({
|
||||||
abortSignal,
|
|
||||||
accessToken,
|
accessToken,
|
||||||
username,
|
refresh,
|
||||||
slug
|
signal,
|
||||||
|
slug,
|
||||||
|
username
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
queryClient
|
queryClient
|
||||||
@ -140,6 +146,7 @@ const Recipe = ({ username, slug }: RecipeProps) => {
|
|||||||
getImage({
|
getImage({
|
||||||
accessToken,
|
accessToken,
|
||||||
signal,
|
signal,
|
||||||
|
refresh,
|
||||||
url: recipeQuery.data!.recipe.mainImage!.url
|
url: recipeQuery.data!.recipe.mainImage!.url
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -46,6 +46,7 @@ const Recipes = () => {
|
|||||||
// any needed in the params
|
// any needed in the params
|
||||||
const imgUrl = await getImage({
|
const imgUrl = await getImage({
|
||||||
accessToken,
|
accessToken,
|
||||||
|
refresh,
|
||||||
signal,
|
signal,
|
||||||
url: recipeInfoView.mainImage!.url
|
url: recipeInfoView.mainImage!.url
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user