Skip to content

Commit

Permalink
feat: 커피챗 상세 더보기 구현 (#1641)
Browse files Browse the repository at this point in the history
* feat: 커피챗 상세 더보기 버튼 구현

* feat: 커피챗 상세 삭제 구현

* chore: 불필요 코드 삭제

* feat: 타이틀 스타일 변경

* fix: 깃 충돌 해결

* chore: 수정 삭제 스타일 수정
  • Loading branch information
seojisoosoo authored Nov 4, 2024
1 parent e505106 commit 05189ce
Show file tree
Hide file tree
Showing 7 changed files with 278 additions and 35 deletions.
11 changes: 11 additions & 0 deletions src/api/endpoint/coffeechat/deleteCoffeechat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { z } from 'zod';

import { createEndpoint } from '@/api/typedAxios';

export const deleteCoffeechat = createEndpoint({
request: () => ({
method: 'DELETE',
url: `api/v1/members/coffeechat/details`,
}),
serverResponseScheme: z.unknown(),
});
3 changes: 2 additions & 1 deletion src/components/coffeechat/detail/OpenerProfile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface OpenerProfileProps {
export default function OpenerProfile({ memberId }: OpenerProfileProps) {
const { data: openerProfile } = useGetCoffeechatDetail(memberId);
const { isOpen: isOpenMessageModal, onOpen: onOpenMessageModal, onClose: onCloseMessageModal } = useModalState();

return (
<>
{openerProfile && (
Expand Down Expand Up @@ -173,7 +174,7 @@ const OpenerProfileSection = styled.section<{ isMine: boolean }>`
grid: [row1-start] 'profileImageBox profileInfoBox buttonSection' auto [row1-end]/ auto;
grid-template-columns: 1fr 5fr 2fr;
gap: 28px;
align-items: center;
align-items: ${({ isMine }) => (isMine ? 'flex-end' : 'center')};
justify-content: space-between;
width: 100%;
Expand Down
232 changes: 232 additions & 0 deletions src/components/coffeechat/detail/SeemoreSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import styled from '@emotion/styled';
import * as Dialog from '@radix-ui/react-dialog';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { colors } from '@sopt-makers/colors';
import { fonts } from '@sopt-makers/fonts';
import { IconDotsVertical, IconEdit, IconTrash } from '@sopt-makers/icons';
import { DialogOptionType, useDialog, useToast } from '@sopt-makers/ui';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import { playgroundLink } from 'playground-common/export';
import { useState } from 'react';

import { deleteCoffeechat } from '@/api/endpoint/coffeechat/deleteCoffeechat';
import Responsive from '@/components/common/Responsive';
import { MOBILE_MEDIA_QUERY } from '@/styles/mediaQuery';

const DropdownPortal = dynamic<DropdownMenu.DropdownMenuPortalProps>(
() => import('@radix-ui/react-dropdown-menu').then((r) => r.DropdownMenuPortal),
{
ssr: false,
},
);

const DialogPortal = dynamic<Dialog.DialogPortalProps>(
() => import('@radix-ui/react-dialog').then((r) => r.DialogPortal),
{
ssr: false,
},
);

interface SeemoreSelectProp {
memberId: string;
}

interface SeemoreContentProps {
onEdit: () => void;
onDelete: () => void;
}

export default function SeemoreSelect({ memberId }: SeemoreSelectProp) {
const router = useRouter();
const queryClient = useQueryClient();
const { open: toastOpen } = useToast();
const { open } = useDialog();
const option: DialogOptionType = {
title: '커피챗을 삭제하시겠습니까?',
description: '새 커피챗을 다시 열 수 있지만, 작성했던 내용은 저장되지 않아요.',
type: 'danger',
typeOptions: {
cancelButtonText: '취소',
approveButtonText: '삭제하기',
buttonFunction: () => handleDelete(),
},
};

const { mutate, isPending } = useMutation({
mutationFn: () => deleteCoffeechat.request(),
});

const onEdit = () => {
router.push(playgroundLink.coffeechatEdit(memberId));
};

const handleDelete = () => {
mutate(undefined, {
onSuccess: async () => {
// TODO: 연결
// logSubmitEvent('');
// queryClient.invalidateQueries('')
toastOpen({ icon: 'success', content: '커피챗이 삭제되었어요. 다음에 또 만나요!' });
await router.push(playgroundLink.coffeechat());
},
});
};

const onDelete = () => {
open(option);
};

return (
<>
<Responsive only='desktop'>
<DropdownSeemore onEdit={onEdit} onDelete={onDelete} />
</Responsive>
<Responsive only='mobile'>
<BottomSheetSeemore onEdit={onEdit} onDelete={onDelete} />
</Responsive>
</>
);
}

const DropdownSeemore = ({ onEdit, onDelete }: SeemoreContentProps) => {
const [open, setOpen] = useState(false);

return (
<DropdownMenu.Root open={open} onOpenChange={setOpen} modal={false}>
<DropdownMenu.Trigger asChild>
<DotsVerticalIcon />
</DropdownMenu.Trigger>
<DropdownPortal>
<DropdownMenu.Content sideOffset={10} align='end' side='bottom' asChild>
<StyledContent>
<StyledItem onClick={onEdit}>
<EditIcon />
<>수정</>
</StyledItem>
<StyledItem onClick={onDelete} isTrash>
<TrashIcon />
<>삭제</>
</StyledItem>
</StyledContent>
</DropdownMenu.Content>
</DropdownPortal>
</DropdownMenu.Root>
);
};

const BottomSheetSeemore = ({ onEdit, onDelete }: SeemoreContentProps) => {
const [open, setOpen] = useState(false);

return (
<Dialog.Root open={open} onOpenChange={setOpen} modal={false}>
<Dialog.Trigger asChild>
<DotsVerticalIcon />
</Dialog.Trigger>
<DialogPortal>
<Dialog.Overlay asChild>
<Overlay />
</Dialog.Overlay>
<Dialog.Content asChild>
<StyledContent>
<StyledContentItem
onClick={() => {
setOpen(false);
onEdit();
}}
>
<EditIcon />
<>수정</>
</StyledContentItem>
<StyledContentItem
onClick={() => {
setOpen(false);
onDelete();
}}
isTrash
>
<TrashIcon />
<>삭제</>
</StyledContentItem>
</StyledContent>
</Dialog.Content>
</DialogPortal>
</Dialog.Root>
);
};

const Overlay = styled.div`
position: fixed;
inset: 0;
z-index: 101;
background-color: rgb(0 0 0 / 70%);
animation: overlay-show 0.3s cubic-bezier(0.16, 1, 0.3, 1);
@keyframes overlay-show {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
`;

const StyledContent = styled.div`
display: flex;
flex-direction: column;
gap: 6px;
border-radius: 13px;
background-color: ${colors.gray800};
padding: 8px;
@media ${MOBILE_MEDIA_QUERY} {
position: fixed;
right: 16px;
bottom: 42px;
left: 16px;
z-index: 102;
border-radius: 20px;
padding: 12px 8px;
width: calc(100% - 32px);
}
`;

const StyledItem = styled(DropdownMenu.Item)<{ isTrash?: boolean }>`
display: flex;
gap: 10px;
align-items: center;
padding: 8px 12px;
color: ${({ isTrash }) => isTrash && colors.red400};
${fonts.BODY_16_M};
`;

const StyledContentItem = styled.div<{ isTrash?: boolean }>`
display: flex;
gap: 10px;
align-items: center;
padding: 10px;
color: ${({ isTrash }) => isTrash && colors.red400};
${fonts.BODY_14_M};
`;

const EditIcon = styled(IconEdit)`
width: 16px;
height: 16px;
`;

const TrashIcon = styled(IconTrash)`
width: 16px;
height: 16px;
color: ${colors.red400};
`;

const DotsVerticalIcon = styled(IconDotsVertical)`
margin-top: 12px;
cursor: pointer;
width: 24px;
height: 24px;
`;
17 changes: 7 additions & 10 deletions src/components/coffeechat/detail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import styled from '@emotion/styled';
import { colors } from '@sopt-makers/colors';
import { fonts } from '@sopt-makers/fonts';
import { IconDotsVertical } from '@sopt-makers/icons';
import { useMemo } from 'react';

import { useGetCoffeechatDetail } from '@/api/endpoint/coffeechat/getCoffeechatDetail';
import { useGetMemberOfMe } from '@/api/endpoint/members/getMemberOfMe';
import { useGetMemberProfileById } from '@/api/endpoint_LEGACY/hooks';
import CoffeechatContents from '@/components/coffeechat/detail/CoffeechatContents';
import OpenerProfile from '@/components/coffeechat/detail/OpenerProfile';
import SeemoreSelect from '@/components/coffeechat/detail/SeemoreSelect';
import Loading from '@/components/common/Loading';
import CoffeechatLoading from '@/components/coffeechat/Loading';
import CareerSection from '@/components/members/detail/CareerSection';
import DetailInfoSection from '@/components/members/detail/DetailinfoSection';
Expand Down Expand Up @@ -44,7 +45,7 @@ export default function CoffeechatDetail({ memberId }: CoffeechatDetailProp) {
<CoffeechatHeader>
<CoffeechatTitle>{openerProfile.bio}</CoffeechatTitle>
{/* TODO: 더보기 버튼 기능 구현 */}
{/* <>{openerProfile.isMine && <DotsVerticalIcon />}</> */}
<>{openerProfile.isMine && <SeemoreSelect memberId={memberId} />}</>
</CoffeechatHeader>
<OpenerProfile memberId={memberId} />

Expand Down Expand Up @@ -98,12 +99,12 @@ const ProfilPojectSection = styled.div`
const SoptActivityTitle = styled.h2`
margin: 28px 0 32px;
color: ${colors.white};
${fonts.HEADING_32_B};
${fonts.HEADING_28_B};
@media ${MOBILE_MEDIA_QUERY} {
margin: 24px 0;
${fonts.HEADING_28_B};
${fonts.HEADING_20_B};
}
`;

Expand All @@ -123,11 +124,6 @@ const DetailPage = styled.div`
}
`;

const DotsVerticalIcon = styled(IconDotsVertical)`
width: 24px;
height: 24px;
`;

const CoffeechatTitle = styled.h1`
/* stylelint-disable-next-line value-no-vendor-prefix */
display: -webkit-box;
Expand All @@ -149,7 +145,8 @@ const CoffeechatTitle = styled.h1`

const CoffeechatHeader = styled.header`
display: flex;
align-items: center;
gap: 20px;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 24px;
`;
8 changes: 4 additions & 4 deletions src/components/members/detail/GroupSection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { playgroundLink } from '@/constants/links';
import useEnterScreen from '@/hooks/useEnterScreen';
import { MOBILE_MEDIA_QUERY } from '@/styles/mediaQuery';
import { safeParseInt } from '@/utils';
import { fonts } from '@sopt-makers/fonts';

interface GroupSectionProps {
profile: ProfileDetail;
Expand Down Expand Up @@ -88,11 +89,10 @@ const Container = styled.section`
`;

const ActivityTitle = styled.div`
line-height: 100%;
font-size: 32px;
font-weight: 700;
${fonts.HEADING_28_B};
@media ${MOBILE_MEDIA_QUERY} {
font-size: 22px;
${fonts.HEADING_20_B};
}
`;

Expand Down
8 changes: 4 additions & 4 deletions src/components/members/detail/ProjectSection/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import styled from '@emotion/styled';
import { colors } from '@sopt-makers/colors';
import { fonts } from '@sopt-makers/fonts';
import Link from 'next/link';
import { playgroundLink } from 'playground-common/export';

Expand Down Expand Up @@ -65,11 +66,10 @@ const Container = styled.section`
`;

const ActivityTitle = styled.div`
line-height: 100%;
font-size: 32px;
font-weight: 700;
${fonts.HEADING_28_B};
@media ${MOBILE_MEDIA_QUERY} {
font-size: 22px;
${fonts.HEADING_20_B};
}
`;

Expand Down
Loading

0 comments on commit 05189ce

Please sign in to comment.