diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1fb9ff2a..ccebdc0d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -name: ESLint test +name: ESLint & Build Test on: pull_request: @@ -16,6 +16,11 @@ jobs: - name: Checkout Code uses: actions/checkout@v4 + - name: Install NodeJs + uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Install Pnpm package manager run: | npm install -g pnpm @@ -25,3 +30,6 @@ jobs: - name: Lint Code run: pnpm lint + + - name: Build Test + run: pnpm run build diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 4b9d9652..f9b70120 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,9 +16,6 @@ jobs: steps: - name: Checkout source code. uses: actions/checkout@master - with: - submodules: true - token: ${{ secrets.ACTION_TOKEN }} - name: Cache node modules uses: actions/cache@v4 @@ -47,7 +44,7 @@ jobs: run: pnpm lint - name: Build - run: CI='' pnpm run build + run: pnpm run build - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 5ba7349c..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/shared/utils/env"] - path = src/shared/utils/env - url = https://github.com/Dobbymin/sinitto-submodule.git diff --git a/.prettierignore b/.prettierignore index 6df85bca..1ed1aff2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,5 @@ node_modules .vscode .github dist + +pnpm-lock.yaml \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 5d767d36..85b9dd5b 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -24,18 +24,9 @@ "", - "^@components/(.*)$", + "^@app/(.*)$", "^@pages/(.*)$", - "^@hooks/(.*)$", - "^@assets/(.*)$", - - "^@constants/(.*)$", - "^@utils/(.*)$", - "^@api/(.*)$", - "^@types/(.*)$", - "^@store/(.*)$", - - "^@styles/(.*)$", + "^@shared/(.*)$", "^(.*)/(.*)$" ], diff --git a/package.json b/package.json index 96f60089..b8ac6798 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@tanstack/react-query": "^5.51.11", "axios": "^1.7.5", "date-fns": "^4.1.0", + "dayjs": "^1.11.13", "msw": "^2.3.5", "react": "^18.3.1", "react-datepicker": "^7.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e21fb64..3582a4a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: date-fns: specifier: ^4.1.0 version: 4.1.0 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 msw: specifier: ^2.3.5 version: 2.3.5(typescript@5.5.4) @@ -2584,6 +2587,9 @@ packages: date-fns@4.1.0: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -7991,6 +7997,8 @@ snapshots: date-fns@4.1.0: {} + dayjs@1.11.13: {} + debug@3.2.7: dependencies: ms: 2.1.3 @@ -8267,7 +8275,7 @@ snapshots: debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 @@ -8279,7 +8287,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -8307,7 +8315,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 diff --git a/src/App.tsx b/src/App.tsx index 8830c383..076a432a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,8 +2,9 @@ import { Routes } from '@/app/routes'; import { AllSeniorInfoProvider, queryClient, - AuthProvider, + UserEmailProvider, globalStyle, + SinittoInfoProvider, } from '@/shared'; import { ChakraProvider } from '@chakra-ui/react'; import { Global } from '@emotion/react'; @@ -14,10 +15,12 @@ const App = () => { - - - - + + + + + + diff --git a/src/app/routes/path.ts b/src/app/routes/path.ts index 65754314..260efe46 100644 --- a/src/app/routes/path.ts +++ b/src/app/routes/path.ts @@ -18,4 +18,6 @@ export const RouterPath = { CALL_BACK_GUID_LINE: `:guideLineId`, SENIOR_REGISTER: `/senior-register`, SINITTO_REVIEW: `review`, + + DUMMY_LOGIN: `/dummy`, }; diff --git a/src/app/routes/router.tsx b/src/app/routes/router.tsx index d72aea5f..a11600a4 100644 --- a/src/app/routes/router.tsx +++ b/src/app/routes/router.tsx @@ -14,11 +14,13 @@ import { HelloCallReportPage, SeniorRegisterPage, CallBackListPage, - CallBackDetailPage, // SinittoGuideLinePage, + CallBackDetailPage, + SinittoGuideLinePage, SinittoReviewPage, HelloCallApplyPage, GuardMainPage, SinittoMainPage, + DummyRedirectPage, } from '@/pages'; import { Layout } from '@/shared/components'; @@ -46,6 +48,16 @@ export const router = createBrowserRouter([ }, ], }, + { + path: RouterPath.DUMMY_LOGIN, + element: , + children: [ + { + index: true, + element: , + }, + ], + }, { path: RouterPath.GUARD, children: [ @@ -147,11 +159,26 @@ export const router = createBrowserRouter([ }, { path: RouterPath.CALL_BACK_DETAIL, - element: , children: [ { - index: true, - element: , + path: '', + element: , + children: [ + { + index: true, + element: , + }, + ], + }, + { + path: RouterPath.CALL_BACK_GUID_LINE, + element: , + children: [ + { + index: true, + element: , + }, + ], }, ], }, diff --git a/src/pages/common/main/assets/kakao.svg b/src/pages/assets/main/kakao.svg similarity index 100% rename from src/pages/common/main/assets/kakao.svg rename to src/pages/assets/main/kakao.svg diff --git a/src/pages/common/main/assets/star-icon.svg b/src/pages/assets/main/star-icon.svg similarity index 100% rename from src/pages/common/main/assets/star-icon.svg rename to src/pages/assets/main/star-icon.svg diff --git a/src/pages/common/dummy-redirect/DummyRedirectPage.tsx b/src/pages/common/dummy-redirect/DummyRedirectPage.tsx new file mode 100644 index 00000000..2d7f2717 --- /dev/null +++ b/src/pages/common/dummy-redirect/DummyRedirectPage.tsx @@ -0,0 +1,57 @@ +import { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { RouterPath } from '@/app/routes'; +import { Box, Text, Spinner, Heading } from '@chakra-ui/react'; + +export const DummyRedirectPage = () => { + const [statusMessage, setStatusMessage] = useState( + '유저 정보를 기다리고 있습니다...' + ); + const [isLoading, setIsLoading] = useState(true); + const navigate = useNavigate(); + + useEffect(() => { + const params = new URLSearchParams(window.location.search); + + const accessToken = params.get('accessToken'); + const refreshToken = params.get('refreshToken'); + const isSinitto = params.get('isSinitto'); + + if (accessToken && refreshToken && isSinitto) { + // 로컬 스토리지에 토큰 저장 + localStorage.setItem('accessToken', accessToken); + localStorage.setItem('refreshToken', refreshToken); + localStorage.setItem('isSinitto', isSinitto); + + // isSinitto 상태에 따른 메시지 설정 + setStatusMessage( + isSinitto === 'true' + ? '시니또 더미데이터로 로그인 중입니다. 페이지 이동 중...' + : '보호자 더미데이터로 로그인 중입니다. 페이지 이동 중...' + ); + + setTimeout(() => { + setIsLoading(false); // 로딩 완료 + navigate(isSinitto === 'true' ? RouterPath.SINITTO : RouterPath.GUARD); + }, 2000); + } else { + console.error('Access or Refresh token not found in query parameters.'); + setStatusMessage('[ERROR] 토큰이 존재하지 않습니다.'); + + setIsLoading(false); + } + }, [navigate]); + + return ( + + + 더미데이터 로그인 + + {statusMessage} + {(isLoading || statusMessage === '유저 정보를 기다리고 있습니다...') && ( + + )} + + ); +}; diff --git a/src/pages/common/dummy-redirect/index.ts b/src/pages/common/dummy-redirect/index.ts new file mode 100644 index 00000000..244e91fc --- /dev/null +++ b/src/pages/common/dummy-redirect/index.ts @@ -0,0 +1 @@ +export { DummyRedirectPage } from './DummyRedirectPage'; diff --git a/src/pages/common/index.ts b/src/pages/common/index.ts index b7ea19a4..85a9c9e7 100644 --- a/src/pages/common/index.ts +++ b/src/pages/common/index.ts @@ -1,3 +1,4 @@ +export * from './dummy-redirect'; export * from './main'; export * from './redirect'; export * from './register'; diff --git a/src/pages/common/main/components/login-button/LoginButton.tsx b/src/pages/common/main/components/login-button/LoginButton.tsx index e9047756..cf0cf3c3 100644 --- a/src/pages/common/main/components/login-button/LoginButton.tsx +++ b/src/pages/common/main/components/login-button/LoginButton.tsx @@ -1,13 +1,15 @@ import { Link } from 'react-router-dom'; -import Logo from '../../assets/kakao.svg'; -import { KAKAO_AUTH_URL } from '@/shared/utils/env/config'; +import Logo from '@/pages/assets/main/kakao.svg'; +import { BASE_URI } from '@/shared/api'; import { Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; const LoginButton = () => { + const KAKAO_LOGIN = `${BASE_URI}/api/auth/oauth/kakao`; + return ( - + kakao-icon 카카오톡 로그인 diff --git a/src/pages/common/main/components/review-box/ReviewBox.tsx b/src/pages/common/main/components/review-box/ReviewBox.tsx index 6c11e89e..9140ea84 100644 --- a/src/pages/common/main/components/review-box/ReviewBox.tsx +++ b/src/pages/common/main/components/review-box/ReviewBox.tsx @@ -1,4 +1,4 @@ -import StarIcon from '../../assets/star-icon.svg'; +import StarIcon from '@/pages/assets/main/star-icon.svg'; import { Box, Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; diff --git a/src/pages/common/redirect/RedirectPage.tsx b/src/pages/common/redirect/RedirectPage.tsx index d793cd3d..99ea9f90 100644 --- a/src/pages/common/redirect/RedirectPage.tsx +++ b/src/pages/common/redirect/RedirectPage.tsx @@ -6,6 +6,7 @@ const RedirectPage = () => { const location = useLocation(); const code = new URLSearchParams(location.search).get('code'); + if (!code) { return
로그인을 다시 진행해주세요.
; } diff --git a/src/pages/common/redirect/components/redirect-section/RedirectSection.tsx b/src/pages/common/redirect/components/redirect-section/RedirectSection.tsx index 73ed7dc8..c92496a1 100644 --- a/src/pages/common/redirect/components/redirect-section/RedirectSection.tsx +++ b/src/pages/common/redirect/components/redirect-section/RedirectSection.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { RouterPath } from '@/app/routes/path'; import { useGetKakaoCallback } from '@/pages'; -import { useAuth } from '@/shared'; +import { useUserEmail } from '@/shared'; import { Flex, Spinner, Text } from '@chakra-ui/react'; type Props = { @@ -13,7 +13,7 @@ type Props = { const RedirectSection = ({ code }: Props) => { const navigate = useNavigate(); - const { setEmail } = useAuth(); + const { setEmail } = useUserEmail(); const { data } = useGetKakaoCallback(code); diff --git a/src/pages/common/register/RegisterPage.tsx b/src/pages/common/register/RegisterPage.tsx index 86e72830..2f666aaa 100644 --- a/src/pages/common/register/RegisterPage.tsx +++ b/src/pages/common/register/RegisterPage.tsx @@ -4,9 +4,7 @@ import { useForm } from 'react-hook-form'; import { RegisterFields, RegisterType, Tos } from './components'; import { useRegister } from './store/hooks'; import { FormValues } from './types'; -import { parsePhoneNumber } from '@/shared'; -import { BasicButton } from '@/shared/components'; -import { useAuth } from '@/shared/provider/auth/Auth'; +import { BasicButton, parsePhoneNumber, useUserEmail } from '@/shared'; import { Divider } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -22,7 +20,7 @@ const RegisterPage = () => { // 회원가입 처리 const mutation = useRegister(); - const { email } = useAuth(); + const { email } = useUserEmail(); const handleUserType = (id: string) => { setUserType(id); diff --git a/src/pages/common/register/store/hooks/useRegister.ts b/src/pages/common/register/store/hooks/useRegister.ts index 0a904678..21aff8cf 100644 --- a/src/pages/common/register/store/hooks/useRegister.ts +++ b/src/pages/common/register/store/hooks/useRegister.ts @@ -4,7 +4,7 @@ import { AxiosError } from 'axios'; import { registerUser, SignupApiResponse } from '../api'; import { RouterPath } from '@/app/routes/path'; -import { authLocalStorage } from '@/shared/utils/storage'; +import { authStorage } from '@/shared/utils/storage'; import { useMutation } from '@tanstack/react-query'; const useRegister = () => { @@ -16,10 +16,10 @@ const useRegister = () => { } else { console.log(data); if ('accessToken' in data) { - authLocalStorage.set(data.accessToken); - authLocalStorage.set(data.refreshToken); + authStorage.accessToken.set(data.accessToken); + authStorage.refreshToken.set(data.refreshToken); alert('회원가입이 완료되었습니다.'); - navigate(data.isSinitto === 'true' ? RouterPath.ROOT : RouterPath.ROOT); + navigate(data.isSinitto ? RouterPath.SINITTO : RouterPath.GUARD); } } }; diff --git a/src/pages/guard/guard-main/components/guideline-list/GuideLineList.tsx b/src/pages/guard/guard-main/components/guideline-list/GuideLineList.tsx index 80b063a0..e8b08216 100644 --- a/src/pages/guard/guard-main/components/guideline-list/GuideLineList.tsx +++ b/src/pages/guard/guard-main/components/guideline-list/GuideLineList.tsx @@ -38,4 +38,5 @@ const NoticeTitle = styled(Text)` const NoticeText = styled(Text)` color: var(--color-gray); + font-size: 20px; `; diff --git a/src/pages/guard/guard-main/components/header/Header.tsx b/src/pages/guard/guard-main/components/header/Header.tsx index 18c784e1..9ebbd697 100644 --- a/src/pages/guard/guard-main/components/header/Header.tsx +++ b/src/pages/guard/guard-main/components/header/Header.tsx @@ -1,5 +1,7 @@ import { ChangeEvent, Dispatch, SetStateAction } from 'react'; +import { Link } from 'react-router-dom'; +import { RouterPath } from '@/app/routes'; import IconList from '@/pages/assets/guard-main/list.svg'; import IconUser from '@/pages/assets/shared/user.svg'; import { HEADER_HEIGHT, useAllSeniorInfo } from '@/shared'; @@ -27,8 +29,8 @@ export const Header = ({ currentSenior, setCurrentSenior }: HeaderProps) => { bg='var(--color-secondary)' border={0} color='var(--color-black)' - borderRadius={5} - fontSize='lg' + borderRadius={20} + fontSize='sm' fontWeight='700' size='sm' value={currentSenior?.toString() || ''} @@ -40,7 +42,9 @@ export const Header = ({ currentSenior, setCurrentSenior }: HeaderProps) => { ))} - icon-user + + icon-user + ); diff --git a/src/pages/guard/guard-main/components/hello-call-apply/HelloCallApply.tsx b/src/pages/guard/guard-main/components/hello-call-apply/HelloCallApply.tsx index 6fa7a793..506997ee 100644 --- a/src/pages/guard/guard-main/components/hello-call-apply/HelloCallApply.tsx +++ b/src/pages/guard/guard-main/components/hello-call-apply/HelloCallApply.tsx @@ -1,3 +1,6 @@ +import { Link } from 'react-router-dom'; + +import { RouterPath } from '@/app/routes'; import { IconArrow } from '@/pages/assets'; import HelloCallImg from '@/pages/assets/shared/hello-call.png'; import { Button, Flex, Image, Text } from '@chakra-ui/react'; @@ -10,13 +13,15 @@ export const HelloCallApply = () => { 안부 전화 서비스를 이용해보세요. 다정한 시니또들이 대신 말 벗이 되어드립니다. - - - 안부 전화 서비스 - 신청하기 - - - + + + + 안부 전화 서비스 + 신청하기 + + + + @@ -38,6 +43,7 @@ const NoticeTitle = styled(Text)` const NoticeText = styled(Text)` color: var(--color-gray); + font-size: 20px; `; const ContentWrapper = styled(Flex)` diff --git a/src/pages/guard/guide-line/GuideLinePage.tsx b/src/pages/guard/guide-line/GuideLinePage.tsx index 6d84b10e..9bc64097 100644 --- a/src/pages/guard/guide-line/GuideLinePage.tsx +++ b/src/pages/guard/guide-line/GuideLinePage.tsx @@ -2,7 +2,7 @@ import { useParams } from 'react-router-dom'; import { useGetSeniorAllGuidelines } from './api'; import { GuideLineInfo, GuidelineRegisterBox } from './components'; -import { Box, Flex } from '@chakra-ui/react'; +import { Box, Flex, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; export type GuideLineDetailParams = { @@ -29,14 +29,27 @@ export const GuideLinePage = () => { return ( - + + + + + 등록한 가이드라인 + + + 총 {guidelineData?.length}개 + + {guidelineData?.map((guideline) => ( { /> ))} - ); }; const Container = styled(Box)` position: relative; - height: 100vh; + display: flex; + flex-direction: column; + align-items: center; `; diff --git a/src/pages/guard/guide-line/api/hooks/index.ts b/src/pages/guard/guide-line/api/hooks/index.ts index 9349033c..cd2ecd3d 100644 --- a/src/pages/guard/guide-line/api/hooks/index.ts +++ b/src/pages/guard/guide-line/api/hooks/index.ts @@ -3,3 +3,4 @@ export { useGetSeniorAllGuidelines } from './useGetSeniorAllGuideines'; export { useModifyGuideline } from './useModifyGuideline'; export { useAddGuideline } from './useAddGuideline'; export { useDeleteGuideline } from './useDeleteGuideline'; +export { useGuidelineInfo } from './useGuidelineInfo'; diff --git a/src/pages/guard/guide-line/api/hooks/useGuidelineInfo.ts b/src/pages/guard/guide-line/api/hooks/useGuidelineInfo.ts new file mode 100644 index 00000000..0a6df5a7 --- /dev/null +++ b/src/pages/guard/guide-line/api/hooks/useGuidelineInfo.ts @@ -0,0 +1,78 @@ +import { useState } from 'react'; + +import { ModifyGuidelineRequest } from '../modify-guideline.api'; +import { UseMutationResult } from '@tanstack/react-query'; + +type GuidelineInfo = { + id: number; + type: string; + title: string; + content: string; +}; + +type UseGuidelineInfoProps = { + guideline: GuidelineInfo; + seniorId: number; + editMutation: UseMutationResult; + deleteMutation: UseMutationResult; +}; + +type UseGuidelineInfoReturn = { + isMore: boolean; + isEditing: boolean; + guidelineTitle: string; + guidelineContent: string; + toggleContent: () => void; + setIsEditing: (value: boolean) => void; + setGuidelineTitle: (value: string) => void; + setGuidelineContent: (value: string) => void; + editGuideline: () => void; + deleteGuideline: () => void; +}; + +export const useGuidelineInfo = ({ + guideline, + seniorId, + editMutation, + deleteMutation, +}: UseGuidelineInfoProps): UseGuidelineInfoReturn => { + const [isMore, setIsMore] = useState(false); + const [isEditing, setIsEditing] = useState(false); + const [guidelineTitle, setGuidelineTitle] = useState(guideline.title); + const [guidelineContent, setGuidelineContent] = useState(guideline.content); + + const toggleContent = () => { + setIsMore(!isMore); + }; + + const editGuideline = () => { + editMutation.mutate({ + seniorId: seniorId, + type: guideline.type, + title: guidelineTitle, + content: guidelineContent, + }); + setIsEditing(false); + }; + + const deleteGuideline = () => { + const isConfirmed = window.confirm('정말 가이드라인을 삭제하시겠습니까?'); + + if (isConfirmed) { + deleteMutation.mutate(guideline.id); + } + }; + + return { + isMore, + isEditing, + guidelineTitle, + guidelineContent, + toggleContent, + setIsEditing, + setGuidelineTitle, + setGuidelineContent, + editGuideline, + deleteGuideline, + }; +}; diff --git a/src/pages/guard/guide-line/components/guide-info-box/GuideLineInfo.tsx b/src/pages/guard/guide-line/components/guide-info-box/GuideLineInfo.tsx index e7e300f6..970bbea5 100644 --- a/src/pages/guard/guide-line/components/guide-info-box/GuideLineInfo.tsx +++ b/src/pages/guard/guide-line/components/guide-info-box/GuideLineInfo.tsx @@ -1,6 +1,8 @@ -import { useState } from 'react'; - -import { useDeleteGuideline, useModifyGuideline } from '@/pages/guard'; +import { + useDeleteGuideline, + useGuidelineInfo, + useModifyGuideline, +} from '@/pages/guard'; import { arrowIcon, deleteIcon, editIcon } from '@/shared/assets'; import { Box, Flex, Text, Image, Input } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -19,36 +21,31 @@ type Props = { }; const GuideLineInfo = ({ guideline, refetch, seniorId }: Props) => { - const [isMore, setIsMore] = useState(false); - const [isEditing, setIsEditing] = useState(false); - const [guidelineTitle, setGuidelineTitle] = useState(guideline.title); - const [guidelineContent, setGuidelineContent] = useState(guideline.content); - const editMutation = useModifyGuideline(refetch, guideline.id); const deleteMutation = useDeleteGuideline(refetch, guideline.id); - const toggleContent = () => { - setIsMore(!isMore); - }; - - const handleEdit = () => { - editMutation.mutate({ - seniorId: seniorId, - type: guideline.type, - title: guidelineTitle, - content: guidelineContent, - }); - setIsEditing(false); - }; - - const handleDelete = () => { - deleteMutation.mutate(guideline.id); - }; + const { + isMore, + isEditing, + guidelineTitle, + guidelineContent, + toggleContent, + setIsEditing, + setGuidelineTitle, + setGuidelineContent, + editGuideline, + deleteGuideline, + } = useGuidelineInfo({ + guideline, + seniorId, + editMutation, + deleteMutation, + }); return ( {isEditing ? ( - + { - 저장 + + 저장 + + setIsEditing(false)} + fontSize='0.9rem' + fontWeight={700} + cursor='pointer' + color='var(--color-primary)' + > + 취소 + ) : ( @@ -97,7 +117,7 @@ const GuideLineInfo = ({ guideline, refetch, seniorId }: Props) => { display='flex' flexDir='row' w='100%' - maxW='300px' + maxW='370px' justifyContent='space-between' alignItems='center' cursor='pointer' @@ -106,13 +126,13 @@ const GuideLineInfo = ({ guideline, refetch, seniorId }: Props) => { {guideline.title} - setIsEditing(true)} w={4} h={4} /> + @@ -136,7 +156,7 @@ const GuideLineInfoContainer = styled(Flex)` flex-direction: column; justify-content: center; width: 100%; - max-width: 330px; + max-width: 370px; height: auto; background-color: var(--color-secondary); border: 1px solid var(--color-secondary); @@ -153,7 +173,7 @@ const InfoText = styled(Text)` const InfoBox = styled(Box)` width: 100%; - max-width: 300px; + max-width: 330px; display: flex; flex-direction: row; justify-content: space-between; diff --git a/src/pages/guard/guide-line/components/guide-register-box/GuidelineRegisterBox.tsx b/src/pages/guard/guide-line/components/guide-register-box/GuidelineRegisterBox.tsx index 1770ec94..3f944da4 100644 --- a/src/pages/guard/guide-line/components/guide-register-box/GuidelineRegisterBox.tsx +++ b/src/pages/guard/guide-line/components/guide-register-box/GuidelineRegisterBox.tsx @@ -61,13 +61,8 @@ const GuidelineRegisterBox = ({ refetch, seniorId, guidelineType }: Props) => { export default GuidelineRegisterBox; const RegisterBox = styled(Box)` - position: absolute; - bottom: 0; width: 100%; height: auto; - min-height: 350px; - left: 50%; - transform: translateX(-50%); max-width: 370px; display: flex; flex-direction: column; @@ -75,29 +70,26 @@ const RegisterBox = styled(Box)` background-color: var(--color-white-gray); border: 1px solid var(--color-white-gray); border-radius: 15px; + margin-top: 0.25rem; `; const InputBox = styled(Box)` width: 300px; - height: 80px; - display: flex; - flex-direction: column; - margin: 0.5rem; - margin-bottom: 1rem; + margin: 0.2rem; `; const StyledButton = styled.button` - position: absolute; - bottom: 0.5rem; width: 300px; height: 40px; background-color: #c69090; + font-weight: bold; color: #ffffff; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; + margin-bottom: 10px; &:hover { background-color: #a67070; diff --git a/src/pages/guard/mypage/GuardMyPage.tsx b/src/pages/guard/mypage/GuardMyPage.tsx index 3ed66222..70e58200 100644 --- a/src/pages/guard/mypage/GuardMyPage.tsx +++ b/src/pages/guard/mypage/GuardMyPage.tsx @@ -1,6 +1,6 @@ import { GuardProfileBox } from './components'; import { PointBox, PointLogBox } from '@/shared/components'; -import { Box } from '@chakra-ui/react'; +import { Flex } from '@chakra-ui/react'; import styled from '@emotion/styled'; export const GuardMyPage = () => { @@ -13,8 +13,8 @@ export const GuardMyPage = () => { ); }; -const MyPageLayout = styled(Box)` - display: flex; +const MyPageLayout = styled(Flex)` flex-direction: column; align-items: center; + gap: 0.2rem; `; diff --git a/src/pages/guard/mypage/components/profile-box/GuardProfileBox.tsx b/src/pages/guard/mypage/components/profile-box/GuardProfileBox.tsx index ccfc140b..6ec0072e 100644 --- a/src/pages/guard/mypage/components/profile-box/GuardProfileBox.tsx +++ b/src/pages/guard/mypage/components/profile-box/GuardProfileBox.tsx @@ -2,14 +2,12 @@ import { Link } from 'react-router-dom'; import { useGetGuardInformation } from '../../api'; import { RouterPath } from '@/app/routes/path'; -import { Box } from '@chakra-ui/react'; +import { Logout } from '@/shared'; +import { Box, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; const GuardProfileBox = () => { - const { data, isLoading, isError } = useGetGuardInformation(); - - if (isLoading) return
로딩 중...
; - if (isError) return
데이터를 가져오는 데 오류가 발생했습니다.
; + const { data } = useGetGuardInformation(); return ( @@ -17,12 +15,14 @@ const GuardProfileBox = () => { - {data?.name} 님 환영합니다. + + {data?.name} 님 환영합니다. + + 서비스 이용 방법 한번에 이해하기! @@ -78,6 +78,7 @@ const TopContainer = styled(Box)` align-items: center; height: 70%; max-height: 120px; + padding: 1rem; `; const BottomContainer = styled(Box)` diff --git a/src/pages/guard/register/SeniorRegisterPage.tsx b/src/pages/guard/register/SeniorRegisterPage.tsx index 60847a8f..dcbc6643 100644 --- a/src/pages/guard/register/SeniorRegisterPage.tsx +++ b/src/pages/guard/register/SeniorRegisterPage.tsx @@ -1,7 +1,7 @@ import { useGetAllSeniorInfo } from '../mypage'; import { SeniorInfo } from './components'; import SeniorRegisterBox from './components/senior-register-box/SeniorRegisterBox'; -import { Box, Flex } from '@chakra-ui/react'; +import { Box, Flex, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; export const SeniorRegisterPage = () => { @@ -17,29 +17,45 @@ export const SeniorRegisterPage = () => { return ( - + + + + + 등록한 시니어 + + + 총 {seniors?.length}명 + + + {seniors?.map((senior) => ( ))} - ); }; const Container = styled(Box)` position: relative; - height: 100vh; display: flex; flex-direction: column; + align-items: center; `; const SeniorInfoContainer = styled(Flex)` - flex-grow: 1; - overflow-y: auto; - height: 70vh; + width: 100%; + max-width: 370px; flex-direction: column; align-items: center; + border-radius: 10px; `; export default SeniorRegisterPage; diff --git a/src/pages/guard/register/api/hooks/index.ts b/src/pages/guard/register/api/hooks/index.ts index a772528f..5407c6ed 100644 --- a/src/pages/guard/register/api/hooks/index.ts +++ b/src/pages/guard/register/api/hooks/index.ts @@ -1,3 +1,4 @@ export { useAddSeniorInfo } from './useAddSeniorInfo'; export { useDeleteSeniorInfo } from './useDeleteSeniorInfo'; export { useEditSeniorInfo } from './useEditSeniorInfo'; +export { useSeniorInfo } from './useSeniorInfo'; diff --git a/src/pages/guard/register/api/hooks/useSeniorInfo.ts b/src/pages/guard/register/api/hooks/useSeniorInfo.ts new file mode 100644 index 00000000..c51245cf --- /dev/null +++ b/src/pages/guard/register/api/hooks/useSeniorInfo.ts @@ -0,0 +1,69 @@ +import { useState } from 'react'; + +import { SeniorRegisterValues as SeniorRegisterRequest } from '../types/senior-register.type'; +import { UseMutationResult } from '@tanstack/react-query'; + +type SeniorInfoType = { + seniorName: string; + seniorPhoneNumber: string; + seniorId: number; +}; + +type UseSeniorInfoProps = { + senior: SeniorInfoType; + deleteMutation: UseMutationResult; + editMutation: UseMutationResult< + string, + Error, + { seniorId: number; seniorInfo: SeniorRegisterRequest } + >; +}; + +type UseSeniorInfoReturn = { + isEditing: boolean; + seniorName: string; + seniorPhoneNumber: string; + setIsEditing: (value: boolean) => void; + setSeniorName: (value: string) => void; + setSeniorPhoneNumber: (value: string) => void; + deleteSenior: () => void; + editSenior: () => void; +}; + +export const useSeniorInfo = ({ + senior, + deleteMutation, + editMutation, +}: UseSeniorInfoProps): UseSeniorInfoReturn => { + const [isEditing, setIsEditing] = useState(false); + const [seniorName, setSeniorName] = useState(senior.seniorName); + const [seniorPhoneNumber, setSeniorPhoneNumber] = useState( + senior.seniorPhoneNumber + ); + + const deleteSenior = () => { + const isConfirmed = window.confirm('해당 시니어를 삭제하시겠습니까?'); + if (isConfirmed) { + deleteMutation.mutate(senior.seniorId); + } + }; + + const editSenior = () => { + editMutation.mutate({ + seniorId: senior.seniorId, + seniorInfo: { seniorName, seniorPhoneNumber }, + }); + setIsEditing(false); + }; + + return { + isEditing, + seniorName, + seniorPhoneNumber, + setIsEditing, + setSeniorName, + setSeniorPhoneNumber, + deleteSenior, + editSenior, + }; +}; diff --git a/src/pages/guard/register/components/senior-info/senior-info-box/SeniorInfo.tsx b/src/pages/guard/register/components/senior-info/senior-info-box/SeniorInfo.tsx index 8d6ce92a..39840046 100644 --- a/src/pages/guard/register/components/senior-info/senior-info-box/SeniorInfo.tsx +++ b/src/pages/guard/register/components/senior-info/senior-info-box/SeniorInfo.tsx @@ -1,6 +1,8 @@ -import { useState } from 'react'; - -import { useDeleteSeniorInfo, useEditSeniorInfo } from '../../../api'; +import { + useDeleteSeniorInfo, + useEditSeniorInfo, + useSeniorInfo, +} from '@/pages/guard'; import { formatPhoneNumber } from '@/shared'; import { deleteIcon, editIcon } from '@/shared/assets'; import { Box, Flex, Text, Image, Input } from '@chakra-ui/react'; @@ -19,26 +21,23 @@ const SeniorInfo = ({ senior: SeniorInfoType; refetch: () => void; }) => { - const [isEditing, setIsEditing] = useState(false); - const [seniorName, setSeniorName] = useState(senior.seniorName); - const [seniorPhoneNumber, setSeniorPhoneNumber] = useState( - senior.seniorPhoneNumber - ); - const deleteMutation = useDeleteSeniorInfo(refetch); const editMutation = useEditSeniorInfo(refetch); - const handleDelete = () => { - deleteMutation.mutate(senior.seniorId); - }; - - const handleEdit = () => { - editMutation.mutate({ - seniorId: senior.seniorId, - seniorInfo: { seniorName, seniorPhoneNumber }, - }); - setIsEditing(false); - }; + const { + isEditing, + seniorName, + seniorPhoneNumber, + setIsEditing, + setSeniorName, + setSeniorPhoneNumber, + deleteSenior, + editSenior, + } = useSeniorInfo({ + senior, + deleteMutation, + editMutation, + }); return ( - 저장 + + 저장 + + setIsEditing(false)} + fontSize='0.9rem' + fontWeight={700} + cursor='pointer' + color='var(--color-primary)' + > + 취소 +
) : ( @@ -110,7 +132,7 @@ const SeniorInfo = ({ h={4} ml={1} cursor='pointer' - onClick={handleDelete} + onClick={deleteSenior} /> @@ -126,7 +148,7 @@ const SeniorInfo = ({ const SeniorInfoContainer = styled(Flex)` width: 100%; - max-width: 330px; + max-width: 370px; height: 5rem; min-height: 5rem; background-color: var(--color-secondary); @@ -143,7 +165,7 @@ const InfoText = styled(Text)` const InfoBox = styled(Box)` width: 100%; - max-width: 300px; + max-width: 350px; display: flex; flex-direction: row; justify-content: space-between; diff --git a/src/pages/guard/register/components/senior-register-box/SeniorRegisterBox.tsx b/src/pages/guard/register/components/senior-register-box/SeniorRegisterBox.tsx index 18144347..528258f0 100644 --- a/src/pages/guard/register/components/senior-register-box/SeniorRegisterBox.tsx +++ b/src/pages/guard/register/components/senior-register-box/SeniorRegisterBox.tsx @@ -48,7 +48,7 @@ const SeniorRegisterBox = ({ refetch }: { refetch: () => void }) => { })} /> - 시니어 등록 + 시니어 등록하기 ); }; @@ -56,11 +56,8 @@ const SeniorRegisterBox = ({ refetch }: { refetch: () => void }) => { export default SeniorRegisterBox; const RegisterBox = styled(Box)` - position: relative; width: 100%; height: auto; - left: 50%; - transform: translateX(-50%); max-width: 370px; display: flex; flex-direction: column; @@ -68,17 +65,19 @@ const RegisterBox = styled(Box)` background-color: var(--color-white-gray); border: 1px solid var(--color-white-gray); border-radius: 15px; + margin-top: 0.25rem; `; const InputBox = styled(Box)` width: 300px; - margin: 0.5rem; + margin: 0.2rem; `; const StyledButton = styled.button` width: 300px; height: 40px; background-color: #c69090; + font-weight: bold; color: #ffffff; border: none; border-radius: 5px; diff --git a/src/pages/sinitto/call-back/detail/CallBackDetailPage.tsx b/src/pages/sinitto/call-back/detail/CallBackDetailPage.tsx index 2f8c70a1..847bc5df 100644 --- a/src/pages/sinitto/call-back/detail/CallBackDetailPage.tsx +++ b/src/pages/sinitto/call-back/detail/CallBackDetailPage.tsx @@ -1,7 +1,6 @@ import { useEffect } from 'react'; import { useParams, Outlet, useNavigate } from 'react-router-dom'; -import { useGetAccepted } from './api/hooks'; import { CallbackMenu } from './components'; import { GuideLineList } from './components/guide-line-list'; import { RouterPath } from '@/app/routes/path'; @@ -34,16 +33,6 @@ export const CallBackDetailPage = () => { } }, [isCallBackError, callBackError, navigate]); - const { - data: currentReq, - isLoading: iscurrentReqLoading, - isError: iscurrentReqError, - } = useGetAccepted(); - const accept = - iscurrentReqError || !currentReq - ? false - : currentReq.callbackId == Number(callBackId); - return ( <> @@ -59,11 +48,11 @@ export const CallBackDetailPage = () => { /> - {iscurrentReqLoading ? ( - - ) : ( - - )} + ) )} diff --git a/src/pages/sinitto/call-back/detail/components/menu/CallbackMenu.tsx b/src/pages/sinitto/call-back/detail/components/menu/CallbackMenu.tsx index 7d91f0a6..5bfd8e9f 100644 --- a/src/pages/sinitto/call-back/detail/components/menu/CallbackMenu.tsx +++ b/src/pages/sinitto/call-back/detail/components/menu/CallbackMenu.tsx @@ -7,15 +7,21 @@ import { } from '../../api/hooks'; import { PostAcceptMenu } from '../../components/menu/post-accept'; import { PreAcceptMenu } from '../../components/menu/pre-accept'; -import { RouterPath } from '@/app/routes'; +import { RouterPath } from '@/app/routes/path'; +import { formatPhoneNumber } from '@/shared'; import { Spinner } from '@chakra-ui/react'; type MenuProps = { callBackId: number; accept: boolean; + phoneNumber: string; }; -export const CallbackMenu = ({ callBackId, accept }: MenuProps) => { +export const CallbackMenu = ({ + callBackId, + accept, + phoneNumber, +}: MenuProps) => { const navigate = useNavigate(); const { @@ -33,7 +39,7 @@ export const CallbackMenu = ({ callBackId, accept }: MenuProps) => { isSuccess: isCompleteSuccess, } = useCompleteCallback(); if (isCompleteSuccess) { - navigate(RouterPath.CALL_BACK_LIST); // TODO: 완료 이후 이동 페이지 지정 필요 + navigate(RouterPath.SINITTO); } const { @@ -42,7 +48,7 @@ export const CallbackMenu = ({ callBackId, accept }: MenuProps) => { isSuccess: isCancelSuccess, } = useCancelCallback(); if (isCancelSuccess) { - navigate(RouterPath.CALL_BACK_LIST); // TODO: 취소 이후 이동 페이지 지정 필요 + navigate(RouterPath.CALL_BACK_LIST); } const isLoading = isAcceptLoading || isCancelLoading || isCompleteLoading; @@ -53,7 +59,7 @@ export const CallbackMenu = ({ callBackId, accept }: MenuProps) => { completeCallback(callBackId)} handleCancle={() => cancelCallback(callBackId)} - phoneNumber='010-1234-5678' // TODO: api로 콜백 조회 시 response에 전화번호 추가 필요 + phoneNumber={formatPhoneNumber(phoneNumber)} /> ) : ( acceptCallback(callBackId)} /> diff --git a/src/pages/sinitto/call-back/list/api/callback-list.api.ts b/src/pages/sinitto/call-back/list/api/callback-list.api.ts index c904b9ac..a4f20b49 100644 --- a/src/pages/sinitto/call-back/list/api/callback-list.api.ts +++ b/src/pages/sinitto/call-back/list/api/callback-list.api.ts @@ -1,4 +1,4 @@ -import { CallbacksResponse } from './types'; +import { CallbackListResponse } from './types'; import { fetchInstance } from '@/shared/api/instance'; const getCallbackListPath = '/api/callbacks'; @@ -12,7 +12,7 @@ export const CallbackListQueryKey = (page: number, size: number) => [ export const getCallbackList = async ( page: number, size: number -): Promise => { +): Promise => { const response = await fetchInstance.get(getCallbackListPath, { params: { pageable: { diff --git a/src/pages/sinitto/call-back/list/api/get-call-backs.api.ts b/src/pages/sinitto/call-back/list/api/get-call-backs.api.ts index 3bd83f9b..5100daf2 100644 --- a/src/pages/sinitto/call-back/list/api/get-call-backs.api.ts +++ b/src/pages/sinitto/call-back/list/api/get-call-backs.api.ts @@ -1,15 +1,20 @@ -import type { CallbacksResponse } from './types'; +import type { CallbackListResponse } from './types'; import { fetchInstance } from '@/shared/api/instance'; const getCallbacksPath = () => `/api/callbacks`; -export const getCallbacks = async (page: number, size: number) => { - const response = await fetchInstance.get( +export const getCallbacks = async ( + page: number, + size: number, + sort: string = 'DESC' +) => { + const response = await fetchInstance.get( getCallbacksPath(), { params: { page, size, + sort, }, } ); diff --git a/src/pages/sinitto/call-back/list/api/index.ts b/src/pages/sinitto/call-back/list/api/index.ts index a2626325..738b0d55 100644 --- a/src/pages/sinitto/call-back/list/api/index.ts +++ b/src/pages/sinitto/call-back/list/api/index.ts @@ -1 +1,3 @@ export { getCallbacks } from './get-call-backs.api'; + +export * from './hooks'; diff --git a/src/pages/sinitto/call-back/list/api/types/callbacks.response.ts b/src/pages/sinitto/call-back/list/api/types/callbacks.response.ts index 020b7af0..47b1eb43 100644 --- a/src/pages/sinitto/call-back/list/api/types/callbacks.response.ts +++ b/src/pages/sinitto/call-back/list/api/types/callbacks.response.ts @@ -1,6 +1,6 @@ import { CallbackResponse } from '@/shared/types'; -export type CallbacksResponse = { +export type CallbackListResponse = { totalElements: number; totalPages: number; first: boolean; diff --git a/src/pages/sinitto/call-back/list/api/types/index.ts b/src/pages/sinitto/call-back/list/api/types/index.ts index 77c2c660..5ec35e62 100644 --- a/src/pages/sinitto/call-back/list/api/types/index.ts +++ b/src/pages/sinitto/call-back/list/api/types/index.ts @@ -1 +1 @@ -export type { CallbacksResponse } from './callbacks.response'; +export type { CallbackListResponse } from './callbacks.response'; diff --git a/src/pages/sinitto/call-back/list/index.ts b/src/pages/sinitto/call-back/list/index.ts index cfab8beb..b3b9f57c 100644 --- a/src/pages/sinitto/call-back/list/index.ts +++ b/src/pages/sinitto/call-back/list/index.ts @@ -2,3 +2,4 @@ export { default as CallBackListPage } from './CallBackListPage'; export * from './components'; export * from './data'; +export * from './api'; diff --git a/src/pages/sinitto/guide-line/SinittoGuideLinePage.tsx b/src/pages/sinitto/guide-line/SinittoGuideLinePage.tsx index 5dfa173b..5dd57a92 100644 --- a/src/pages/sinitto/guide-line/SinittoGuideLinePage.tsx +++ b/src/pages/sinitto/guide-line/SinittoGuideLinePage.tsx @@ -1,14 +1,13 @@ -import { useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { useGetGuideline } from './api/hooks'; import { GuidelineResponse } from './api/types'; +import { GuideLineContainer } from './components'; import { CATEGORIES } from './data'; import { Category } from './types'; import { RouterPath } from '@/app/routes/path'; -import { useGetCallback } from '@/shared/api/hooks'; import { handleCallbackError } from '@/shared/utils'; -import { Container, Spinner } from '@chakra-ui/react'; +import { Spinner } from '@chakra-ui/react'; import styled from '@emotion/styled'; type GuideLineParams = { @@ -22,32 +21,21 @@ export const SinittoGuideLinePage = () => { const guideLineInfo = CATEGORIES.find((item: Category) => item.id === guideLineId)?.name || null; - const { - data: callBack, - isLoading: isCallBackLoading, - isError: isCallBackError, - error: callBackError, - } = useGetCallback(callBackId); - const seniorId = - !isCallBackLoading && callBack ? callBack.seniorId : undefined; - const { data: guideLine, isLoading: isGuideLineLoading, isError: isGuideLineError, - } = useGetGuideline(Number(seniorId), guideLineId); + } = useGetGuideline(Number(callBackId), guideLineId); - useEffect(() => { - if (isCallBackError) { - const errorMessage = handleCallbackError(callBackError); - alert(errorMessage); - navigate(RouterPath.CALL_BACK_LIST); - } - }, [isCallBackError, callBackError, navigate]); + if (isGuideLineError) { + const errorMessage = handleCallbackError(isGuideLineError); + alert(errorMessage); + navigate(RouterPath.CALL_BACK_LIST); + } return ( - {isCallBackLoading || isGuideLineLoading ? ( + {isGuideLineLoading ? ( ) : ( <> @@ -61,9 +49,9 @@ export const SinittoGuideLinePage = () => { (guideLine.length == 0 ? (

등록된 가이드라인이 없습니다.

) : ( - guideLine.map((data: GuidelineResponse, index: number) => ( - ( + diff --git a/src/pages/sinitto/guide-line/api/get-guideline.api.ts b/src/pages/sinitto/guide-line/api/get-guideline.api.ts index 4bc12141..f3d4cbea 100644 --- a/src/pages/sinitto/guide-line/api/get-guideline.api.ts +++ b/src/pages/sinitto/guide-line/api/get-guideline.api.ts @@ -1,12 +1,13 @@ import type { GuidelineResponse } from './types'; import { fetchInstance } from '@/shared/api/instance'; -const getGuidelinesPath = (seniorId: number, type: string) => - `/api/guardguidelines/${seniorId}/${type}`; +const getGuidelinesPath = (callbackId: number, type: string) => + `/api/guardguidelines/sinitto/${callbackId}/${type}`; -export const getGuidelines = async (seniorId: number, type: string) => { +export const getGuidelines = async (callbackId: number, type: string) => { const response = await fetchInstance.get( - getGuidelinesPath(seniorId, type) + getGuidelinesPath(callbackId, type) ); + return response.data; }; diff --git a/src/pages/sinitto/guide-line/api/hooks/useGetGuideline.ts b/src/pages/sinitto/guide-line/api/hooks/useGetGuideline.ts index 57ffd458..a4a80d38 100644 --- a/src/pages/sinitto/guide-line/api/hooks/useGetGuideline.ts +++ b/src/pages/sinitto/guide-line/api/hooks/useGetGuideline.ts @@ -1,10 +1,10 @@ import { getGuidelines } from '../get-guideline.api'; import { useQuery } from '@tanstack/react-query'; -export const useGetGuideline = (seniorId: number, type: string) => { +export const useGetGuideline = (callbackId: number, type: string) => { return useQuery({ - queryKey: ['Guideline', seniorId, type], - queryFn: () => getGuidelines(seniorId, type), - enabled: !!seniorId && !!type, + queryKey: ['Guideline', callbackId, type], + queryFn: () => getGuidelines(callbackId, type), + enabled: !!callbackId && !!type, }); }; diff --git a/src/pages/sinitto/guide-line/api/types/guideline.response.ts b/src/pages/sinitto/guide-line/api/types/guideline.response.ts index d1c38418..99bd34f3 100644 --- a/src/pages/sinitto/guide-line/api/types/guideline.response.ts +++ b/src/pages/sinitto/guide-line/api/types/guideline.response.ts @@ -2,4 +2,5 @@ export type GuidelineResponse = { type: string; title: string; content: string; + id: number; }; diff --git a/src/pages/sinitto/guide-line/components/container/Container.tsx b/src/pages/sinitto/guide-line/components/container/Container.tsx index dbabdcec..c68a2d2d 100644 --- a/src/pages/sinitto/guide-line/components/container/Container.tsx +++ b/src/pages/sinitto/guide-line/components/container/Container.tsx @@ -5,7 +5,7 @@ type Props = { content: string; }; -export const Container = ({ title, content }: Props) => { +export const GuideLineContainer = ({ title, content }: Props) => { return ( {title} diff --git a/src/pages/sinitto/guide-line/components/container/index.ts b/src/pages/sinitto/guide-line/components/container/index.ts index b3999f02..bda3ec81 100644 --- a/src/pages/sinitto/guide-line/components/container/index.ts +++ b/src/pages/sinitto/guide-line/components/container/index.ts @@ -1 +1 @@ -export { Container } from './Container'; +export { GuideLineContainer } from './Container'; diff --git a/src/pages/sinitto/hello-call-list/HelloCallListPage.tsx b/src/pages/sinitto/hello-call-list/HelloCallListPage.tsx index 0dadf5cd..12dbfa3e 100644 --- a/src/pages/sinitto/hello-call-list/HelloCallListPage.tsx +++ b/src/pages/sinitto/hello-call-list/HelloCallListPage.tsx @@ -1,18 +1,19 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useRef, useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { useGetServiceList } from './api'; import { CallRequest } from './components'; import { RouterPath } from '@/app/routes/path'; -import { LoadingView, VisibilityLoader } from '@/shared/components'; +import { LoadingView } from '@/shared/components'; import { Flex, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; const HelloCallListPage = () => { const [isLastPageReached, setIsLastPageReached] = useState(false); + const observerRef = useRef(null); const { data, isError, isLoading, hasNextPage, fetchNextPage, error } = - useGetServiceList(); + useGetServiceList(10); const navigate = useNavigate(); @@ -22,6 +23,23 @@ const HelloCallListPage = () => { navigate(`${RouterPath.HELLO_CALL_SERVICE}/${helloCallId}`); }; + const lastElementRef = useCallback( + (node: HTMLDivElement | null) => { + if (isLoading) return; + + if (observerRef.current) observerRef.current.disconnect(); + + observerRef.current = new IntersectionObserver((entries) => { + if (entries[0].isIntersecting && hasNextPage) { + fetchNextPage(); + } + }); + + if (node) observerRef.current.observe(node); + }, + [isLoading, fetchNextPage, hasNextPage] + ); + useEffect(() => { if (isError && error instanceof Error && error.message.includes('500')) { setIsLastPageReached(true); @@ -37,17 +55,18 @@ const HelloCallListPage = () => { 새로고침 - {allContent.map((item) => ( - handlerNavigate(item.helloCallId)} - /> - ))} - {hasNextPage && !isLoading && !isLastPageReached && ( - - )} + {allContent.map((item, index) => { + const isLastElement = index === allContent.length - 1; // 마지막 요소인지 확인 + return ( + handlerNavigate(item.helloCallId)} + ref={isLastElement ? lastElementRef : null} // 마지막 요소에 ref 할당 + /> + ); + })} {(!hasNextPage || isLastPageReached) && ( 더 이상 요청이 없어요 🥲 )} diff --git a/src/pages/sinitto/hello-call-list/api/hooks/useGetServiceList.ts b/src/pages/sinitto/hello-call-list/api/hooks/useGetServiceList.ts index 2f0bf308..2692883a 100644 --- a/src/pages/sinitto/hello-call-list/api/hooks/useGetServiceList.ts +++ b/src/pages/sinitto/hello-call-list/api/hooks/useGetServiceList.ts @@ -2,12 +2,16 @@ import { getServiceList, ServiceListQueryKey } from '../service-list.api'; import { ServiceListResponse } from '../types'; import { useInfiniteQuery } from '@tanstack/react-query'; -export const useGetServiceList = () => { +export const useGetServiceList = (size: number) => { return useInfiniteQuery({ - queryKey: ServiceListQueryKey, - queryFn: ({ pageParam = 0 }) => getServiceList(Number(pageParam)), - getNextPageParam: (lastPage, allPages) => - lastPage.content.length > 0 ? allPages.length : undefined, + queryKey: [ServiceListQueryKey, size], + queryFn: ({ pageParam = 0 }) => getServiceList(Number(pageParam), size), + getNextPageParam: (lastPage) => { + if (!lastPage.last) { + return lastPage.number + 1; + } + return undefined; + }, initialPageParam: 0, }); }; diff --git a/src/pages/sinitto/hello-call-list/api/service-list.api.ts b/src/pages/sinitto/hello-call-list/api/service-list.api.ts index af579b29..65ac40b2 100644 --- a/src/pages/sinitto/hello-call-list/api/service-list.api.ts +++ b/src/pages/sinitto/hello-call-list/api/service-list.api.ts @@ -1,16 +1,24 @@ import { ServiceListResponse } from './types'; import { fetchInstance } from '@/shared/api/instance'; -const getServiceListPath = (page: number) => - `/api/hellocalls/sinittos/list?page=${page}`; +const getServiceListPath = () => `/api/hellocalls/sinittos/list`; -export const ServiceListQueryKey = ['serviceList']; +export const ServiceListQueryKey = [getServiceListPath]; export const getServiceList = async ( - page: number + page: number, + size: number, + sort: string = 'DESC' ): Promise => { const response = await fetchInstance.get( - getServiceListPath(page) + getServiceListPath(), + { + params: { + page, + size, + sort, + }, + } ); return response.data; }; diff --git a/src/pages/sinitto/hello-call-list/components/call-request/CallRequest.tsx b/src/pages/sinitto/hello-call-list/components/call-request/CallRequest.tsx index 14da6501..31841927 100644 --- a/src/pages/sinitto/hello-call-list/components/call-request/CallRequest.tsx +++ b/src/pages/sinitto/hello-call-list/components/call-request/CallRequest.tsx @@ -1,3 +1,5 @@ +import { forwardRef } from 'react'; + import ArrowIcon from '../../assets/arrow.svg'; import { Box, Image, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -8,36 +10,41 @@ type Props = { days?: string[]; }; -const CallRequest = ({ onClick, seniorName, days }: Props) => { - return ( - - - {seniorName}님의 요청 - - - - {days?.map((day, index) => {day})} - +const CallRequest = forwardRef( + ({ onClick, seniorName, days }, ref) => { + return ( + - arrow-icon + {seniorName}님의 요청 + + + + {days?.map((day, index) => {day})} + + + arrow-icon + - - ); -}; + ); + } +); + +CallRequest.displayName = 'CallRequest'; export default CallRequest; diff --git a/src/pages/sinitto/hello-call-list/index.ts b/src/pages/sinitto/hello-call-list/index.ts index b5a3635a..5993baba 100644 --- a/src/pages/sinitto/hello-call-list/index.ts +++ b/src/pages/sinitto/hello-call-list/index.ts @@ -1,3 +1,4 @@ export { default as HelloCallListPage } from './HelloCallListPage'; export * from './components'; +export * from './api'; diff --git a/src/pages/sinitto/mypage/SinittoMypage.tsx b/src/pages/sinitto/mypage/SinittoMypage.tsx index 25206498..23bd06f2 100644 --- a/src/pages/sinitto/mypage/SinittoMypage.tsx +++ b/src/pages/sinitto/mypage/SinittoMypage.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import { SinittoProfileBox, AccountInfoBox } from './components'; import { BasicButton, PointBox, PointLogBox } from '@/shared/components'; -import { Box } from '@chakra-ui/react'; +import { Flex } from '@chakra-ui/react'; import styled from '@emotion/styled'; const SinittoMypage = () => { @@ -18,6 +18,7 @@ const SinittoMypage = () => { setIsEditingProfile(true)} > 내 정보 수정하기 @@ -29,6 +30,7 @@ const SinittoMypage = () => { setIsEditingAccount(true)} > 계좌번호 수정하기 @@ -41,8 +43,8 @@ const SinittoMypage = () => { export default SinittoMypage; -const MyPageLayout = styled(Box)` - display: flex; +const MyPageLayout = styled(Flex)` flex-direction: column; align-items: center; + gap: 0.2rem; `; diff --git a/src/pages/sinitto/mypage/store/hooks/index.ts b/src/pages/sinitto/mypage/api/hooks/index.ts similarity index 78% rename from src/pages/sinitto/mypage/store/hooks/index.ts rename to src/pages/sinitto/mypage/api/hooks/index.ts index ab383c3b..4e7c8152 100644 --- a/src/pages/sinitto/mypage/store/hooks/index.ts +++ b/src/pages/sinitto/mypage/api/hooks/index.ts @@ -1,5 +1,4 @@ export { - useGetSinittoInformation, useModifySinittoBankInfomation, useModifySinittoInformation, } from './useSinittoInfo'; diff --git a/src/pages/sinitto/mypage/store/hooks/useSinittoInfo.ts b/src/pages/sinitto/mypage/api/hooks/useSinittoInfo.ts similarity index 62% rename from src/pages/sinitto/mypage/store/hooks/useSinittoInfo.ts rename to src/pages/sinitto/mypage/api/hooks/useSinittoInfo.ts index 1577ce4e..d5f93021 100644 --- a/src/pages/sinitto/mypage/store/hooks/useSinittoInfo.ts +++ b/src/pages/sinitto/mypage/api/hooks/useSinittoInfo.ts @@ -1,23 +1,9 @@ -import { getSinittoInformation } from '../api'; import { - getSinittoInformationQueryKey, modifySinittoBankInfomation, modifySinittoInfomation, - SinittoBankInfo, - SinittoInformation, -} from '../api/sinitto-information.api'; -import { - useMutation, - UseMutationResult, - useQuery, -} from '@tanstack/react-query'; - -export const useGetSinittoInformation = () => { - return useQuery({ - queryKey: getSinittoInformationQueryKey, - queryFn: () => getSinittoInformation(), - }); -}; +} from '../sinitto-information.api'; +import { SinittoBankInfo, SinittoInformation } from '../types'; +import { useMutation, UseMutationResult } from '@tanstack/react-query'; export const useModifySinittoBankInfomation = (): UseMutationResult< string, diff --git a/src/pages/sinitto/mypage/api/index.ts b/src/pages/sinitto/mypage/api/index.ts new file mode 100644 index 00000000..852dcd03 --- /dev/null +++ b/src/pages/sinitto/mypage/api/index.ts @@ -0,0 +1,7 @@ +export { + modifySinittoBankInfomation, + modifySinittoInfomation, +} from './sinitto-information.api'; + +export * from './types'; +export * from './hooks'; diff --git a/src/pages/sinitto/mypage/api/sinitto-information.api.ts b/src/pages/sinitto/mypage/api/sinitto-information.api.ts new file mode 100644 index 00000000..cb22d693 --- /dev/null +++ b/src/pages/sinitto/mypage/api/sinitto-information.api.ts @@ -0,0 +1,26 @@ +import { SinittoBankInfo, SinittoInformation } from './types'; +import { fetchInstance } from '@/shared'; + +const sinittoInformationPath = () => '/api/sinittos'; + +// 계좌 정보 수정 +export const modifySinittoBankInfomation = async ( + bankInfo: SinittoBankInfo +) => { + const response = await fetchInstance.put( + `${sinittoInformationPath()}/bank`, + bankInfo + ); + return response.data; +}; + +// 본인 정보 수정 +export const modifySinittoInfomation = async ( + sinittoInfo: SinittoInformation +) => { + const response = await fetchInstance.put( + sinittoInformationPath(), + sinittoInfo + ); + return response.data; +}; diff --git a/src/pages/sinitto/mypage/api/types/index.ts b/src/pages/sinitto/mypage/api/types/index.ts new file mode 100644 index 00000000..677e7d8f --- /dev/null +++ b/src/pages/sinitto/mypage/api/types/index.ts @@ -0,0 +1,4 @@ +export type { + SinittoInformation, + SinittoBankInfo, +} from './sinitto-infromation.response'; diff --git a/src/pages/sinitto/mypage/api/types/sinitto-infromation.response.ts b/src/pages/sinitto/mypage/api/types/sinitto-infromation.response.ts new file mode 100644 index 00000000..cd17197d --- /dev/null +++ b/src/pages/sinitto/mypage/api/types/sinitto-infromation.response.ts @@ -0,0 +1,12 @@ +export type SinittoInformation = { + name: string; + email: string; + phoneNumber: string; + accountNumber: string; + bankName: string; +}; + +export type SinittoBankInfo = { + accountNumber: string; + bankName: string; +}; diff --git a/src/pages/sinitto/mypage/components/account-info-box/AccountInfoBox.tsx b/src/pages/sinitto/mypage/components/account-info-box/AccountInfoBox.tsx index f39c0b2a..abc076f6 100644 --- a/src/pages/sinitto/mypage/components/account-info-box/AccountInfoBox.tsx +++ b/src/pages/sinitto/mypage/components/account-info-box/AccountInfoBox.tsx @@ -1,10 +1,8 @@ import { useEffect, useState } from 'react'; -import { - useGetSinittoInformation, - useModifySinittoBankInfomation, -} from '../../store/hooks'; -import { Box, Text, Button, Input } from '@chakra-ui/react'; +import { useModifySinittoBankInfomation } from '@/pages'; +import { useSinittoInfo } from '@/shared'; +import { Text, Button, Input, Flex } from '@chakra-ui/react'; import styled from '@emotion/styled'; type Props = { @@ -13,7 +11,7 @@ type Props = { }; const AccountInfoBox = ({ isEditing, setIsEditing }: Props) => { - const { data, isLoading, isError, refetch } = useGetSinittoInformation(); + const { data, refetch } = useSinittoInfo(); const modifyBankInfoMutation = useModifySinittoBankInfomation(); const [accountNumber, setAccountNumber] = useState(''); @@ -38,20 +36,12 @@ const AccountInfoBox = ({ isEditing, setIsEditing }: Props) => { ); }; - if (isLoading) return
로딩 중...
; - if (isError) return
데이터를 가져오는 데 오류가 발생했습니다.
; - return ( - + @@ -72,17 +62,11 @@ const AccountInfoBox = ({ isEditing, setIsEditing }: Props) => { {data?.accountNumber} )} - - + + @@ -99,37 +83,31 @@ const AccountInfoBox = ({ isEditing, setIsEditing }: Props) => { bg='var(--color-white)' /> ) : ( - + {data?.bankName} )} - - + + 계좌 인증 여부 - - 인증 완료 + + {data?.accountNumber ? '인증 완료' : '인증 미완료'} - - + + {isEditing ? ( <> ) : null} - + ); }; export default AccountInfoBox; -const AccountBoxLayout = styled(Box)` - display: flex; +const AccountBoxLayout = styled(Flex)` flex-direction: column; justify-content: center; background-color: #f2f2f2; diff --git a/src/pages/sinitto/mypage/components/profile-box/SinittoProfileBox.tsx b/src/pages/sinitto/mypage/components/profile-box/SinittoProfileBox.tsx index 40488e81..a8ff41d1 100644 --- a/src/pages/sinitto/mypage/components/profile-box/SinittoProfileBox.tsx +++ b/src/pages/sinitto/mypage/components/profile-box/SinittoProfileBox.tsx @@ -1,9 +1,7 @@ import { useEffect, useState } from 'react'; -import { - useGetSinittoInformation, - useModifySinittoInformation, -} from '../../store/hooks'; +import { useModifySinittoInformation } from '@/pages'; +import { Logout, useSinittoInfo } from '@/shared'; import { Box, Text, Button, Input } from '@chakra-ui/react'; import styled from '@emotion/styled'; @@ -13,12 +11,13 @@ type Props = { }; const SinittoProfileBox = ({ isEditing, setIsEditing }: Props) => { - const { data, isLoading, isError, refetch } = useGetSinittoInformation(); - const modifySinittoInfoMutation = useModifySinittoInformation(); - const [name, setName] = useState(''); const [phoneNumber, setPhoneNumber] = useState(''); + const { data, refetch } = useSinittoInfo(); + + const modifySinittoInfoMutation = useModifySinittoInformation(); + useEffect(() => { if (isEditing) { setName(data?.name || ''); @@ -42,14 +41,19 @@ const SinittoProfileBox = ({ isEditing, setIsEditing }: Props) => { }); }; - if (isLoading) return
로딩 중...
; - if (isError) return
데이터를 가져오는 데 오류가 발생했습니다.
; - return ( - - {data?.name} 님 환영합니다. - + + + {data?.name} 님 환영합니다. + + + '/api/sinittos'; - -export const getSinittoInformationQueryKey = ['sinittoInformation']; - -// 본인 정보 조회 -export const getSinittoInformation = async (): Promise => { - const response = await fetchInstance.get(sinittoInformationPath()); - return response.data; -}; - -// 계좌 정보 수정 -export const modifySinittoBankInfomation = async ( - bankInfo: SinittoBankInfo -) => { - const response = await fetchInstance.put( - `${sinittoInformationPath()}/bank`, - bankInfo - ); - return response.data; -}; - -// 본인 정보 수정 -export const modifySinittoInfomation = async ( - sinittoInfo: SinittoInformation -) => { - const response = await fetchInstance.put( - sinittoInformationPath(), - sinittoInfo - ); - return response.data; -}; diff --git a/src/pages/sinitto/mypage/store/servers/index.ts b/src/pages/sinitto/mypage/store/servers/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/pages/sinitto/sinitto-main/SinittoMainPage.tsx b/src/pages/sinitto/sinitto-main/SinittoMainPage.tsx index c867df29..ff174776 100644 --- a/src/pages/sinitto/sinitto-main/SinittoMainPage.tsx +++ b/src/pages/sinitto/sinitto-main/SinittoMainPage.tsx @@ -1,19 +1,16 @@ -import { CallBackApply, Header, HelloCallApply } from './components'; -import { Flex, Text } from '@chakra-ui/react'; +import { + CallBackApply, + Header, + HelloCallApply, + SinittoName, +} from './components'; import styled from '@emotion/styled'; export const SinittoMainPage = () => { return (
- - - 김시니또 - - - 님 안녕하세요! - - + diff --git a/src/pages/sinitto/sinitto-main/api/hooks/index.ts b/src/pages/sinitto/sinitto-main/api/hooks/index.ts new file mode 100644 index 00000000..819a0cf1 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/hooks/index.ts @@ -0,0 +1 @@ +export { useGetSinittoInfo } from './useGetSinittoInfo'; diff --git a/src/pages/sinitto/sinitto-main/api/hooks/useGetSinittoInfo.ts b/src/pages/sinitto/sinitto-main/api/hooks/useGetSinittoInfo.ts new file mode 100644 index 00000000..0bc9f310 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/hooks/useGetSinittoInfo.ts @@ -0,0 +1,12 @@ +import { getSinittoInfo, sinittoInfoPath } from '../sinitto-info.api'; +import { SinittoInfoResponse } from '../types'; +import { useQuery } from '@tanstack/react-query'; + +const SinittoInfoQueryKey = [sinittoInfoPath()]; + +export const useGetSinittoInfo = () => { + return useQuery({ + queryKey: SinittoInfoQueryKey, + queryFn: () => getSinittoInfo(), + }); +}; diff --git a/src/pages/sinitto/sinitto-main/api/index.ts b/src/pages/sinitto/sinitto-main/api/index.ts new file mode 100644 index 00000000..36f6f976 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/index.ts @@ -0,0 +1,4 @@ +export { getSinittoInfo, sinittoInfoPath } from './sinitto-info.api'; + +export * from './types'; +export * from './hooks'; diff --git a/src/pages/sinitto/sinitto-main/api/sinitto-info.api.ts b/src/pages/sinitto/sinitto-main/api/sinitto-info.api.ts new file mode 100644 index 00000000..dbeaa2e4 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/sinitto-info.api.ts @@ -0,0 +1,10 @@ +import { SinittoInfoResponse } from './types'; +import { fetchInstance } from '@/shared'; + +export const sinittoInfoPath = () => `/api/sinitto`; + +export const getSinittoInfo = async (): Promise => { + const response = + await fetchInstance.get(sinittoInfoPath()); + return response.data; +}; diff --git a/src/pages/sinitto/sinitto-main/api/types/index.ts b/src/pages/sinitto/sinitto-main/api/types/index.ts new file mode 100644 index 00000000..9a1d4016 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/types/index.ts @@ -0,0 +1 @@ +export type { SinittoInfoResponse } from './sinitto-info.response'; diff --git a/src/pages/sinitto/sinitto-main/api/types/sinitto-info.response.ts b/src/pages/sinitto/sinitto-main/api/types/sinitto-info.response.ts new file mode 100644 index 00000000..4a31330d --- /dev/null +++ b/src/pages/sinitto/sinitto-main/api/types/sinitto-info.response.ts @@ -0,0 +1,7 @@ +export type SinittoInfoResponse = { + name: string; + phoneNumber: string; + email: string; + accountNumber: string; + bankName: string; +}; diff --git a/src/pages/sinitto/sinitto-main/components/common/call-back-apply/CallBackApply.tsx b/src/pages/sinitto/sinitto-main/components/common/call-back-apply/CallBackApply.tsx index 2becfe5f..f7b30ee9 100644 --- a/src/pages/sinitto/sinitto-main/components/common/call-back-apply/CallBackApply.tsx +++ b/src/pages/sinitto/sinitto-main/components/common/call-back-apply/CallBackApply.tsx @@ -1,23 +1,42 @@ +import { Link } from 'react-router-dom'; + +import dayjs from 'dayjs'; + +import { RouterPath } from '@/app/routes'; import { IconArrow } from '@/pages/assets'; import IconCall from '@/pages/assets/sinitto-main/call.svg'; -import { ResponseBox } from '@/pages/sinitto'; -import { Box, Flex, Image, Text } from '@chakra-ui/react'; +import { ResponseBox, useGetCallbacks } from '@/pages/sinitto'; +import { Box, Flex, Image, Spinner, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; export const CallBackApply = () => { - const seniorName = '김순자'; - const seniorId = 1; + const { data: callBackList, isLoading } = useGetCallbacks(4); + + const timeSince = (postTime: string) => { + const now = dayjs(); + const postDate = dayjs(postTime); + const diffInMinutes = now.diff(postDate, 'minute'); + + if (diffInMinutes < 60) return `${diffInMinutes}분 전`; + const diffInHours = now.diff(postDate, 'hour'); + if (diffInHours < 24) return `${diffInHours}시간 전`; + + const diffInDays = now.diff(postDate, 'day'); + return `${diffInDays}일 전`; + }; return ( 콜백 요청 - - - 요청 더보기 - - - + + + + 요청 더보기 + + + + call-icon @@ -25,11 +44,21 @@ export const CallBackApply = () => { 대기 중인 요청을 잡아 가이드라인을 확인하고 도움을 시작해보세요. - - {[...Array(4)].map((_, index) => ( - - ))} - + {isLoading ? ( + + + + ) : ( + + {callBackList?.pages?.[0]?.content.map((callback) => ( + + ))} + + )} ); }; diff --git a/src/pages/sinitto/sinitto-main/components/common/header/Header.tsx b/src/pages/sinitto/sinitto-main/components/common/header/Header.tsx index 57173bf2..f51fbc51 100644 --- a/src/pages/sinitto/sinitto-main/components/common/header/Header.tsx +++ b/src/pages/sinitto/sinitto-main/components/common/header/Header.tsx @@ -1,3 +1,6 @@ +import { Link } from 'react-router-dom'; + +import { RouterPath } from '@/app/routes'; import IconUser from '@/pages/assets/shared/user.svg'; import { HEADER_HEIGHT } from '@/shared'; import { Image } from '@chakra-ui/react'; @@ -6,7 +9,9 @@ import styled from '@emotion/styled'; export const Header = () => { return ( - icon-user + + icon-user + ); }; diff --git a/src/pages/sinitto/sinitto-main/components/common/hello-call-apply/HelloCallApply.tsx b/src/pages/sinitto/sinitto-main/components/common/hello-call-apply/HelloCallApply.tsx index 506843b3..b22069c1 100644 --- a/src/pages/sinitto/sinitto-main/components/common/hello-call-apply/HelloCallApply.tsx +++ b/src/pages/sinitto/sinitto-main/components/common/hello-call-apply/HelloCallApply.tsx @@ -1,23 +1,27 @@ +import { Link } from 'react-router-dom'; + +import { RouterPath } from '@/app/routes'; import { IconArrow } from '@/pages/assets'; import HelloCallImg from '@/pages/assets/shared/hello-call.png'; -import { ResponseBox } from '@/pages/sinitto'; -import { Box, Flex, Image, Text } from '@chakra-ui/react'; +import { ResponseBox, useGetServiceList } from '@/pages/sinitto'; +import { Box, Flex, Image, Spinner, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; export const HelloCallApply = () => { - const seniorName = '김순자'; - const seniorId = 1; + const { data: helloCallList, isLoading } = useGetServiceList(2); return ( 안부전화 요청 - - - 요청 더보기 - - - + + + + 요청 더보기 + + + + call-icon @@ -28,11 +32,21 @@ export const HelloCallApply = () => { - - {[...Array(2)].map((_, index) => ( - - ))} - + {isLoading ? ( + + + + ) : ( + + {helloCallList?.pages?.[0]?.content.map((helloCall) => ( + + ))} + + )} ); }; diff --git a/src/pages/sinitto/sinitto-main/components/common/index.ts b/src/pages/sinitto/sinitto-main/components/common/index.ts index 49ab53ba..195ad234 100644 --- a/src/pages/sinitto/sinitto-main/components/common/index.ts +++ b/src/pages/sinitto/sinitto-main/components/common/index.ts @@ -1,3 +1,4 @@ export * from './call-back-apply'; export * from './header'; export * from './hello-call-apply'; +export * from './sinitto-name'; diff --git a/src/pages/sinitto/sinitto-main/components/common/sinitto-name/SinittoName.tsx b/src/pages/sinitto/sinitto-main/components/common/sinitto-name/SinittoName.tsx new file mode 100644 index 00000000..c86dd153 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/components/common/sinitto-name/SinittoName.tsx @@ -0,0 +1,17 @@ +import { useSinittoInfo } from '@/shared'; +import { Flex, Text } from '@chakra-ui/react'; + +export const SinittoName = () => { + const { data } = useSinittoInfo(); + + return ( + + + {data?.name} + + + 님 안녕하세요! + + + ); +}; diff --git a/src/pages/sinitto/sinitto-main/components/common/sinitto-name/index.ts b/src/pages/sinitto/sinitto-main/components/common/sinitto-name/index.ts new file mode 100644 index 00000000..de7680f6 --- /dev/null +++ b/src/pages/sinitto/sinitto-main/components/common/sinitto-name/index.ts @@ -0,0 +1 @@ +export { SinittoName } from './SinittoName'; diff --git a/src/pages/sinitto/sinitto-main/components/features/response-box/ResponseBox.tsx b/src/pages/sinitto/sinitto-main/components/features/response-box/ResponseBox.tsx index 98aafad7..28ea45fa 100644 --- a/src/pages/sinitto/sinitto-main/components/features/response-box/ResponseBox.tsx +++ b/src/pages/sinitto/sinitto-main/components/features/response-box/ResponseBox.tsx @@ -3,14 +3,15 @@ import styled from '@emotion/styled'; type Props = { seniorName: string; + requestTime: string; }; -export const ResponseBox = ({ seniorName }: Props) => { +export const ResponseBox = ({ seniorName, requestTime }: Props) => { return ( {seniorName}님 - 6 분전 + {requestTime} 대기 diff --git a/src/pages/sinitto/sinitto-main/index.ts b/src/pages/sinitto/sinitto-main/index.ts index 6a5c4b34..152917ff 100644 --- a/src/pages/sinitto/sinitto-main/index.ts +++ b/src/pages/sinitto/sinitto-main/index.ts @@ -1,3 +1,4 @@ export { SinittoMainPage } from './SinittoMainPage'; +export * from './api'; export * from './components'; diff --git a/src/shared/api/hooks/index.ts b/src/shared/api/hooks/index.ts index 976d77a4..8dc953cb 100644 --- a/src/shared/api/hooks/index.ts +++ b/src/shared/api/hooks/index.ts @@ -1 +1,2 @@ export { useGetCallback } from './useGetCallback'; +export { useLogout } from './useLogout'; diff --git a/src/shared/api/hooks/useLogout.ts b/src/shared/api/hooks/useLogout.ts new file mode 100644 index 00000000..31befb43 --- /dev/null +++ b/src/shared/api/hooks/useLogout.ts @@ -0,0 +1,20 @@ +import { useNavigate } from 'react-router-dom'; + +import { RouterPath } from '@/app/routes'; +import { userLogout } from '@/shared'; +import { authStorage } from '@/shared/utils'; +import { useMutation } from '@tanstack/react-query'; + +export const useLogout = () => { + const navigate = useNavigate(); + + return useMutation({ + mutationFn: userLogout, + onSuccess: () => { + authStorage.accessToken.set(undefined); + authStorage.refreshToken.set(undefined); + alert('로그아웃 되었습니다.'); + navigate(RouterPath.ROOT); + }, + }); +}; diff --git a/src/shared/api/index.ts b/src/shared/api/index.ts index 3ff8b375..075b7a60 100644 --- a/src/shared/api/index.ts +++ b/src/shared/api/index.ts @@ -1,5 +1,5 @@ export { getCallback } from './get-call-back.api'; - +export { userLogout } from './logout.api'; export * from './instance'; export * from './hooks'; export * from './point'; diff --git a/src/shared/api/instance/Instance.tsx b/src/shared/api/instance/Instance.tsx index 5ab6ac81..f19891b5 100644 --- a/src/shared/api/instance/Instance.tsx +++ b/src/shared/api/instance/Instance.tsx @@ -5,8 +5,7 @@ import type { } from 'axios'; import axios from 'axios'; -import { authLocalStorage } from '@/shared'; -import { BASE_URI } from '@/shared/utils/env/config'; +import { authStorage } from '../../utils/storage/authStorage'; import { QueryClient } from '@tanstack/react-query'; const initInstance = (config: AxiosRequestConfig): AxiosInstance => { @@ -25,6 +24,8 @@ const initInstance = (config: AxiosRequestConfig): AxiosInstance => { return instance; }; +export const BASE_URI = `http://sinitto.site:8080`; + export const fetchInstance = initInstance({ baseURL: BASE_URI, }); @@ -42,7 +43,7 @@ export const queryClient = new QueryClient({ fetchInstance.interceptors.request.use( (config: InternalAxiosRequestConfig) => { - const accessToken = authLocalStorage.get(); + const accessToken = authStorage.accessToken.get(); if (accessToken !== undefined) { config.headers['Content-Type'] = 'application/json'; config.headers.Authorization = `Bearer ${accessToken}`; diff --git a/src/shared/api/instance/index.ts b/src/shared/api/instance/index.ts index 07aed276..370c34a5 100644 --- a/src/shared/api/instance/index.ts +++ b/src/shared/api/instance/index.ts @@ -1 +1 @@ -export { fetchInstance, queryClient } from './Instance'; +export { fetchInstance, BASE_URI, queryClient } from './Instance'; diff --git a/src/shared/api/logout.api.ts b/src/shared/api/logout.api.ts new file mode 100644 index 00000000..51cb9c53 --- /dev/null +++ b/src/shared/api/logout.api.ts @@ -0,0 +1,8 @@ +import { fetchInstance } from '@/shared/api/instance'; + +const getLogoutPath = '/api/members/logout'; + +export const userLogout = async () => { + const response = await fetchInstance.delete(getLogoutPath); + return response.data; +}; diff --git a/src/shared/api/point/point.api.ts b/src/shared/api/point/point.api.ts index a2c0e80c..86c57f7e 100644 --- a/src/shared/api/point/point.api.ts +++ b/src/shared/api/point/point.api.ts @@ -24,7 +24,7 @@ export const getPointInfo = async (): Promise => { // 포인트 인출 API export const withdrawPoint = async (price: number) => { const response = await fetchInstance.post(`${pointApiPath}/withdraw`, { - price: price, + price, }); return response.data; }; @@ -34,7 +34,7 @@ export const chargePoint = async ( price: number ): Promise => { const response = await fetchInstance.put(`${pointApiPath}/charge`, { - price: price, + price, }); return response.data; }; diff --git a/src/shared/components/common/button/BasicButton.tsx b/src/shared/components/common/button/BasicButton.tsx index 464ad729..b0e7c1f6 100644 --- a/src/shared/components/common/button/BasicButton.tsx +++ b/src/shared/components/common/button/BasicButton.tsx @@ -3,11 +3,12 @@ import styled from '@emotion/styled'; type Props = { themeType?: 'default' | 'outline'; width?: string; + height?: string; }; export const BasicButton = styled.button` width: ${(props) => (props.width ? props.width : '100%')}; - height: 50px; + height: ${(props) => (props.height ? props.height : '50px')}; border-radius: 10px; outline: 0; diff --git a/src/shared/components/common/guide-line-button/GuideLineButton.tsx b/src/shared/components/common/guide-line-button/GuideLineButton.tsx index b7d72e28..01ff1026 100644 --- a/src/shared/components/common/guide-line-button/GuideLineButton.tsx +++ b/src/shared/components/common/guide-line-button/GuideLineButton.tsx @@ -4,19 +4,13 @@ import { IconArrow } from '@/pages/assets'; import { Box, Text } from '@chakra-ui/react'; import styled from '@emotion/styled'; -type GuideLineCategory = { - title: string; - id: string | null; - backgroundColor: string; -}; - type Props = { marginTop?: number; marginBottom?: number; seniorId?: number | null; }; -const GUIDE_LINE_CATEGORIES: GuideLineCategory[] = [ +const GUIDE_LINE_CATEGORIES = [ { title: '택시 호출하기', id: 'TAXI', @@ -37,7 +31,9 @@ const GUIDE_LINE_CATEGORIES: GuideLineCategory[] = [ id: null, backgroundColor: '#ff4d68', }, -]; +] as const; + +type GuideLineCategory = (typeof GUIDE_LINE_CATEGORIES)[number]; export const GuideLineButton = ({ marginTop, @@ -47,7 +43,7 @@ export const GuideLineButton = ({ const navigate = useNavigate(); const location = useLocation(); - const handleClick = (id: string | null) => { + const goToSinitto = (id: string | null) => { if (id === null) { alert('개발 예정입니다.'); return; @@ -69,12 +65,12 @@ export const GuideLineButton = ({ }; return ( - - {GUIDE_LINE_CATEGORIES.map((data) => ( + + {GUIDE_LINE_CATEGORIES.map((data: GuideLineCategory) => ( handleClick(data.id)} + onClick={() => goToSinitto(data.id)} > {data.title} @@ -82,14 +78,10 @@ export const GuideLineButton = ({ ))} - + ); }; -const Wrapper = styled(Box)` - width: 100%; -`; - const ButtonWrapper = styled.div<{ backgroundColor: string }>` width: 100%; height: 70px; diff --git a/src/shared/components/common/index.ts b/src/shared/components/common/index.ts index e160f1e8..bd7a6d3c 100644 --- a/src/shared/components/common/index.ts +++ b/src/shared/components/common/index.ts @@ -2,4 +2,3 @@ export * from './button'; export * from './guide-line-button'; export * from './layout'; export * from './view'; -export * from './visibility-loader'; diff --git a/src/shared/components/common/visibility-loader/VisibilityLoader.tsx b/src/shared/components/common/visibility-loader/VisibilityLoader.tsx deleted file mode 100644 index 02fd169a..00000000 --- a/src/shared/components/common/visibility-loader/VisibilityLoader.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { - useIntersectionObserver, - UseIntersectionObserverProps, -} from '@/shared'; -import { Spinner } from '@chakra-ui/react'; -import styled from '@emotion/styled'; - -type Props = { - children?: React.ReactNode; -} & UseIntersectionObserverProps; - -export const VisibilityLoader = ({ - children = , - ...observerProps -}: Props) => { - const { ref } = useIntersectionObserver(observerProps); - - return ( - -
{children}
-
- ); -}; - -const Wrapper = styled.div` - width: 100%; - display: flex; - justify-content: center; - padding: '32px 48px'; -`; diff --git a/src/shared/components/common/visibility-loader/index.ts b/src/shared/components/common/visibility-loader/index.ts deleted file mode 100644 index a6a985c8..00000000 --- a/src/shared/components/common/visibility-loader/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { VisibilityLoader } from './VisibilityLoader'; diff --git a/src/shared/components/features/header/Header.tsx b/src/shared/components/features/header/Header.tsx index e4d28c7c..22c08374 100644 --- a/src/shared/components/features/header/Header.tsx +++ b/src/shared/components/features/header/Header.tsx @@ -18,7 +18,7 @@ type Props = { const Header = ({ title, defaultBackPath = RouterPath.ROOT }: Props) => { const navigate = useNavigate(); - const handleBackClick = () => { + const goToBack = () => { if (window.history.length > 1) { navigate(-1); } else { @@ -28,7 +28,7 @@ const Header = ({ title, defaultBackPath = RouterPath.ROOT }: Props) => { return ( - + {title} diff --git a/src/shared/components/features/mypage/index.ts b/src/shared/components/features/mypage/index.ts index 8df36623..bcb65af8 100644 --- a/src/shared/components/features/mypage/index.ts +++ b/src/shared/components/features/mypage/index.ts @@ -1,2 +1,3 @@ export * from './point-box'; export * from './point-log-box'; +export * from './logout-button'; diff --git a/src/shared/components/features/mypage/logout-button/Logout.tsx b/src/shared/components/features/mypage/logout-button/Logout.tsx new file mode 100644 index 00000000..7eae7303 --- /dev/null +++ b/src/shared/components/features/mypage/logout-button/Logout.tsx @@ -0,0 +1,18 @@ +import { BasicButton, useLogout } from '@/shared'; + +const Logout = () => { + const { mutate: logout } = useLogout(); + + return ( + logout()} + > + 로그아웃 + + ); +}; + +export default Logout; diff --git a/src/shared/components/features/mypage/logout-button/index.ts b/src/shared/components/features/mypage/logout-button/index.ts new file mode 100644 index 00000000..a32f1378 --- /dev/null +++ b/src/shared/components/features/mypage/logout-button/index.ts @@ -0,0 +1 @@ +export { default as Logout } from './Logout'; diff --git a/src/shared/components/features/mypage/point-box/PointBox.tsx b/src/shared/components/features/mypage/point-box/PointBox.tsx index 4c915673..2ea4b1ab 100644 --- a/src/shared/components/features/mypage/point-box/PointBox.tsx +++ b/src/shared/components/features/mypage/point-box/PointBox.tsx @@ -5,11 +5,11 @@ import { useGetPointInfo, useWithdrawPoint, } from '@/shared/hooks'; -import { Box, Text, Spinner, Button, Input } from '@chakra-ui/react'; +import { Box, Spinner, Button, Input } from '@chakra-ui/react'; import styled from '@emotion/styled'; const PointBox = () => { - const { data: pointData, isLoading, error, refetch } = useGetPointInfo(); + const { data: pointData, isLoading, refetch } = useGetPointInfo(); const chargePointMutation = useChargePoint(); const withdrawPointMutation = useWithdrawPoint(); const [actionType, setActionType] = useState(''); @@ -42,16 +42,6 @@ const PointBox = () => { ); } - if (error) { - return ( - - - 포인트 조회 중 오류가 발생했습니다. - - - ); - } - return ( { const [currentPage, setCurrentPage] = useState(0); const pageSize = 5; - const { data, isLoading, isError } = useGetPointLogs(currentPage, pageSize); + const { data, isLoading } = useGetPointLogs(currentPage, pageSize); const totalPages = data?.totalPages || 1; - if (isLoading) return
로딩 중...
; - if (isError) return
데이터를 가져오는 데 오류가 발생했습니다.
; + if (isLoading) { + return ( + + + + ); + } return ( @@ -98,7 +103,7 @@ const UseDetailBoxLayout = styled(Box)` background-color: #2e2e2e; border: 1px solid #2e2e2e; border-radius: 10px; - margin-top: 0.5rem; + margin: 0.5rem; `; const TextBox = styled(Box)` diff --git a/src/shared/hooks/point/useChargePoint.ts b/src/shared/hooks/point/useChargePoint.ts index 2be690af..69c1b93a 100644 --- a/src/shared/hooks/point/useChargePoint.ts +++ b/src/shared/hooks/point/useChargePoint.ts @@ -9,8 +9,8 @@ export const useChargePoint = (): UseMutationResult< > => { return useMutation({ mutationFn: (price) => chargePoint(price), - onSuccess: (data: ChargePointResponse) => { - alert(data.depositMessage); + onSuccess: () => { + alert('포인트 충전 요청 완료했습니다.'); }, onError: (error: Error) => { console.error(error); diff --git a/src/shared/provider/auth/Auth.tsx b/src/shared/provider/auth/Auth.tsx deleted file mode 100644 index 491b27d9..00000000 --- a/src/shared/provider/auth/Auth.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { createContext, ReactNode, useContext, useState } from 'react'; - -type AuthInfo = { - email: string | null; - setEmail: (email: string) => void; -}; - -export const AuthContext = createContext(undefined); - -export const AuthProvider = ({ children }: { children: ReactNode }) => { - const [email, setEmail] = useState(null); - - return ( - - {children} - - ); -}; - -export const useAuth = () => { - const context = useContext(AuthContext); - if (!context) { - throw new Error('useAuth는 AuthProvider 내부에서 사용되어야 합니다.'); - } - return context; -}; diff --git a/src/shared/provider/auth/index.ts b/src/shared/provider/auth/index.ts deleted file mode 100644 index 7710b448..00000000 --- a/src/shared/provider/auth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AuthContext, AuthProvider, useAuth } from './Auth'; diff --git a/src/shared/provider/index.ts b/src/shared/provider/index.ts index 9476e32e..ba826f9b 100644 --- a/src/shared/provider/index.ts +++ b/src/shared/provider/index.ts @@ -1,2 +1,3 @@ -export * from './auth'; +export * from './user-email'; +export * from './sinitto-info'; export * from './senior-info'; diff --git a/src/shared/provider/sinitto-info/SinittoInfo.tsx b/src/shared/provider/sinitto-info/SinittoInfo.tsx new file mode 100644 index 00000000..ba7dea04 --- /dev/null +++ b/src/shared/provider/sinitto-info/SinittoInfo.tsx @@ -0,0 +1,26 @@ +import { createContext, useContext, ReactNode } from 'react'; + +import { SinittoInfoResponse, useGetSinittoInfo } from '@/pages'; +import { UseQueryResult } from '@tanstack/react-query'; + +type SinittoInfoType = UseQueryResult; + +const SinittoInfo = createContext(undefined); + +export const SinittoInfoProvider = ({ children }: { children: ReactNode }) => { + const sinittoInfo = useGetSinittoInfo(); + + return ( + {children} + ); +}; + +export const useSinittoInfo = (): SinittoInfoType => { + const context = useContext(SinittoInfo); + if (context === undefined) { + throw new Error( + 'useSinittoInfo hook은 SinittoInfoProvider 내부에서 사용되어야 합니다.' + ); + } + return context; +}; diff --git a/src/shared/provider/sinitto-info/index.ts b/src/shared/provider/sinitto-info/index.ts new file mode 100644 index 00000000..89e7a198 --- /dev/null +++ b/src/shared/provider/sinitto-info/index.ts @@ -0,0 +1 @@ +export { SinittoInfoProvider, useSinittoInfo } from './SinittoInfo'; diff --git a/src/shared/provider/user-email/index.ts b/src/shared/provider/user-email/index.ts new file mode 100644 index 00000000..ed85bf19 --- /dev/null +++ b/src/shared/provider/user-email/index.ts @@ -0,0 +1,5 @@ +export { + UserEmailContext, + UserEmailProvider, + useUserEmail, +} from './user-email'; diff --git a/src/shared/provider/user-email/user-email.tsx b/src/shared/provider/user-email/user-email.tsx new file mode 100644 index 00000000..fbe8b844 --- /dev/null +++ b/src/shared/provider/user-email/user-email.tsx @@ -0,0 +1,30 @@ +import { createContext, ReactNode, useContext, useState } from 'react'; + +type UserEmailInfo = { + email: string | null; + setEmail: (email: string) => void; +}; + +export const UserEmailContext = createContext( + undefined +); + +export const UserEmailProvider = ({ children }: { children: ReactNode }) => { + const [email, setEmail] = useState(null); + + return ( + + {children} + + ); +}; + +export const useUserEmail = () => { + const context = useContext(UserEmailContext); + if (!context) { + throw new Error( + 'useUserEmail는 UserEmailProvider 내부에서 사용되어야 합니다.' + ); + } + return context; +}; diff --git a/src/shared/types/callback.response.ts b/src/shared/types/callback.response.ts index 715b3568..b0fae4fd 100644 --- a/src/shared/types/callback.response.ts +++ b/src/shared/types/callback.response.ts @@ -4,4 +4,6 @@ export type CallbackResponse = { postTime: string; status: string; seniorId: number; + isAssignedToSelf: boolean; + seniorPhoneNumber: string; }; diff --git a/src/shared/utils/env b/src/shared/utils/env deleted file mode 160000 index 2a0f73d6..00000000 --- a/src/shared/utils/env +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2a0f73d6acd23a0ed6836adac4bb909fbea387a3 diff --git a/src/shared/utils/storage/authLocalStorage.ts b/src/shared/utils/storage/authStorage.ts similarity index 75% rename from src/shared/utils/storage/authLocalStorage.ts rename to src/shared/utils/storage/authStorage.ts index 345799bc..9d8337bc 100644 --- a/src/shared/utils/storage/authLocalStorage.ts +++ b/src/shared/utils/storage/authStorage.ts @@ -1,5 +1,6 @@ type StorageKey = { accessToken?: string; + refreshToken?: string; }; const initStorage = ( @@ -23,4 +24,7 @@ const initStorage = ( return { get, set }; }; -export const authLocalStorage = initStorage('accessToken', localStorage); +export const authStorage = { + accessToken: initStorage('accessToken', localStorage), + refreshToken: initStorage('refreshToken', localStorage), +}; diff --git a/src/shared/utils/storage/index.ts b/src/shared/utils/storage/index.ts index cae91c62..ca30e68e 100644 --- a/src/shared/utils/storage/index.ts +++ b/src/shared/utils/storage/index.ts @@ -1 +1 @@ -export { authLocalStorage } from './authLocalStorage'; +export { authStorage } from './authStorage';