Skip to content

Commit

Permalink
faet #18 등록 폼 확인 페이지 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
lee7198 committed Feb 18, 2024
1 parent 289097b commit 344ea9a
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 112 deletions.
5 changes: 5 additions & 0 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import InitAgreement from './pages/Auth/components/Init/components/initAgreement
import ServiceAgreement from './pages/Auth/components/Init/components/ServiceAgreement';
import PrivacyAgreement from './pages/Auth/components/Init/components/PrivacyAgreement';
import MarketingAgreement from './pages/Auth/components/Init/components/MarketingAgreement';
import Confirm from './pages/Register/components/Confirm';

export default function Router() {
// recoil state로 access roles 관리
Expand Down Expand Up @@ -142,6 +143,10 @@ export default function Router() {
path: 'notice',
element: <Notice />,
},
{
path: 'confirm',
element: <Confirm />,
},
],
},
// 마이페이지
Expand Down
13 changes: 6 additions & 7 deletions src/pages/Goods/components/CarouselBox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,22 @@ import { Pagination } from 'swiper/modules';
import 'swiper/css';
import 'swiper/css/pagination';
import './index.css';
import { GoodsPageDTO } from '@src/types/goods';

export default function CarouselBox({ data }: { data: GoodsPageDTO }) {
if (!data || !data.goodsImagesList)
export default function CarouselBox({ images }: { images: string[] }) {
if (images.length === 0)
return <div className="aspect-square w-full animate-pulse bg-gray-300" />;

return (
<Swiper
pagination
modules={[Pagination]}
loop
className="flex aspect-square w-full items-center justify-center"
className="flex aspect-square w-full items-center justify-center bg-zinc-300"
>
{data.goodsImagesList.map((item, i) => (
<SwiperSlide key={item.goodsImgUrl}>
{images.map((item) => (
<SwiperSlide key={item}>
<img
src={item.goodsImgUrl}
src={item || undefined}
className="aspect-square w-full object-cover"
alt="상품 이미지"
/>
Expand Down
36 changes: 24 additions & 12 deletions src/pages/Goods/components/HeaderProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { GoodsPageDTO } from '@src/types/goods';
import Avatar from 'boring-avatars';
import { differenceInDays } from 'date-fns';

export default function HeaderProfile({
data,
goodsLimitTime,
goodsName,
sellerNickname,
sellCount,
}: {
data: GoodsPageDTO | undefined;
goodsLimitTime?: string;
goodsName?: string;
sellerNickname?: string;
sellCount?: number;
}) {
const today = new Date();

Expand All @@ -18,33 +23,33 @@ export default function HeaderProfile({
return (
<div
className={`mb-3 mt-8 flex flex-col gap-3 ${
!data ? 'animate-pulse' : ''
!goodsName ? 'animate-pulse' : ''
}`}
>
{/* 상품 제목 등 */}
<div className="flex items-center gap-2">
<div className="w16 rounded-2xl bg-gray-100 px-2 py-1 text-center text-sm text-gray-700">
{`D-${data ? getdDay(data.goodsLimitTime) : ''}`}
<div className="w-16 rounded-2xl bg-gray-100 px-2 py-1 text-center text-sm text-gray-700">
{`D-${goodsLimitTime ? getdDay(goodsLimitTime) : ''}`}
</div>
{data ? (
<div className="font-bold">{data.goodsName}</div>
{goodsName ? (
<div className="font-bold">{goodsName}</div>
) : (
<div className="h-4 w-full rounded bg-gray-200" />
)}
</div>

{/* 작성자 정보 */}
<div className="flex items-center gap-3 border-b border-gray-300 pb-[20px]">
{data ? (
{sellCount ? (
<Avatar variant="beam" />
) : (
<div className="size-10 shrink-0 rounded-full bg-gray-200" />
)}
{data ? (
{sellerNickname ? (
<div>
{data.sellerInfoDto.sellerNickname}{' '}
{sellerNickname}{' '}
<span className="text-zinc-400">
| {data.sellerInfoDto.sellCount}
| {sellCount}
번째 구매 리드
</span>
</div>
Expand All @@ -55,3 +60,10 @@ export default function HeaderProfile({
</div>
);
}

HeaderProfile.defaultProps = {
goodsLimitTime: undefined,
goodsName: undefined,
sellerNickname: undefined,
sellCount: undefined,
};
29 changes: 18 additions & 11 deletions src/pages/Goods/components/PlaceInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { useState } from 'react';
import { useQuery } from 'react-query';
import { GoodsPageDTO } from '@src/types/goods';
import { Address } from '@src/types/goods';
import { PositionType } from '@src/types/map';
import IntroStaticMap from '@src/components/MarkerOnStaticMap';

export default function PlaceInfo({
data,
coordinate,
image,
}: {
data: GoodsPageDTO | undefined;
coordinate?: Address;
image?: string;
}) {
const { kakao } = window;
const [address, setAddress] = useState('-');
Expand All @@ -28,9 +30,9 @@ export default function PlaceInfo({
'revGeoCoder',
() =>
getAddress(
data && {
lat: data.address.mapY,
lng: data.address.mapX,
coordinate && {
lat: coordinate.latitude,
lng: coordinate.longitude,
}
),
{ retryDelay: 500, retry: 3 }
Expand All @@ -40,16 +42,16 @@ export default function PlaceInfo({
<div className="flex flex-col gap-4 rounded-xl bg-gray-50 p-4">
<div className="relative aspect-[1.9197] w-full rounded-xl bg-gray-300">
<IntroStaticMap
img={data?.goodsImagesList[0].goodsImgUrl}
img={image || undefined}
position={
data && {
lat: data.address.mapY,
lng: data.address.mapX,
coordinate && {
lat: coordinate.latitude,
lng: coordinate.longitude,
}
}
/>
</div>
{data ? (
{address ? (
<div className="text-center ">
<span className="mr-2 text-sm font-light text-gray-600">
픽업 예정 장소 :
Expand All @@ -62,3 +64,8 @@ export default function PlaceInfo({
</div>
);
}

PlaceInfo.defaultProps = {
coordinate: undefined,
image: undefined,
};
16 changes: 9 additions & 7 deletions src/pages/Goods/components/ProductContent.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { GoodsPageDTO } from '@src/types/goods';

export default function ProductContent({
data,
introduction,
}: {
data: GoodsPageDTO | undefined;
introduction?: string;
}) {
return (
<div
className={`flex flex-col gap-2 border-b border-gray-300 py-8 ${
!data ? 'animate-pulse' : ''
!introduction ? 'animate-pulse' : ''
}`}
>
{data ? (
<div>{data.introduction}</div>
{introduction ? (
<div>{introduction}</div>
) : (
<>
<div className="h-3 w-3/4 rounded bg-gray-300" />
Expand All @@ -23,3 +21,7 @@ export default function ProductContent({
</div>
);
}

ProductContent.defaultProps = {
introduction: undefined,
};
33 changes: 24 additions & 9 deletions src/pages/Goods/components/ProductInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,41 @@ import getOpenGraph from '../../../api/og';
import OpenGraphViewer from '../../../components/OpenGraphViewer';

export default function ProductInfo({
data,
// data,
deliveryFee,
realDeliveryFee,
link,
goodsPrice,
}: {
data: GoodsPageDTO | undefined;
// data: GoodsPageDTO | undefined;
deliveryFee?: number;
realDeliveryFee?: number;
link?: string;
goodsPrice?: number;
}) {
const openGraph = useQuery('introOpenGraph', () => getOpenGraph(data?.link), {
const openGraph = useQuery('introOpenGraph', () => getOpenGraph(link), {
retryDelay: 500,
});

let people = 0;
if (data) people = data.deliveryFee / data.realDeliveryFee;
if (deliveryFee && realDeliveryFee) people = deliveryFee / realDeliveryFee;

return (
<div
className={`flex flex-col gap-4 py-3 ${
!data && !openGraph.isSuccess ? 'animate-pulse' : ''
!deliveryFee && !openGraph.isSuccess ? 'animate-pulse' : ''
}`}
>
<div>상품정보</div>

<OpenGraphViewer openGraph={openGraph.data} link={data?.link as string} />
<OpenGraphViewer openGraph={openGraph.data} link={link as string} />
<div className="flex flex-col gap-2">
{data ? (
{goodsPrice && deliveryFee ? (
<>
<div>구매가: {data.goodsPrice.toLocaleString()}</div>
<div>구매가: {goodsPrice.toLocaleString()}</div>
<div>
<span>{`배송비:
${data.deliveryFee.toLocaleString()} / `}</span>
${deliveryFee.toLocaleString()} / `}</span>
<span className="text-yellow-400">{people}</span>
<span>명 분할 중</span>
</div>
Expand All @@ -47,3 +55,10 @@ export default function ProductInfo({
</div>
);
}

ProductInfo.defaultProps = {
deliveryFee: undefined,
realDeliveryFee: undefined,
link: undefined,
goodsPrice: undefined,
};
49 changes: 26 additions & 23 deletions src/pages/Goods/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useState } from 'react';
import { useNavigate, Outlet, useLocation, useParams } from 'react-router-dom';
import { useQuery } from 'react-query';
import { add } from 'date-fns';
import { getGoodsPage } from '@src/api/goods';
import { dateFormetter } from '@src/utils';
import CarouselBox from './components/CarouselBox';
import HeaderProfile from './components/HeaderProfile';
import ProductInfo from './components/ProductInfo';
Expand All @@ -15,25 +15,11 @@ export default function Goods() {
const { idx } = useParams();
const location = useLocation();
const navigate = useNavigate();
const [limitDate, setLimitDate] = useState('');

const isSubmitted = location.pathname.includes('submitted');

const dateFormetter = (param: string) => {
const date = add(new Date(param), { days: -1 });

return `${date.getMonth() + 1}${date.getDate()}일 23시 59분`;
};

const { data: goods, isSuccess } = useQuery(
'itemDetail',
() => getGoodsPage(idx as string),
{
onSuccess: (res) => {
setLimitDate(dateFormetter(res.goodsPageDto.goodsLimitTime));
},
// onError: () => navigate('/err'),
}
const { data: goods, isSuccess } = useQuery('itemDetail', () =>
getGoodsPage(idx as string)
);

return (
Expand All @@ -55,16 +41,30 @@ export default function Goods() {

{/* 상품 사진 */}
{isSuccess ? (
<CarouselBox data={goods.goodsPageDto} />
<CarouselBox
images={goods?.goodsPageDto.goodsImagesList.map(
(item) => item.goodsImgUrl
)}
/>
) : (
<div className="aspect-square w-full animate-pulse bg-gray-300" />
)}

{/* 상품 정보 */}
<section className="px-4">
<HeaderProfile data={goods?.goodsPageDto} />
<ProductInfo data={goods?.goodsPageDto} />
<ProductContent data={goods?.goodsPageDto} />
<HeaderProfile
goodsLimitTime={goods?.goodsPageDto.goodsLimitTime}
goodsName={goods?.goodsPageDto.goodsName}
sellerNickname={goods?.goodsPageDto.sellerInfoDto.sellerNickname}
sellCount={goods?.goodsPageDto.sellerInfoDto.sellCount}
/>
<ProductInfo
deliveryFee={goods?.goodsPageDto.deliveryFee}
realDeliveryFee={goods?.goodsPageDto.realDeliveryFee}
link={goods?.goodsPageDto.link}
goodsPrice={goods?.goodsPageDto.goodsPrice}
/>
<ProductContent introduction={goods?.goodsPageDto.introduction} />
</section>

<section className="px-4 pt-12 text-sm">
Expand All @@ -74,7 +74,10 @@ export default function Goods() {

<section className="flex flex-col gap-2">
{/* 상품 위치 정보 */}
<PlaceInfo data={goods && goods.goodsPageDto} />
<PlaceInfo
coordinate={goods?.goodsPageDto.coordinate}
image={goods?.goodsPageDto.goodsImagesList[0].goodsImgUrl}
/>

{/* 상품 마감일 */}
<div className="rounded-xl bg-gray-50 p-6">
Expand All @@ -83,7 +86,7 @@ export default function Goods() {
<span className="mr-2 text-sm font-light text-gray-600">
구매종료일 :
</span>
<span>{limitDate}</span>
<span>{dateFormetter(goods?.goodsPageDto.goodsLimitTime)}</span>
</div>
) : (
<div className="mx-auto h-3 w-3/4 animate-pulse rounded-lg bg-gray-300" />
Expand Down
10 changes: 5 additions & 5 deletions src/pages/Mypage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { ProfileHeaderType } from './index.d';

export default function Mypage() {
// useQuery를 사용하여 fetch 함수 실행 (getProfile)
// const { data: profile } = useQuery('getProfile', () => getProfile(), {
// onSuccess: (data) => {
// console.log(data);
// },
// });
const { data: profile } = useQuery('getProfile', () => getProfile(), {
onSuccess: (data) => {
console.log(data);
},
});

const [profileHeader, setProfileHeader] = useState<ProfileHeaderType>({
title: '마이페이지',
Expand Down
Loading

0 comments on commit 344ea9a

Please sign in to comment.