diff --git a/apps/duri/src/App.tsx b/apps/duri/src/App.tsx
index a63060c5..05cf56e8 100644
--- a/apps/duri/src/App.tsx
+++ b/apps/duri/src/App.tsx
@@ -1,6 +1,7 @@
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import AuthPage from '@duri/pages/Auth';
+import Home from '@duri/pages/Home';
import MyPetPage from '@duri/pages/My/MyPet';
import Onboarding from '@duri/pages/Onboarding';
import { globalStyle } from '@duri-fe/ui';
@@ -11,7 +12,6 @@ import PetDiaryDetail from '@pages/Diary/DiaryDetail';
import DooriAI from '@pages/DooriAI';
import DooriAIResult from '@pages/DooriAI/AIResult';
import AIStyling from '@pages/DooriAI/AIStyling';
-import Home from '@pages/Home';
import LoginPage from '@pages/Login';
import MyPage from '@pages/My';
import MyHistoryPage from '@pages/My/MyHistory';
diff --git a/apps/duri/src/components/my/review/ReviewUserInfo.tsx b/apps/duri/src/components/my/review/ReviewUserInfo.tsx
index 7e8a19c3..839fc3a5 100644
--- a/apps/duri/src/components/my/review/ReviewUserInfo.tsx
+++ b/apps/duri/src/components/my/review/ReviewUserInfo.tsx
@@ -80,18 +80,12 @@ export const ReviewUserInfo = ({
{createdAt}
-
+
-
+
{isOpen && (
-
+
@@ -101,14 +95,10 @@ export const ReviewUserInfo = ({
)}
{isOpenModal && (
-
+
-
+ 후기를 삭제하시겠습니까?
+
후기 삭제 후
@@ -116,12 +106,13 @@ export const ReviewUserInfo = ({
복구할 수 없습니다.
-
+
);
};
+
+const MoveToPortfolio = styled.a`
+ background-color: ${theme.palette.White};
+ ${theme.typo.Caption3}
+ color: ${theme.palette.Gray300};
+ padding: 10px;
+ text-align: center;
+ border-radius: 99px;
+ cursor: pointer;
+ text-decoration: none;
+`;
diff --git a/apps/salon/src/components/onboarding/InputSalon.tsx b/apps/salon/src/components/onboarding/InputSalon.tsx
index 24434be9..dad2b4d8 100644
--- a/apps/salon/src/components/onboarding/InputSalon.tsx
+++ b/apps/salon/src/components/onboarding/InputSalon.tsx
@@ -225,6 +225,7 @@ const InputSalon = ({
placeholder="미용사 면허번호 입력"
isEssential
width={175}
+ maxLength={10}
isNoBorder
shadow="0px 0px 4px 0px rgba(0, 0, 0, 0.10)"
helperText={
@@ -260,7 +261,7 @@ const InputSalon = ({
다음 단계
diff --git a/apps/salon/src/components/onboarding/InputSalonOwner.tsx b/apps/salon/src/components/onboarding/InputSalonOwner.tsx
index 132fad8a..7258c9db 100644
--- a/apps/salon/src/components/onboarding/InputSalonOwner.tsx
+++ b/apps/salon/src/components/onboarding/InputSalonOwner.tsx
@@ -362,8 +362,8 @@ const InputSalonOwner = ({
console.log(historyYear, historyMonths, license)}
- onSubmit={handleSubmit(onSubmitSalonOwnerData)}
+ // onClick={() => console.log(historyYear, historyMonths, license)}
+ onClick={handleSubmit(onSubmitSalonOwnerData)}
>
다음 단계
diff --git a/apps/salon/src/pages/Home/index.tsx b/apps/salon/src/pages/Home/index.tsx
index 0bb26200..7ebb4e40 100644
--- a/apps/salon/src/pages/Home/index.tsx
+++ b/apps/salon/src/pages/Home/index.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import { BottomSheet } from 'react-spring-bottom-sheet';
import { useNavigate } from 'react-router-dom';
@@ -22,6 +22,7 @@ import {
useBottomSheet,
useGetClosetGrooming,
useGetDailySchedule,
+ useGetGroomersList,
useGetHomeQuotationRequest,
useGetHomeShopInfo,
usePutGroomingComplete,
@@ -29,6 +30,7 @@ import {
} from '@duri-fe/utils';
import styled from '@emotion/styled';
import { RadioButton } from '@salon/components/home/RadioButton';
+import useGroomerStore from '@salon/stores/groomerStore';
import ClosetGrooming from '@components/home/ClosetGrooming';
import DailyScheduleItem from '@components/home/DailyScheduleItem';
@@ -49,6 +51,10 @@ const Home = () => {
const [completeToggle, setCompleteToggle] = useState(null);
+ //홈 진입 시 groomerId 전역변수로 저장
+ const { data: groomersListInfo } = useGetGroomersList({});
+ const { setGroomerId } = useGroomerStore();
+
const { data: shopInfoData } = useGetHomeShopInfo({});
const { data: closetGroomingData, isPending: closetGroomingPending } =
useGetClosetGrooming();
@@ -72,6 +78,11 @@ const Home = () => {
}
};
+ //로그인 후 미용사 id를 전역변수로 저장 for 포트폴리오
+ useEffect(() => {
+ if (groomersListInfo) setGroomerId(groomersListInfo[0].id);
+ }, [groomersListInfo]);
+
return (
{
- // const { data: petData, isError: getPetInfoError } = useGetPetInfo();
-
const navigate = useNavigate();
const handleNavigate = (path: string) => navigate(path);
+
+ const groomerId = useGroomerStore((state) => state.groomerId);
+
+ const [shopProfile, setShopProfile] = useState();
+ const [groomerProfile, setGroomerProfile] = useState();
+
+ const { data } = UseGetGroomerInfo({
+ groomerId: groomerId,
+ });
+
+ useEffect(() => {
+ if (data) {
+ setGroomerProfile(data.groomerProfileDetail);
+ setShopProfile(data.shopProfileDetail);
+ }
+ }, [data]);
+
const logout = () => {
- localStorage.removeItem('authorization_user');
+ localStorage.removeItem('authorization_shop');
navigate('/login');
};
+
useEffect(() => {
window.scrollTo(0, 0);
}, []);
@@ -38,54 +60,60 @@ const MyPage = () => {
margin="0 0 100px 0"
justify="flex-start"
>
-
-
-
-
-
+
-
- handleNavigate('/my/income')}
- >
-
- 매출관리
-
- handleNavigate('/my/review')}
- >
-
- 후기관리
-
+
+
+
+
+
+ handleNavigate('/my/income')}
+ >
+
+ 매출관리
+
+ handleNavigate('/my/review')}
+ >
+
+ 후기관리
+
+
+
-
-
+ >
+ ) : (
+ 등록된 정보가 없습니다.
+ )}
로그아웃
-
+
);
};
diff --git a/apps/salon/src/pages/Onboarding/index.tsx b/apps/salon/src/pages/Onboarding/index.tsx
index 416328e6..079c9940 100644
--- a/apps/salon/src/pages/Onboarding/index.tsx
+++ b/apps/salon/src/pages/Onboarding/index.tsx
@@ -58,7 +58,7 @@ const OnboardingPage = () => {
};
formData.append(
- 'data',
+ 'shopOnboardingRequest',
new Blob([JSON.stringify(onboardingFormData)], {
type: 'application/json',
}),
diff --git a/apps/salon/src/pages/Portfolio/PortfolioDetail.tsx b/apps/salon/src/pages/Portfolio/PortfolioDetail.tsx
new file mode 100644
index 00000000..bb92399f
--- /dev/null
+++ b/apps/salon/src/pages/Portfolio/PortfolioDetail.tsx
@@ -0,0 +1,17 @@
+import { useParams } from 'react-router-dom';
+
+import { GroomerPortfolioDetail, MobileLayout, SalonNavbar } from '@duri-fe/ui';
+
+const PortfolioDetailPage = () => {
+ const { portfolioId } = useParams<{ portfolioId: string }>();
+ const feedbackId = portfolioId ? Number(portfolioId) : 0;
+
+ return (
+
+
+
+
+ );
+};
+
+export default PortfolioDetailPage;
diff --git a/apps/salon/src/pages/Portfolio/index.tsx b/apps/salon/src/pages/Portfolio/index.tsx
new file mode 100644
index 00000000..8e59264c
--- /dev/null
+++ b/apps/salon/src/pages/Portfolio/index.tsx
@@ -0,0 +1,14 @@
+import { GroomerPortfolio, MobileLayout, SalonNavbar } from "@duri-fe/ui"
+import useGroomerStore from "@salon/stores/groomerStore";
+
+const PortfolioPage = () => {
+ const groomerId = useGroomerStore((state)=>state.groomerId);
+
+ return(
+
+
+
+
+ )
+}
+export default PortfolioPage;
\ No newline at end of file
diff --git a/apps/salon/src/stores/groomerStore.ts b/apps/salon/src/stores/groomerStore.ts
new file mode 100644
index 00000000..4aa26b87
--- /dev/null
+++ b/apps/salon/src/stores/groomerStore.ts
@@ -0,0 +1,23 @@
+import { create } from 'zustand';
+import { createJSONStorage, persist } from 'zustand/middleware';
+
+interface GroomerStoreType {
+ groomerId: number;
+ setGroomerId: (id: number) => void;
+}
+
+// Zustand 상태 생성
+const useGroomerStore = create(
+ persist(
+ (set) => ({
+ groomerId: 0,
+ setGroomerId: (groomerId: number) => set({ groomerId }),
+ }),
+ {
+ name: 'groomer-id',
+ storage: createJSONStorage(() => sessionStorage), // sessionStorage 사용
+ },
+ ),
+);
+
+export default useGroomerStore;
diff --git a/apps/salon/src/stores/index.ts b/apps/salon/src/stores/index.ts
new file mode 100644
index 00000000..4c491a60
--- /dev/null
+++ b/apps/salon/src/stores/index.ts
@@ -0,0 +1 @@
+export * from './groomerStore'
\ No newline at end of file
diff --git a/apps/salon/vite.config.ts b/apps/salon/vite.config.ts
index e62fce30..fda672ba 100644
--- a/apps/salon/vite.config.ts
+++ b/apps/salon/vite.config.ts
@@ -14,6 +14,7 @@ export default defineConfig({
{ find: '@utils', replacement: '/src/utils' },
{ find: '@types', replacement: '/src/types' },
{ find: '@hooks', replacement: '/src/hooks' },
+ { find: '@stores', replacement: '/src/stores' },
],
},
server: {
diff --git a/packages/ui/src/components/Portfolio/DesignerInfo.tsx b/packages/ui/src/components/Portfolio/DesignerInfo.tsx
index 0ca6807e..973ac92c 100644
--- a/packages/ui/src/components/Portfolio/DesignerInfo.tsx
+++ b/packages/ui/src/components/Portfolio/DesignerInfo.tsx
@@ -1,6 +1,7 @@
+import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
-import { Approve, Flex, Text, theme } from '@duri-fe/ui';
+import { Approve, Flex, ProfileImage, Text, theme } from '@duri-fe/ui';
import styled from '@emotion/styled';
interface DesignerInfoProps {
@@ -28,12 +29,22 @@ export const DesignerInfo = ({
}: DesignerInfoProps) => {
const navigate = useNavigate();
+ const [careerYear, setCareerYear] = useState(0);
+ const [careerMonth, setCareerMonth] = useState(0);
+
const moveToPortfolio = () => {
if (version === 'vertical') {
navigate(`/portfolio/${designerId}`);
}
};
+ useEffect(() => {
+ if (experience !== 0) {
+ setCareerYear(Math.floor(experience / 12));
+ setCareerMonth(experience % 12);
+ }
+ }, [experience]);
+
return (
-
+ {imageUrl === undefined ? (
+
+ ) : (
+
+ )}
- {name}
+ {name ?? '정보없음'}
{`경력 ${experience}년, ${age}세, ${gender}`}
+ >{`경력 ${careerYear ?? '-'}년 ${careerMonth ?? '-'}개월, ${age ?? '-'}세, ${gender}`}
-
- {roles.map((item, idx) => (
-
-
- {item}
-
-
-
- ))}
-
+ {roles?.length > 0 && (
+
+ {roles.map((item, idx) => (
+
+
+ {item}
+
+
+
+ ))}
+
+ )}
);
diff --git a/packages/ui/src/components/Portfolio/GroomerPortfolio.tsx b/packages/ui/src/components/Portfolio/GroomerPortfolio.tsx
index 136e41ad..2c88f4fd 100644
--- a/packages/ui/src/components/Portfolio/GroomerPortfolio.tsx
+++ b/packages/ui/src/components/Portfolio/GroomerPortfolio.tsx
@@ -1,8 +1,13 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
+import React from 'react';
-import { FilledHeart, Heart } from '@duri-fe/ui';
+import { FilledHeart, Heart, SalonTag } from '@duri-fe/ui';
import { theme } from '@duri-fe/ui';
import { UseGetGroomerInfo } from '@duri-fe/utils';
+import {
+ GroomerInfoType,
+ ShopInfoType,
+} from '@duri-fe/utils/src/apis/types/my';
import styled from '@emotion/styled';
import { Flex, HeightFitFlex, WidthFitFlex } from '../FlexBox';
@@ -13,24 +18,28 @@ import { PortfolioPhotos } from './PortfolioPhotos';
export const GroomerPortfolio = ({ groomerId }: { groomerId: number }) => {
const [isMarked, setIsMarked] = useState(false);
+ const [shopProfile, setShopProfile] = useState();
+ const [groomerProfile, setGroomerProfile] = useState();
const { data } = UseGetGroomerInfo({
groomerId: groomerId,
});
+ useEffect(() => {
+ if (data) {
+ setGroomerProfile(data.groomerProfileDetail);
+ setShopProfile(data.shopProfileDetail);
+ }
+ }, [data]);
+
return (
<>
-
+
- 댕댕샵
+ {shopProfile?.name ?? '정보 없음'}
{
- 경기도 성남시 불정로 119
+ {shopProfile?.address ?? '정보 없음'}
+ {shopProfile?.tags && (
+
+ {shopProfile.tags[0] && (
+
+ )}
+ {shopProfile.tags[1] && (
+
+ )}
+ {shopProfile.tags[2] && (
+
+ )}
+
+ )}
- {data && (
+ {groomerProfile && (
)}
diff --git a/packages/ui/src/components/Portfolio/GroomerPortfolioDetail.tsx b/packages/ui/src/components/Portfolio/GroomerPortfolioDetail.tsx
index 7920e8c1..8cc594b3 100644
--- a/packages/ui/src/components/Portfolio/GroomerPortfolioDetail.tsx
+++ b/packages/ui/src/components/Portfolio/GroomerPortfolioDetail.tsx
@@ -1,32 +1,62 @@
+import { useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
+ Button,
Card,
Flex,
+ HardText,
Header,
HeightFitFlex,
Image,
+ Menu,
+ Modal,
PetInfo,
+ ProfileImage,
RelativeFlex,
SalonTag,
Text,
theme,
WidthFitFlex,
} from '@duri-fe/ui';
-import { UseGetPorfolioDetail } from '@duri-fe/utils';
+import {
+ useDeletePortfolio,
+ UseGetPorfolioDetail,
+ useModal,
+} from '@duri-fe/utils';
import styled from '@emotion/styled';
export const GroomerPortfolioDetail = ({
feedbackId,
+ groomer = false,
}: {
feedbackId: number;
+ groomer?: boolean;
}) => {
const navigate = useNavigate();
+ const { isOpenModal, toggleModal } = useModal();
const { data } = UseGetPorfolioDetail({
feedbackId: feedbackId,
});
+ const { mutateAsync: deletePortfolio } = useDeletePortfolio();
+
+ const [menuOpen, setMenuOpen] = useState(false); // MenuWrapper 상태
+ const menuRef = useRef(null); // MenuWrapper의 ref
+
+ const handleClickMenu = () => {
+ setMenuOpen(!menuOpen);
+ };
+
+ const handleClickModifyButton = () => {
+ // navigate('/portfolio/modify', { state: feedbackId });
+ };
+
+ const handleClickDeleteConfirmButton = () => {
+ deletePortfolio(feedbackId);
+ };
+
return (
data && (
<>
@@ -39,10 +69,10 @@ export const GroomerPortfolioDetail = ({
{/** 피드백 및 후기 */}
-
-
+
+
- {data.groomerInfo.name}
- {/*
- 2024-12-25
- */}
+ {/* 미용사 포폴용 - 수정삭제를 선택 할 수 있는 메뉴 노출 */}
+ {groomer ? (
+ <>
+
+
+ {data.feedbackDate}
+
+
+
+
+
+ {menuOpen && (
+
+
+
+
+ )}
+ >
+ ) : (
+
+ {data.feedbackDate}
+
+ )}
@@ -115,7 +175,47 @@ export const GroomerPortfolioDetail = ({
padding="12px"
/>
-
+
+
+
+
+ 포트폴리오 본문을
+ 삭제하시겠습니까?
+
+
+
+ 삭제 후엔 복구할 수 없습니다.
+
+
+ 신중히 선택해주세요!
+
+
+
+
+ 아니오
+
+
+ 네
+
+
+
>
)
);
@@ -162,3 +262,30 @@ const PetInfoCard = styled(Card)`
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
background-color: ${theme.palette.Gray_White};
`;
+
+const MenuWrapper = styled(WidthFitFlex)`
+ cursor: pointer;
+`;
+
+const MenuCard = styled(Flex)`
+ position: absolute;
+ top: 37.4px;
+ right: 9px;
+ background-color: ${theme.palette.White};
+ box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.1);
+ z-index: 10;
+`;
+
+const MenuItem = styled.div`
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ cursor: pointer;
+ /* padding: 0 10px; // 좌우 여백을 추가하여 텍스트가 너무 붙지 않도록 조정 */
+ &:hover {
+ background-color: ${theme.palette.Gray_White};
+ border-radius: 8px;
+ }
+ z-index: 10;
+`;
diff --git a/packages/ui/src/components/Portfolio/PortfolioPhotos.tsx b/packages/ui/src/components/Portfolio/PortfolioPhotos.tsx
index a8d986e8..59e00361 100644
--- a/packages/ui/src/components/Portfolio/PortfolioPhotos.tsx
+++ b/packages/ui/src/components/Portfolio/PortfolioPhotos.tsx
@@ -1,6 +1,6 @@
import { useNavigate } from 'react-router-dom';
-import { Flex, Text } from '@duri-fe/ui';
+import { Flex, Text, theme } from '@duri-fe/ui';
import { UseGetGroomerPorfolio } from '@duri-fe/utils';
import styled from '@emotion/styled';
@@ -33,8 +33,8 @@ export const PortfolioPhotos = ({ groomerId }: PortfolioPhotosProps) => {
))}
) : (
-
- 아직 등록된 포트폴리오가 없어요.
+
+ 아직 등록된 포트폴리오가 없어요.
)}
diff --git a/packages/ui/src/components/ShopInfo/ShopInfo.tsx b/packages/ui/src/components/ShopInfo/ShopInfo.tsx
index e42ac674..2fda931a 100644
--- a/packages/ui/src/components/ShopInfo/ShopInfo.tsx
+++ b/packages/ui/src/components/ShopInfo/ShopInfo.tsx
@@ -46,7 +46,8 @@ export const ShopInfo = ({
onClick,
themeVariant,
}: ShopInfoProps) => {
- const { imageSize, typo, gap, padding, backgroundColor } = ShopInfoTheme[themeVariant];
+ const { imageSize, typo, gap, padding, backgroundColor } =
+ ShopInfoTheme[themeVariant];
return (
{title && {title}}
-
+
{address}
-
-
-
-
-
+ {(shopTag1 || shopTag2 || shopTag3) && (
+
+ {shopTag1 && }
+ {shopTag2 && }
+ {shopTag3 && }
+
+ )}
@@ -112,5 +115,5 @@ const FlexButton = styled(Flex)`
`;
const ShadowImage = styled(Image)`
- box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.10);
-`
\ No newline at end of file
+ box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.1);
+`;
diff --git a/packages/ui/vite.config.ts b/packages/ui/vite.config.ts
index fabde1a8..d348c4c3 100644
--- a/packages/ui/vite.config.ts
+++ b/packages/ui/vite.config.ts
@@ -3,4 +3,7 @@ import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react()],
+ resolve: {
+ alias: [{ find: '@assets', replacement: '/src/assets' }],
+ },
});
diff --git a/packages/utils/src/apis/duri/hooks/quotation.ts b/packages/utils/src/apis/duri/hooks/quotation.ts
index 2a9e7411..e529cea0 100644
--- a/packages/utils/src/apis/duri/hooks/quotation.ts
+++ b/packages/utils/src/apis/duri/hooks/quotation.ts
@@ -1,5 +1,7 @@
import { useQuery } from '@tanstack/react-query';
+import { BaseError, RequestDetailResponse } from '../../types';
+import { UseQueryProps } from '../../types/tanstack';
import { getDetailRequestQuotaion, getQuotationList } from '../quotation';
import { getRequestItems } from './../quotation';
@@ -13,11 +15,24 @@ export const useGetRequestItems = () => {
return data;
};
-export const useGetDetailRequestQuotation = (requestId: number) => {
+type UseGetDetailRequestQuotation = UseQueryProps<
+ RequestDetailResponse['response'],
+ BaseError
+> & {
+ requestId: number;
+};
+
+// 견적서 매장 순위 조회용
+export const useGetDetailRequestQuotation = ({
+ queryKey,
+ requestId,
+ options,
+}: UseGetDetailRequestQuotation) => {
return useQuery({
- queryKey: ['getRequestDetailInfo'],
+ queryKey: ['getRequestDetailInfo', requestId, ...(queryKey || [])],
queryFn: () => getDetailRequestQuotaion(requestId),
- staleTime: 1000 * 60 * 10,
+ staleTime: 1000 * 60 * 0, //항상 최신상태!!
+ ...options,
});
};
diff --git a/packages/utils/src/apis/duri/portfolio.ts b/packages/utils/src/apis/duri/portfolio.ts
index b2bd3436..397955eb 100644
--- a/packages/utils/src/apis/duri/portfolio.ts
+++ b/packages/utils/src/apis/duri/portfolio.ts
@@ -21,5 +21,6 @@ export const getPortfolioDetail = async ({
const { data } = await publicInstance.get(`/feedback/detail/${feedbackId}`, {
params: { feedbackId },
});
+ console.log(data);
return data.response;
};
diff --git a/packages/utils/src/apis/salon/home.ts b/packages/utils/src/apis/salon/home.ts
index 11825348..e53eb4b6 100644
--- a/packages/utils/src/apis/salon/home.ts
+++ b/packages/utils/src/apis/salon/home.ts
@@ -1,6 +1,7 @@
import {
ClosetGroomingResponse,
DailyScheduleResponse,
+ GroomersListProfileResponse,
HomeQuotationRequestResponse,
HomeShopInfoResponse,
salonInstance,
@@ -59,3 +60,11 @@ export const putGroomingNoshow = async (quotationId: number) => {
);
return response.data.response;
};
+
+//미용사 id 조회
+export const getGroomersProfileList = async (): Promise<
+GroomersListProfileResponse['response']
+> => {
+ const { data } = await salonInstance.get('/shop/groomers');
+ return data.response;
+};
diff --git a/packages/utils/src/apis/salon/hooks/home.ts b/packages/utils/src/apis/salon/hooks/home.ts
index 4a5462ed..b137e42c 100644
--- a/packages/utils/src/apis/salon/hooks/home.ts
+++ b/packages/utils/src/apis/salon/hooks/home.ts
@@ -2,8 +2,10 @@ import {
BaseError,
getClosetGrooming,
getDailySchedule,
+ getGroomersProfileList,
getHomeQuotationRequest,
getHomeShopInfo,
+ GroomersListProfileResponse,
HomeShopInfoResponse,
putGroomingComplete,
PutGroomingCompleteResponse,
@@ -83,3 +85,20 @@ export const usePutGroomingNoshow = (): UseMutationResult<
mutationFn: (quotationId: number) => putGroomingNoshow(quotationId),
});
};
+
+type UseGetGroomerProfile = UseQueryProps<
+ GroomersListProfileResponse['response'],
+ BaseError
+>;
+
+export const useGetGroomersList = ({
+ queryKey,
+ options,
+}: UseGetGroomerProfile) => {
+ return useQuery({
+ queryKey: ['getPortfolioDetail', ...(queryKey || [])],
+ queryFn: () => getGroomersProfileList(),
+ staleTime: 1000 * 60 * 5,
+ ...options,
+ });
+};
diff --git a/packages/utils/src/apis/salon/hooks/index.ts b/packages/utils/src/apis/salon/hooks/index.ts
index 46bd6c78..5cc3de67 100644
--- a/packages/utils/src/apis/salon/hooks/index.ts
+++ b/packages/utils/src/apis/salon/hooks/index.ts
@@ -4,3 +4,4 @@ export * from './request';
export * from './quotation';
export * from './onboarding';
export * from './my';
+export * from './portfolio';
\ No newline at end of file
diff --git a/packages/utils/src/apis/salon/hooks/my.ts b/packages/utils/src/apis/salon/hooks/my.ts
index 209cd08e..129eb5bc 100644
--- a/packages/utils/src/apis/salon/hooks/my.ts
+++ b/packages/utils/src/apis/salon/hooks/my.ts
@@ -1,12 +1,12 @@
import { useQuery } from '@tanstack/react-query';
import { BaseError } from '../../types';
-import { GroomerInfoResponse } from '../../types/my';
+import { GroomerAndShopProfileResponse } from '../../types/my';
import { UseQueryProps } from '../../types/tanstack';
import { getGroomerInfo } from '../my';
type UseGetGroomerInfo = UseQueryProps<
- GroomerInfoResponse['response'],
+GroomerAndShopProfileResponse['response'],
BaseError
> & {
groomerId: number;
diff --git a/packages/utils/src/apis/salon/hooks/portfolio.ts b/packages/utils/src/apis/salon/hooks/portfolio.ts
new file mode 100644
index 00000000..bf27b6e0
--- /dev/null
+++ b/packages/utils/src/apis/salon/hooks/portfolio.ts
@@ -0,0 +1,16 @@
+import { useMutation } from '@tanstack/react-query';
+
+import { deletePortfolio } from '../portfolio';
+
+export const useDeletePortfolio = () => {
+ return useMutation({
+ mutationKey: ['deletePortfolio'],
+ mutationFn: (feedbackId: number) => deletePortfolio(feedbackId),
+ onSuccess: () => {
+ window.location.href = '/portfolio';
+ },
+ onError: (error) => {
+ console.error(error);
+ },
+ });
+};
diff --git a/packages/utils/src/apis/salon/index.ts b/packages/utils/src/apis/salon/index.ts
index 12579d72..040a68d8 100644
--- a/packages/utils/src/apis/salon/index.ts
+++ b/packages/utils/src/apis/salon/index.ts
@@ -5,3 +5,4 @@ export * from './request';
export * from './quotation';
export * from './onboarding';
export * from './my';
+export * from './portfolio';
\ No newline at end of file
diff --git a/packages/utils/src/apis/salon/my.ts b/packages/utils/src/apis/salon/my.ts
index 582d782f..104dfd7f 100644
--- a/packages/utils/src/apis/salon/my.ts
+++ b/packages/utils/src/apis/salon/my.ts
@@ -1,12 +1,12 @@
import { publicInstance } from '@duri-fe/utils';
-import { GroomerInfoResponse } from '../types/my';
+import { GroomerAndShopProfileResponse } from '../types/my';
export const getGroomerInfo = async ({
groomerId,
}: {
groomerId: number;
-}): Promise => {
+}): Promise => {
const { data } = await publicInstance.get(`/groomer/profile/${groomerId}`, {
params: { groomerId },
});
diff --git a/packages/utils/src/apis/salon/portfolio.ts b/packages/utils/src/apis/salon/portfolio.ts
new file mode 100644
index 00000000..3fd58ca0
--- /dev/null
+++ b/packages/utils/src/apis/salon/portfolio.ts
@@ -0,0 +1,9 @@
+import { salonInstance } from '../config';
+import { PutDeletePortfolioResponse } from '../types/portfolio';
+
+export const deletePortfolio = async (
+ feedbackId: number,
+): Promise => {
+ const { data } = await salonInstance.put(`/feedback/remove/${feedbackId}`);
+ return data;
+};
diff --git a/packages/utils/src/apis/types/home.ts b/packages/utils/src/apis/types/home.ts
index 8e583661..4366b0fa 100644
--- a/packages/utils/src/apis/types/home.ts
+++ b/packages/utils/src/apis/types/home.ts
@@ -1,4 +1,5 @@
import { BaseResponse } from './base';
+import { GroomerInfoType } from './my';
export interface ClosetGroomingResponse extends BaseResponse {
response: {
@@ -116,3 +117,8 @@ export interface HomeShopInfoResponse extends BaseResponse {
phone: string;
};
}
+
+//미용사 GroomersList 프로필 조회 응답
+export interface GroomersListProfileResponse extends BaseResponse {
+ response: GroomerInfoType[];
+}
\ No newline at end of file
diff --git a/packages/utils/src/apis/types/my.ts b/packages/utils/src/apis/types/my.ts
index 76a02117..d71fa591 100644
--- a/packages/utils/src/apis/types/my.ts
+++ b/packages/utils/src/apis/types/my.ts
@@ -114,7 +114,7 @@ export interface VisitHistoryResponse {
}[];
}
-/** 그루머 아이디로 그루머 인포 조회 시 사용 */
+/** 그루머 아이디로 그루머 인포 조회 시 사용 & 포트폴리오 조회를 위해 id 얻으려고 사용 */
export interface GroomerInfoType {
id: number;
email: string;
@@ -128,6 +128,22 @@ export interface GroomerInfoType {
license: string[];
}
-export interface GroomerInfoResponse extends BaseResponse {
- response: GroomerInfoType;
+export interface ShopInfoType {
+ id: 0;
+ name: string;
+ address: string;
+ imageURL: string;
+ phone: string;
+ openTime: string;
+ closeTime: string;
+ info: string;
+ kakaoTalk: string;
+ tags: string[];
+}
+
+export interface GroomerAndShopProfileResponse extends BaseResponse {
+ response: {
+ groomerProfileDetail: GroomerInfoType;
+ shopProfileDetail: ShopInfoType;
+ };
}
diff --git a/packages/utils/src/apis/types/portfolio.ts b/packages/utils/src/apis/types/portfolio.ts
index 4058ca33..939ebe93 100644
--- a/packages/utils/src/apis/types/portfolio.ts
+++ b/packages/utils/src/apis/types/portfolio.ts
@@ -1,5 +1,20 @@
import { BaseResponse } from './base';
+export interface GroomerProfileInfo extends BaseResponse {
+ response: {
+ id: number;
+ email: string;
+ phone: string;
+ name: string;
+ gender: string;
+ age: number;
+ history: number;
+ image: string;
+ info: string;
+ license: string[];
+ }[];
+}
+
export interface PortfolioType {
feedbackId: number;
imageUrl: string;
@@ -34,8 +49,14 @@ export interface PortfolioDetailType {
feedbackImages: string[];
petInfo: PortfolioPetInfo;
groomerInfo: PortfolioGroomerInfo;
+ feedbackDate: string;
}
export interface PorfolioDetailResponse extends BaseResponse {
response: PortfolioDetailType;
}
+
+//삭제 수정용 response
+export interface PutDeletePortfolioResponse extends BaseResponse {
+ response: string;
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index d58f43f2..7af7f25e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -561,6 +561,7 @@ __metadata:
react-toastify: "npm:^10.0.6"
typescript: "npm:5.5.4"
vite: "npm:^5.1.4"
+ zustand: "npm:^5.0.2"
languageName: unknown
linkType: soft