diff --git a/apps/duri/index.html b/apps/duri/index.html index 0f5dcee4..51e8fa0e 100644 --- a/apps/duri/index.html +++ b/apps/duri/index.html @@ -9,6 +9,12 @@ crossorigin="anonymous" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.6/dist/web/static/pretendard-dynamic-subset.css" /> + 두리묭실 diff --git a/apps/duri/package.json b/apps/duri/package.json index 5906899d..622a95e8 100644 --- a/apps/duri/package.json +++ b/apps/duri/package.json @@ -17,6 +17,7 @@ "@emotion/react": "^11.13.5", "@emotion/styled": "^11.13.5", "@tanstack/react-query": "^5.62.0", + "@tanstack/react-query-devtools": "^5.62.2", "@tosspayments/tosspayments-sdk": "^2.3.2", "@types/node": "^22.10.1", "@typescript-eslint/eslint-plugin": "^8.15.0", diff --git a/apps/duri/src/App.tsx b/apps/duri/src/App.tsx index d721a741..27f7d055 100644 --- a/apps/duri/src/App.tsx +++ b/apps/duri/src/App.tsx @@ -15,13 +15,15 @@ import QuotationPage from '@pages/Quotation'; import RequestPage from '@pages/Request'; import Shop from '@pages/Shop'; +import Portfolio from './pages/Shop/Portfolio'; +import ShopDetail from './pages/Shop/ShopDetail'; + function App() { return ( } /> - } /> } /> @@ -33,6 +35,8 @@ function App() { } /> } /> } /> + } /> + } /> } /> diff --git a/apps/duri/src/assets/types/shop.ts b/apps/duri/src/assets/types/shop.ts index 6d541c21..acd1c3af 100644 --- a/apps/duri/src/assets/types/shop.ts +++ b/apps/duri/src/assets/types/shop.ts @@ -1,12 +1,12 @@ export interface RegularShopProps { salonIdx: string; - salonName:string; + salonName: string; salonImage: string; salonScore?: number; salonReviewCount?: number; } -export interface RecommendeShopProps extends RegularShopProps{ +export interface RecommendeShopProps extends RegularShopProps { salonAddress: string; salonTag: string[]; -} \ No newline at end of file +} diff --git a/apps/duri/src/components/onboarding/PetPersonalityInfo.tsx b/apps/duri/src/components/onboarding/PetPersonalityInfo.tsx index c4c8fae3..49eaedc5 100644 --- a/apps/duri/src/components/onboarding/PetPersonalityInfo.tsx +++ b/apps/duri/src/components/onboarding/PetPersonalityInfo.tsx @@ -47,7 +47,11 @@ const PetPersonalityInfo = ({ {name}는
어떤 성격을 가지고 있나요? - + 입력된 성격은 MY에서 변경가능해요. 0 || '성격에 대해 알려주세요.', }} render={() => ( - + {personalityOptions.map((value) => ( + + {phone} + + + + {tags.map((tag, idx) => ( + + ))} + + - - {phone} - - - - - - - - - ); }; @@ -108,3 +123,7 @@ const MarkText = styled.span` const TextLine = styled(Text)` display: inline; `; + +const TagList = styled(Flex)` + flex-wrap: wrap; +`; diff --git a/apps/duri/src/components/shop/ShopList.tsx b/apps/duri/src/components/shop/ShopList.tsx index 65150974..96bd09ba 100644 --- a/apps/duri/src/components/shop/ShopList.tsx +++ b/apps/duri/src/components/shop/ShopList.tsx @@ -1,5 +1,5 @@ -import { forwardRef, useState } from 'react'; -import { BottomSheet, BottomSheetRef } from 'react-spring-bottom-sheet'; +import { useState } from 'react'; +import { BottomSheet } from 'react-spring-bottom-sheet'; import { Button, @@ -14,20 +14,27 @@ import { theme, WidthFitFlex, } from '@duri-fe/ui'; -import { css } from '@emotion/react'; +import { ShopInfoType, useBottomSheet } from '@duri-fe/utils'; import styled from '@emotion/styled'; import 'react-spring-bottom-sheet/dist/style.css'; import { ShopLine } from './ShopLine'; -export const ShopList = forwardRef((_, ref) => { - const [open, setOpen] = useState(false); - const [filter, setFilter] = useState<'거리순' | '별점순'>('거리순'); - - const handleDismiss = () => { - setOpen(false); - }; +interface ShopListProps { + nearbyShops: ShopInfoType[] | null; + filter: 'distance' | 'rating'; + onFilterChange: (filter: 'distance' | 'rating') => void; +} + +export const ShopList = ({ + nearbyShops, + filter, + onFilterChange, +}: ShopListProps) => { + const { openSheet, bottomSheetProps } = useBottomSheet({ + maxHeight: 260, + }); // 선택된 가게 취합용 const [selectedShops, setSelectedShops] = useState([]); @@ -54,7 +61,7 @@ export const ShopList = forwardRef((_, ref) => { borderRadius="99px" padding="10px" shadow={'0px 0px 4px 0px rgba(0, 0, 0, 0.25)'} - onClick={() => setOpen(true)} + onClick={openSheet} > ((_, ref) => { disabled={true} > - {filter} + {filter == 'distance' ? '거리순' : '별점순'} @@ -106,50 +113,22 @@ export const ShopList = forwardRef((_, ref) => { : '17px 20px 28px 20px' } > - toggleShopSelection(1)} - /> - toggleShopSelection(2)} - /> - toggleShopSelection(3)} - /> - toggleShopSelection(4)} - /> + {/** 각 가게 정보 박스*/} + {nearbyShops?.map((shop) => ( + toggleShopSelection(shop.shopId)} + tags={shop.tags} + /> + ))} {selectedShops.length > 0 ? ( @@ -166,14 +145,7 @@ export const ShopList = forwardRef((_, ref) => { ) : null} - [maxHeight]} - onDismiss={handleDismiss} - > + ((_, ref) => { bg="transparent" width="fit-content" padding="0" - onClick={() => setFilter('거리순')} + onClick={() => onFilterChange('distance')} > ((_, ref) => { bg="transparent" width="fit-content" padding="0" - onClick={() => setFilter('별점순')} + onClick={() => onFilterChange('rating')} > ((_, ref) => { ); -}); - -ShopList.displayName = 'ShopList'; +}; const ScrollFlex = styled(Flex)` height: calc(100vh - 274.5px); @@ -242,22 +212,3 @@ const ScrollFlex = styled(Flex)` scrollbar-width: none; } `; - -const StyledBottomCss = css` - position: relative; - - [data-rsbs-overlay], - [data-rsbs-root]::after { - border-radius: 16px 16px 0px 0px; - z-index: 20; - max-width: 480px; - - @media (min-width: 480px) { - left: calc(50% - 240px); - } - } - - [data-rsbs-backdrop] { - background-color: rgba(49, 48, 54, 0.5); - } -`; diff --git a/apps/duri/src/components/shop/ShopPhotos.tsx b/apps/duri/src/components/shop/ShopPhotos.tsx new file mode 100644 index 00000000..4b859876 --- /dev/null +++ b/apps/duri/src/components/shop/ShopPhotos.tsx @@ -0,0 +1,36 @@ +import { Flex } from '@duri-fe/ui'; +import styled from '@emotion/styled'; + +export const ShopPhotos = () => { + const images = [ + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + 'https://s3-alpha-sig.figma.com/img/1d85/dbcb/8d458ee15d53bb800b97c0da776b2909?Expires=1734307200&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=bsJT2VGq6a~lRLJF9PaZBN8uBPvTrzvaZdf0vOPJfoNQ~-z7jq6hxODfjPytoebWbo2qilv6nihm3zGBKeZykT2HzA58as4Xcx0QJ26~1l6GlWr1JSmQNG2jiPDOnuzF5QYjik52HzOuB1y85zBkGKb-U1XiwOisvaSIthgJkLyZ74vG3bmO3a-VJCeFR0atgacdxDzGf6uoiX163aYu6X3R0sJ5Ux6ZpOHuWj6npG9I-eGlQeHZJmkODmqjhfjLyrmuUBilvH15pR0CkhAxwraIvSHx4qb3RK6o1K79sDldRPDQ6LaAu7fR-WmExifV~KFGVsSTiIwJOofVLqHHGQ__', + ]; + + return ( + + + {images.map((src, index) => ( + + ))} + + + ); +}; + +const PhotoGrid = styled.div` + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 7px; +`; + +const ShopInsideImg = styled.img` + width: 107px; + height: 107px; + border-radius: 4px; + object-fit: cover; +`; diff --git a/apps/duri/src/components/shop/index.tsx b/apps/duri/src/components/shop/index.tsx index f178c2f3..e4431002 100644 --- a/apps/duri/src/components/shop/index.tsx +++ b/apps/duri/src/components/shop/index.tsx @@ -1,3 +1,5 @@ export { MapInfo } from './MapInfo'; export { ShopList } from './ShopList'; export { ShopLine } from './ShopLine'; +export { ShopInfo } from './ShopInfo'; +export { DesignerInfo } from './DesignerInfo'; diff --git a/apps/duri/src/main.tsx b/apps/duri/src/main.tsx index 907745c9..43ebf68f 100644 --- a/apps/duri/src/main.tsx +++ b/apps/duri/src/main.tsx @@ -1,19 +1,18 @@ import { createRoot } from 'react-dom/client'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; -// import { worker } from './mocks/browser'; import App from './App'; import { enableMocking } from './mocks'; -// const rootElement = document.getElementById('app'); const queryClient = new QueryClient(); enableMocking().then(() => { createRoot(document.getElementById('app')!).render( - {/* */} + , ); }); diff --git a/apps/duri/src/mocks/handler.ts b/apps/duri/src/mocks/handler.ts index aa2e4934..0b29aaca 100644 --- a/apps/duri/src/mocks/handler.ts +++ b/apps/duri/src/mocks/handler.ts @@ -82,17 +82,16 @@ export const handlers = [ }), http.get('https://api.example.com/api/v1/pet', () => { - return HttpResponse.json( - { - petId:1, - petName: "멍이", - petImage: 'https://s3-alpha-sig.figma.com/img/be2d/15b9/6d6d9c56fd4e47388fa79cdfb8f3c4b6?Expires=1733702400&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=X1cOpSTMbxxMWxuaqTEsv4id96BVzSloxASEzxOzX87IO8neIKfYCuO8K04E5O8RniSoRCRo7JIlyuYn0AZd6Nda2W7tS8rN36WT7Ewzg-bnozvaUzH5Low6mzAGqUFhQY558k~oAoKolnCTzLEb1DSKR3Zq3Gj073fUrLrxyNnQmXqtbmMObX39c-Flw0~8kzap-ls787b58MKEnfTQ1AVHB8o-Y2~2mQWpFCMY8iKMjIsk84ToA0LhLmiGf5XkRLEtZwwWXFqsTXm0OFB2m~3uqsxFBkuW3gootLBj2ocEp400Za4j8C-IAFj1lNqPeoW9rpLdKLh0xOvoftqeaQ__', - breed: "시츄", - gender: "여아", - age: "7살", - weight: "1.4" - }, - ); + return HttpResponse.json({ + petId: 1, + petName: '멍이', + petImage: + 'https://s3-alpha-sig.figma.com/img/be2d/15b9/6d6d9c56fd4e47388fa79cdfb8f3c4b6?Expires=1733702400&Key-Pair-Id=APKAQ4GOSFWCVNEHN3O4&Signature=X1cOpSTMbxxMWxuaqTEsv4id96BVzSloxASEzxOzX87IO8neIKfYCuO8K04E5O8RniSoRCRo7JIlyuYn0AZd6Nda2W7tS8rN36WT7Ewzg-bnozvaUzH5Low6mzAGqUFhQY558k~oAoKolnCTzLEb1DSKR3Zq3Gj073fUrLrxyNnQmXqtbmMObX39c-Flw0~8kzap-ls787b58MKEnfTQ1AVHB8o-Y2~2mQWpFCMY8iKMjIsk84ToA0LhLmiGf5XkRLEtZwwWXFqsTXm0OFB2m~3uqsxFBkuW3gootLBj2ocEp400Za4j8C-IAFj1lNqPeoW9rpLdKLh0xOvoftqeaQ__', + breed: '시츄', + gender: '여아', + age: '7살', + weight: '1.4', + }); }), http.get('https://api.example.com/api/v1/reservation', () => { diff --git a/apps/duri/src/mocks/index.ts b/apps/duri/src/mocks/index.ts index e911fe12..15a807ca 100644 --- a/apps/duri/src/mocks/index.ts +++ b/apps/duri/src/mocks/index.ts @@ -1,10 +1,11 @@ export async function enableMocking() { - console.log(import.meta.env.VITE_MSW_ENABLED) - if (import.meta.env.VITE_MSW_ENABLED === 'true') { - const { worker } = await import('./browser'); - return await worker.start(); - } - else { - console.log('MSW is disabled'); - } - } \ No newline at end of file + console.log(import.meta.env.VITE_MSW_ENABLED); + if (import.meta.env.VITE_MSW_ENABLED === 'true') { + const { worker } = await import('./browser'); + return await worker.start({ + onUnhandledRequest: 'bypass', + }); + } else { + console.log('MSW is disabled'); + } +} diff --git a/apps/duri/src/pages/Shop/Portfolio.tsx b/apps/duri/src/pages/Shop/Portfolio.tsx new file mode 100644 index 00000000..e6ea87d2 --- /dev/null +++ b/apps/duri/src/pages/Shop/Portfolio.tsx @@ -0,0 +1,60 @@ +import { useState } from 'react'; + +import { + AbsoluteFlex, + FilledHeart, + Heart, + HeightFitFlex, + MobileLayout, + RelativeFlex, + Text, + theme, + WidthFitFlex, +} from '@duri-fe/ui'; +import styled from '@emotion/styled'; + +const Portfolio = () => { + const [isMarked, setIsMarked] = useState(false); + + return ( + + + + + + 댕댕샵 + setIsMarked(!isMarked)} + > + {isMarked ? ( + + ) : ( + + )} + + + + 경기도 성남시 불정로 119 + + + + ); +}; + +export default Portfolio; + +const MainImg = styled.img` + width: 100%; + position: relative; + aspect-ratio: 375 / 310; + object-fit: cover; +`; + +const Gradation = styled.div` + background: linear-gradient(180deg, rgba(217, 217, 217, 0) 0%, #111 100%); +`; diff --git a/apps/duri/src/pages/Shop/ShopDetail.tsx b/apps/duri/src/pages/Shop/ShopDetail.tsx new file mode 100644 index 00000000..77316508 --- /dev/null +++ b/apps/duri/src/pages/Shop/ShopDetail.tsx @@ -0,0 +1,16 @@ +// import { useParams } from 'react-router-dom'; + +import { ShopInfo } from '@duri/components/shop'; +import { DuriNavbar, MobileLayout } from '@duri-fe/ui'; + +const ShopDetail = () => { + // const { shopId } = useParams<{ shopId: string }>(); + return ( + + + + + ); +}; + +export default ShopDetail; diff --git a/apps/duri/src/pages/Shop/index.tsx b/apps/duri/src/pages/Shop/index.tsx index 7acc8005..b74bb175 100644 --- a/apps/duri/src/pages/Shop/index.tsx +++ b/apps/duri/src/pages/Shop/index.tsx @@ -1,5 +1,4 @@ -import { useRef, useState } from 'react'; -import { BottomSheetRef } from 'react-spring-bottom-sheet'; +import { useEffect, useRef, useState } from 'react'; import { MapInfo } from '@duri/components/shop'; import { ShopList } from '@duri/components/shop/ShopList'; @@ -15,18 +14,47 @@ import { TextField, theme, } from '@duri-fe/ui'; +import { ShopInfoType, useGetNearByShopInfo } from '@duri-fe/utils'; import styled from '@emotion/styled'; const Shop = () => { const mapRef = useRef(null); - const sheetRef = useRef(null); const [isMap, setIsMap] = useState(true); + const [nearbyShops, setNearbyShops] = useState([]); const changeMapType = () => { setIsMap(!isMap); }; + const [filter, setFilter] = useState<'distance' | 'rating'>('distance'); + const handleFilterChange = (filter: 'distance' | 'rating') => { + if (filter) { + setFilter(filter); + } + }; + + const { data } = useGetNearByShopInfo( + // location.coordinates + // ? { + // // lat: location.coordinates.lat, + // // long: location.coordinates.lng, + // // radius: 500, + // lat: 37.5156, + // lon: 127.0451005, + // radius: 500, + // } + // : + { lat: 37.5156, lon: 127.0451005, radius: 500 }, + filter, + ); + + useEffect(() => { + if (data) { + setNearbyShops(data); + } + }, [data]); + return ( @@ -51,7 +79,11 @@ const Shop = () => { ) : ( - + )}