Skip to content

Commit

Permalink
feat: 답변 리스트 아이템 숨기기 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Doeunnkimm committed Aug 24, 2024
1 parent fe862d3 commit 7f9f874
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useMutation, UseMutationOptions, useQueryClient } from '@tanstack/react-query';

import { Http } from '@/common/apis/base.api';

import { ANSWERS_ME_QUERY_KEY } from '../queries/useGetAnswersMe';

interface Request {
meetingId: number;
activeMeetingQuestionIds: Array<number>;
}

interface MutationProps {
options?: UseMutationOptions<unknown, unknown, Request>;
}

export const useUpdateQuestionsActive = ({ options }: MutationProps = {}) => {
const queryClient = useQueryClient();

return useMutation({
mutationFn: ({ meetingId, activeMeetingQuestionIds }: Request) => {
// NOTE: PATCH지만, params로 넘겨줘야 해서 전처리
const params = activeMeetingQuestionIds.map((id) => `activeMeetingQuestionIds=${id}`).join('&');
return Http.PATCH(`/v1/meetings/${meetingId}/questions/active?${params}`);
},
onSuccess: (data, variable, context) => {
queryClient.invalidateQueries({ queryKey: [ANSWERS_ME_QUERY_KEY, variable.meetingId] });

options?.onSuccess?.(data, variable, context);
},
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,54 @@
import { If } from '@sambad/react-utils';
import { Accordion, Checkbox, Txt } from '@sambad/sds/components';
import { colors, size } from '@sambad/sds/theme';
import { useRouter } from 'next/navigation';
import { forwardRef, useImperativeHandle, useRef } from 'react';

import { useUpdateQuestionsActive } from '@/about-me/common/apis/mutates/useUpdateQuestionsActive';
import { EmptyView } from '@/common/components';

import { useGetAnswersByParams } from '../hooks/useGetAnswersByParams';
import { useGetFirstMeetingId } from '../hooks/useGetFirstMeetingId';
import { useGetIsModifyPage } from '../hooks/useGetIsModifyPage';

import { checkboxAttribute } from './constants';
import { answerContentCss, checkboxAndTriggerCss } from './styles';

export const AnsweredQuestionsContainer = () => {
interface Ref {
onMutate: () => void;
}

export const AnsweredQuestionsContainer = forwardRef<Ref>((_, ref) => {
const router = useRouter();

const { meetingId } = useGetFirstMeetingId();
const isModifyPage = useGetIsModifyPage();
const { data: answers } = useGetAnswersByParams();

const answersLength = answers?.contents?.length;

const { mutate } = useUpdateQuestionsActive({
options: { onSuccess: () => router.push('/about/me') },
});

const checkboxRefs = useRef<(HTMLInputElement | null)[]>([]);

if (answersLength === 0) {
return <EmptyView title="아직 답변한 릴레이 질문이 없어요" style={{ height: '300px' }} />;
}

const handleModify = () => {
const checkedIdx = checkboxRefs.current
.filter((checkbox) => checkbox?.checked)
.map((checkbox) => Number(checkbox?.id));

mutate({ meetingId, activeMeetingQuestionIds: checkedIdx });
};

// NOTE: ScreenContainer에서 호출하기 위해 ref에 추가
useImperativeHandle(ref, () => ({
onMutate: handleModify,
}));

return (
<section>
<If condition={isModifyPage}>
Expand All @@ -34,7 +63,14 @@ export const AnsweredQuestionsContainer = () => {
<Accordion.Item key={answer.idx} value={`${answer.idx}`}>
<div css={checkboxAndTriggerCss}>
<If condition={isModifyPage}>
<Checkbox defaultChecked={!answer.isHidden} {...checkboxAttribute.attribute} />
<Checkbox
id={`${answer.idx}`}
ref={(el) => {
checkboxRefs.current[index] = el;
}}
defaultChecked={!answer.isHidden}
{...checkboxAttribute.attribute}
/>
</If>
<Accordion.Trigger>
<Txt typography="subtitle1" color={colors.primary500} style={{ paddingRight: size['6xs'] }}>
Expand All @@ -54,4 +90,6 @@ export const AnsweredQuestionsContainer = () => {
</Accordion>
</section>
);
};
});

AnsweredQuestionsContainer.displayName = 'AnsweredQuestionsContainer';
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { colors, shadow, size } from '@sambad/sds/theme';
import { Button, TextButton, Txt } from '@sds/components';
import { useRouter } from 'next/navigation';
import { useRef } from 'react';

import { useCreateHandWavings } from '@/about-me/common/apis/mutates/useCreateHandWavings';
import { useGetHandWavingsStatus } from '@/about-me/common/apis/queries/useGetHandWavingsStatus';
Expand All @@ -17,6 +18,7 @@ import { SegmentedControlContainer } from './SegmentedControlContainer';
import { handWavingButtonCss, screenRootCss } from './styles';

export const ScreenContainer = () => {
const segmentedRef = useRef<{ onMutate: () => void }>(null);
const isModifyPage = useGetIsModifyPage();
const router = useRouter();

Expand All @@ -39,7 +41,7 @@ export const ScreenContainer = () => {
};

const handleModify = () => {
// 수정 api
segmentedRef.current?.onMutate();
};

return (
Expand All @@ -63,7 +65,7 @@ export const ScreenContainer = () => {
/>
<div style={layoutStyle}>
<ProfileContainer style={{ marginBottom: size['5xs'] }} />
<SegmentedControlContainer style={sectionStyle} />
<SegmentedControlContainer ref={segmentedRef} style={sectionStyle} />
</div>
{!isMy && getWavingStatusSuccess && (
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { SegmentedControl } from '@sambad/sds/components';
import { HTMLAttributes, useState } from 'react';
import { forwardRef, HTMLAttributes, useImperativeHandle, useRef, useState } from 'react';

import { useGetIsModifyPage } from '../hooks/useGetIsModifyPage';

Expand All @@ -13,14 +13,23 @@ type TabType = 'about-me' | 'answered-questions';

type SegmentedControlContainerProps = HTMLAttributes<HTMLDivElement>;

export const SegmentedControlContainer = (props: SegmentedControlContainerProps) => {
interface Ref {
onMutate: () => void;
}

export const SegmentedControlContainer = forwardRef<Ref, SegmentedControlContainerProps>((props, ref) => {
const answeredQuestionContainerRef = useRef<Ref>(null);
const isModifyPage = useGetIsModifyPage();
const [tab, setTab] = useState<TabType>(isModifyPage ? 'answered-questions' : 'about-me');

const handleTab = (value: string) => {
setTab(value as TabType);
};

useImperativeHandle(ref, () => ({
onMutate: answeredQuestionContainerRef.current?.onMutate || (() => {}),
}));

return (
<section css={segmentedSectionCss} {...props}>
<SegmentedControl value={tab} onValueChange={handleTab} css={segmentedCss}>
Expand All @@ -30,8 +39,10 @@ export const SegmentedControlContainer = (props: SegmentedControlContainerProps)

<div css={aboutMeSectionCss}>
{tab === 'about-me' && <AboutMeContainer />}
{tab === 'answered-questions' && <AnsweredQuestionsContainer />}
{tab === 'answered-questions' && <AnsweredQuestionsContainer ref={answeredQuestionContainerRef} />}
</div>
</section>
);
};
});

SegmentedControlContainer.displayName = 'SegmentedControlContainer';

0 comments on commit 7f9f874

Please sign in to comment.