diff --git a/frontend/src/apis/Patrick/http.ts b/frontend/src/apis/Patrick/http.ts new file mode 100644 index 000000000..49926b831 --- /dev/null +++ b/frontend/src/apis/Patrick/http.ts @@ -0,0 +1,36 @@ +import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; + +const API_PREFIX = 'api'; + +export const BASE_URL = + process.env.APP_URL || `https://mapbefine.com/${API_PREFIX}`; + +const axiosInstance = axios.create({ + baseURL: BASE_URL, + timeout: 5000, +}); + +export interface HttpClient extends AxiosInstance { + get(url: string, config?: AxiosRequestConfig): Promise; + post( + url: string, + data?: any, + config?: AxiosRequestConfig, + ): Promise; + patch( + url: string, + data?: any, + config?: AxiosRequestConfig, + ): Promise; + put( + url: string, + data?: any, + config?: AxiosRequestConfig, + ): Promise; + delete(url: string, config?: AxiosRequestConfig): Promise; +} + +export const http: HttpClient = axiosInstance; + +// axios.interceptors.request.use() +axios.interceptors.response.use((res) => res.data) diff --git a/frontend/src/apis/Patrick/index.ts b/frontend/src/apis/Patrick/index.ts new file mode 100644 index 000000000..5fbe65b53 --- /dev/null +++ b/frontend/src/apis/Patrick/index.ts @@ -0,0 +1,6 @@ +import { http } from './http'; +import { TopicCardProps } from '../../types/Topic'; + +export const getProfile = () => { + return http.get("/members/my/topics"); +}; diff --git a/frontend/src/components/TopicCardList/index.tsx b/frontend/src/components/TopicCardList/index.tsx index 666749985..b8c2643fd 100644 --- a/frontend/src/components/TopicCardList/index.tsx +++ b/frontend/src/components/TopicCardList/index.tsx @@ -1,7 +1,6 @@ -import { Fragment, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { styled } from 'styled-components'; -import useGet from '../../apiHooks/useGet'; import { TopicCardProps } from '../../types/Topic'; import Button from '../common/Button'; import Flex from '../common/Flex'; @@ -9,6 +8,7 @@ import Grid from '../common/Grid'; import Space from '../common/Space'; import Text from '../common/Text'; import TopicCard from '../TopicCard'; +import useProfileList from '../../hooks/queries/useProfileList'; interface TopicCardListProps { url: string; @@ -27,18 +27,7 @@ function TopicCardList({ routePage, children, }: TopicCardListProps) { - const [topics, setTopics] = useState(null); - const { fetchGet } = useGet(); - - const getTopicsFromServer = async () => { - fetchGet(url, errorMessage, (response) => { - setTopics(response); - }); - }; - - useEffect(() => { - getTopicsFromServer(); - }, []); + const { data: topics, refetch: refetchTopic } = useProfileList(); if (!topics) return null; @@ -88,7 +77,7 @@ function TopicCardList({ bookmarkCount={topic.bookmarkCount} isInAtlas={topic.isInAtlas} isBookmarked={topic.isBookmarked} - getTopicsFromServer={getTopicsFromServer} + getTopicsFromServer={refetchTopic} /> ))} diff --git a/frontend/src/hooks/queries/useProfileList.ts b/frontend/src/hooks/queries/useProfileList.ts new file mode 100644 index 000000000..cfa066fb9 --- /dev/null +++ b/frontend/src/hooks/queries/useProfileList.ts @@ -0,0 +1,13 @@ +import { useSuspenseQuery } from '@tanstack/react-query'; +import { getProfile } from '../../apis/Patrick'; + +const useProfileList = () => { + const { data, refetch } = useSuspenseQuery({ + queryKey: ['profileList'], + queryFn: getProfile, + }); + + return { data, refetch }; +}; + +export default useProfileList; diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index d2999a20f..ba31e7ac5 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,6 +1,7 @@ import ReactDOM from 'react-dom/client'; import ReactGA from 'react-ga4'; import { ThemeProvider } from 'styled-components'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import App from './App'; import ErrorBoundary from './components/ErrorBoundary'; @@ -12,6 +13,8 @@ const rootElement = document.getElementById('root'); if (!rootElement) throw new Error('Failed to find the root element'); const root = ReactDOM.createRoot(rootElement); +const queryClient = new QueryClient(); + // if (process.env.NODE_ENV === 'development') { // const { worker } = require('./mocks/browser'); // worker.start({ quiet: true }); @@ -22,10 +25,12 @@ if (process.env.REACT_APP_GOOGLE_ANALYTICS) { } root.render( - - - - - - , + + + + + + + + , ); diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index dd9b8268a..b2f5f13b6 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -6,6 +6,7 @@ import Home from './pages/Home'; import NotFound from './pages/NotFound'; import RootPage from './pages/RootPage'; import Search from './pages/Search'; +import TopicListSkeleton from './components/Skeletons/TopicListSkeleton'; const SelectedTopic = lazy(() => import('./pages/SelectedTopic')); const NewPin = lazy(() => import('./pages/NewPin')); @@ -115,9 +116,9 @@ const routes: routeElement[] = [ { path: 'my-page', element: ( - + }> - + ), withAuth: true, },