Skip to content

Commit

Permalink
Merge pull request #35 from eunji-0623/feature-황은지
Browse files Browse the repository at this point in the history
Feat: 내 체험 관리, 체험 등록 form
  • Loading branch information
eunji-0623 authored Jul 16, 2024
2 parents 7d93dbb + be88012 commit 43b7050
Show file tree
Hide file tree
Showing 17 changed files with 261 additions and 81 deletions.
28 changes: 22 additions & 6 deletions components/MyActivity/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { formatCurrency } from '@/utils/formatCurrency';
import { formatNumberToFixed } from '@/utils/formatNumberToFixed';
import { usePopup } from '@/hooks/usePopup';
import useClickOutside from '@/hooks/useClickOutside';
import useDeleteActivity from '@/hooks/myActivity/useDeleteActivity';

function PopoverButton({ children, onClick }: PopoverButtonProps) {
return (
Expand All @@ -19,10 +20,11 @@ function PopoverButton({ children, onClick }: PopoverButtonProps) {
);
}

function Popover({ closePopover }: PopoverProps) {
function Popover({ activityId, closePopover }: PopoverProps) {
const popoverRef = useClickOutside<HTMLDivElement>(closePopover);
const router = useRouter();
const { openPopup } = usePopup();
const { deleteMyActivityMutation } = useDeleteActivity();

const handleClickEdit = () => {
router.push('/myActivity/edit');
Expand All @@ -32,13 +34,15 @@ function Popover({ closePopover }: PopoverProps) {
popupType: 'select',
content: '체험을 삭제하시겠어요?',
btnName: ['아니오', '삭제하기'],
callBackFnc: () => alert('체험 삭제 테스트'),
callBackFnc: () => {
deleteMyActivityMutation.mutate(activityId);
},
});
};

return (
<div
className="flex flex-col absolute rounded-[6px] border border-solid border-var-gray3 right-0 top-[50px] bg-white"
className="flex flex-col absolute rounded-[6px] border border-solid border-var-gray3 right-0 top-[50px] bg-white z-10"
ref={popoverRef}
>
<PopoverButton onClick={handleClickEdit}>수정하기</PopoverButton>
Expand All @@ -48,7 +52,14 @@ function Popover({ closePopover }: PopoverProps) {
);
}

function Card({ activityImage, rating, reviewCount, title, price }: CardProps) {
function Card({
activityId,
activityImage,
rating,
reviewCount,
title,
price,
}: CardProps) {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);

const handleClickMeatball = () => {
Expand All @@ -63,7 +74,7 @@ function Card({ activityImage, rating, reviewCount, title, price }: CardProps) {
return (
<div className="flex rounded-[24px] w-[800px] h-[204px] bg-white shadow-card t:w-full m:w-[calc(100vw-50px)]">
<Image
className="rounded-l-[24px]"
className="rounded-l-[24px] shrink-0"
src={activityImage}
alt={title}
width={210}
Expand All @@ -88,7 +99,12 @@ function Card({ activityImage, rating, reviewCount, title, price }: CardProps) {
<span className="font-[500] text-var-gray8">/인</span>
</div>
<MeatballButton onClick={handleClickMeatball} />
{isPopoverOpen ? <Popover closePopover={handleClosePopover} /> : null}
{isPopoverOpen ? (
<Popover
activityId={activityId}
closePopover={handleClosePopover}
/>
) : null}
</div>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions components/MyActivity/Card.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface CardProps {
activityId: number;
activityImage: string;
rating: number;
reviewCount: number;
Expand All @@ -12,5 +13,6 @@ export interface PopoverButtonProps {
}

export interface PopoverProps {
activityId: number;
closePopover: () => void;
}
40 changes: 40 additions & 0 deletions components/MyActivity/Register/AddressInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import AddressPopup from '@/components/Popup/AddressPopup';
import { addressState } from '@/states/registerState';
import { useState } from 'react';
import { useRecoilValue } from 'recoil';

function AddressInput() {
const address = useRecoilValue(addressState);
const [isPopupOpen, setIsPopupOpen] = useState(false);

const handleInputClick = () => {
setIsPopupOpen(!isPopupOpen);
};

const closePopup = () => {
setIsPopupOpen(false);
};

return (
<div>
<label
className="text-[24px] font-bold block mb-[16px]"
htmlFor="address"
>
주소
</label>
<input
type="text"
id="address"
value={address}
onClick={handleInputClick}
className="w-full h-[56px] py-[8px] px-[16px] rounded-md border border-var-gray6 bg-white"
readOnly
placeholder="주소"
/>
{isPopupOpen && <AddressPopup closePopup={closePopup} />}
</div>
);
}

export default AddressInput;
40 changes: 40 additions & 0 deletions components/Popup/AddressPopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { addressState } from '@/states/registerState';
import React, { useEffect, useState } from 'react';
import DaumPostcode from 'react-daum-postcode';
import { useRecoilState } from 'recoil';
import { AddressPopupProps } from './Popup.types';

const style = {
width: '400px',
height: '600px',
};

const AddressPopup = ({ closePopup }: AddressPopupProps) => {
const [address, setAddress] = useRecoilState(addressState);

const handleComplete = (data: any) => {
let fullAddress = data.address;
setAddress(fullAddress);
};

const handleClose = (state: string) => {
if (state === 'FORCE_CLOSE') {
closePopup();
} else if (state === 'COMPLETE_CLOSE') {
closePopup();
}
};

return (
<div className="flex items-center justify-center bg-black bg-opacity-70 fixed inset-0 z-50">
<DaumPostcode
style={style}
autoClose
onComplete={handleComplete}
onClose={handleClose}
/>
</div>
);
};

export default AddressPopup;
4 changes: 4 additions & 0 deletions components/Popup/Popup.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ export interface PopupProps {
btnName: [string, string?];
callBackFnc?: () => void;
}

export interface AddressPopupProps {
closePopup: () => void;
}
12 changes: 6 additions & 6 deletions components/SideNavigation/SideNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export default function SidenNavigation() {
case '/reservation':
setActiveButton('reservation');
break;
case '/setting':
setActiveButton('setting');
case '/myactivity':
setActiveButton('myactivity');
break;
case '/calendar':
setActiveButton('calendar');
Expand All @@ -45,7 +45,7 @@ export default function SidenNavigation() {
const buttonPaths: routePaths = {
mypage: '/mypage',
reservation: '/reservation',
setting: '/setting',
myactivity: '/myactivity',
calendar: '/calendar',
};
const { postProfileImgMutation } = useUploadProfile();
Expand Down Expand Up @@ -153,14 +153,14 @@ export default function SidenNavigation() {
</button>
<button
className={`${sideNavBtnStyle} ${
activeButton === 'setting'
activeButton === 'myactivity'
? 'bg-var-green1 rounded-[12px] text-var-black'
: 'text-var-gray6'
}`}
onClick={() => handleBtnClick('setting')}
onClick={() => handleBtnClick('myactivity')}
>
<Image
src={activeButton === 'setting' ? settingIcon : graySettingIcon}
src={activeButton === 'myactivity' ? settingIcon : graySettingIcon}
alt="내 체험 관리 아이콘"
/>
<p>내 체험 관리</p>
Expand Down
File renamed without changes.
13 changes: 13 additions & 0 deletions hooks/myActivity/useDeleteActivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { deleteMyActivities } from '@/pages/api/myActivities/apimyActivities';
import { useMutation } from '@tanstack/react-query';

export default function useDeleteActivity() {
const deleteMyActivityMutation = useMutation({
mutationFn: deleteMyActivities,
onSuccess: () => {
window.location.reload();
},
});

return { deleteMyActivityMutation };
}
45 changes: 45 additions & 0 deletions hooks/myActivity/useMyActivityList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useInfiniteQuery } from '@tanstack/react-query';
import { getMyActivityList } from '@/pages/api/myActivities/apimyActivities';
import { getMyActivityListResponse } from '@/pages/api/myActivities/apimyActivities.types';
import { useMemo } from 'react';
import useLoginState from '../useLoginState';

const INITIAL_SIZE = 4;
const REFETCH_SIZE = 1;

export const useMyActivityList = () => {
const loginState = useLoginState();

const { data, fetchNextPage, hasNextPage, isLoading, isFetchingNextPage } =
useInfiniteQuery<getMyActivityListResponse>({
queryKey: ['myActivityList'],
queryFn: ({ pageParam = undefined }) => {
const size = pageParam === undefined ? INITIAL_SIZE : REFETCH_SIZE;
return getMyActivityList({
size,
cursorId: pageParam as number | undefined,
});
},
getNextPageParam: (lastPage) => {
return lastPage.totalCount === lastPage.activities.length
? undefined
: lastPage.cursorId;
},
initialPageParam: undefined,
enabled: loginState.isLoggedIn,
});

const myActivityList = useMemo(() => {
if (data) {
return data.pages.flatMap((page) => page.activities);
}
}, [data]);

return {
myActivityList,
fetchNextPage,
hasNextPage,
isLoading,
isFetchingNextPage,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ import {
postActivityParams,
} from '@/pages/api/activities/apiactivities.types';
import { postActivity } from '@/pages/api/activities/apiactivities';
import { useRouter } from 'next/router';

export default function useRegisterActivity() {
const router = useRouter();

const postActivityMutation: UseMutationResult<
postActivityResponse,
unknown,
postActivityParams
> = useMutation({
mutationFn: postActivity,
onSuccess: () => {
window.location.reload();
router.push('/myActivity');
},
});

Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"next": "14.2.4",
"react": "^18",
"react-calendar": "^5.0.0",
"react-daum-postcode": "^3.1.3",
"react-dom": "^18",
"react-hook-form": "^7.52.1",
"react-intersection-observer": "^9.13.0",
Expand Down
54 changes: 0 additions & 54 deletions pages/myActivity/index.tsx

This file was deleted.

File renamed without changes.
Loading

0 comments on commit 43b7050

Please sign in to comment.