Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/api/endpoint/members/getWorkPreference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useQuery } from '@tanstack/react-query';
import { z } from 'zod';

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

export const getMyWorkPreference = createEndpoint({
request: {
method: 'GET',
url: 'api/v1/members/work-preference',
},
serverResponseScheme: z.object({
workPreference: z.object({
ideationStyle: z.union([z.literal('즉흥'), z.literal('숙고')]),
workTime: z.union([z.literal('아침'), z.literal('밤')]),
communicationStyle: z.union([z.literal('몰아서'), z.literal('나눠서')]),
workPlace: z.union([z.literal('카공'), z.literal('집콕')]),
feedbackStyle: z.union([z.literal('직설적'), z.literal('돌려서')]),
}),
}),
});

export const useGetMyWorkPreference = () => {
return useQuery({
queryKey: ['getMyWorkPreference'],
queryFn: () => getMyWorkPreference.request(),
});
};
2 changes: 1 addition & 1 deletion src/components/matchmember/MatchContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const MatchContent = ({
<Spacing size={24} />
<LoggingClick eventKey='balancegame'>
<Button size='lg' onClick={onNextStep}>
5초만에 소울메이트 찾기
앱잼 소울메이트 보러가기
</Button>
</LoggingClick>
<CloseForTodayButton
Expand Down
21 changes: 18 additions & 3 deletions src/components/matchmember/MemberCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,39 @@ import Text from '@/components/common/Text';
import ProfileIcon from 'public/icons/icon-profile.svg';
import ResizedImage from '@/components/common/ResizedImage';
import { useGetRecommendations } from '@/api/endpoint/members/getRecommendations';
import { useState } from 'react';
import { Skeleton } from '@sopt-makers/ui';
import { useEffect, useState } from 'react';
import { Skeleton, useToast } from '@sopt-makers/ui';
import { playgroundLink } from '@/constants/links';
import { useRouter } from 'next/router';
import NonIcon from '@/public/icons/img/popup/member_match_search.svg';
import useEventLogger from '@/components/eventLogger/hooks/useEventLogger';
import { useRunOnce } from '@/hooks/useRunOnce';
import axios from 'axios';

export const MemberCard = () => {
const { data, isPending } = useGetRecommendations();
const { data, isPending, isError, error } = useGetRecommendations();
const [_isImageLoaded, setIsImageLoaded] = useState(false);
const router = useRouter();
const { logImpressionEvent } = useEventLogger();
const { open: toastOpen } = useToast();

useRunOnce(() => {
logImpressionEvent('feedCard', { screen: '기획경선 홈팝업' });
}, []);

useEffect(() => {
if (isError) {
const status =
axios.isAxiosError(error) && !!error.response && typeof error.response.status === 'number'
? error.response.status
: null;

const errorMessage =
status === 400 ? `밸런스게임을 먼저 진행해주세요` : `데이터를 불러오는 중 오류가 발생했습니다.`;
toastOpen({ icon: 'error', content: errorMessage });
}
}, [isError, error]);

if (isPending)
return (
<CardWrapper>
Expand Down
9 changes: 9 additions & 0 deletions src/components/matchmember/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,12 @@ export const convertAnswersToApiPayload = (answers: BalanceGameValue): WorkPrefe

return payload as WorkPreferenceType;
};

export const convertWorkPreferenceToHashtags = (preference: WorkPreferenceType): string => {
if (!preference) return '';

const tags = Object.values(preference);
const hashtagString = tags.map((tag) => `#${tag}`).join(' ');

return hashtagString;
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ import { MOBILE_MEDIA_QUERY } from '@/styles/mediaQuery';
import MatchMemberModal from '@/components/matchmember/MatchMemberModal';
import { useMatchMemberEvent } from '@/components/matchmember/hooks/useMatchMemberEvent';
import useModalState from '@/components/common/Modal/useModalState';
import { fonts } from '@sopt-makers/fonts';
import { useGetMyWorkPreference } from '@/api/endpoint/members/getWorkPreference';
import { convertWorkPreferenceToHashtags } from '@/components/matchmember/constant';

const MyPreferenceSubTitle = () => {
const { data: myData, isLoading: myLoading } = useGetMyWorkPreference();

if (myLoading || !myData?.workPreference) return <></>;

const tags = convertWorkPreferenceToHashtags(myData.workPreference);

return <SubTitle>내 작업 스타일은 {tags}</SubTitle>;
};

const WorkPreferenceMatchedMemberList = () => {
const { data, isLoading } = useGetRecommendations();
const isEmpty = data?.recommendations && data.recommendations.length === 0;
Expand Down Expand Up @@ -47,41 +61,44 @@ const WorkPreferenceMatchedMemberList = () => {
return (
<>
<StyledContainer>
<TitleWrapper>
<Responsive only='desktop'>
<Text typography='SUIT_20_B' color={colors.gray10}>
나와 37기 사람들의 작업 궁합은?
</Text>
</Responsive>
<Responsive only='mobile'>
<Text typography='SUIT_16_B' color={colors.gray10}>
나와 37기 사람들의 작업 궁합은?
</Text>
</Responsive>
<RefreshIconWrapper>
<button
onClick={() => {
queryClient.invalidateQueries({ queryKey: ['getRecommendations'] });
}}
>
<RefreshIcon style={{ width: '24px', height: '24px', flexShrink: 0, cursor: 'pointer' }} />
</button>
<TitleContainer>
<TitleWrapper>
<Responsive only='desktop'>
<Text typography='SUIT_24_B' color={colors.gray10}>
나와 37기 사람들의 작업 궁합은?
</Text>
</Responsive>
<Responsive only='mobile'>
<MobileTooltipWrapper>
<Text typography='SUIT_16_B' color={colors.gray10}>
나와 37기 사람들의 작업 궁합은?
</Text>
</Responsive>
<RefreshIconWrapper>
<button
onClick={() => {
queryClient.invalidateQueries({ queryKey: ['getRecommendations'] });
}}
>
<StyledRefreshIcon />
</button>
<Responsive only='mobile'>
<MobileTooltipWrapper>
<Text typography='SUIT_13_M' color={colors.gray50}>
더 많은 멤버를 찾아보세요!
</Text>
</MobileTooltipWrapper>
</Responsive>
</RefreshIconWrapper>
<Responsive only='desktop'>
<TooltipWrapper>
<Text typography='SUIT_13_M' color={colors.gray50}>
더 많은 멤버를 찾아보세요!
</Text>
</MobileTooltipWrapper>
</TooltipWrapper>
</Responsive>
</RefreshIconWrapper>
<Responsive only='desktop'>
<TooltipWrapper>
<Text typography='SUIT_13_M' color={colors.gray50}>
더 많은 멤버를 찾아보세요!
</Text>
</TooltipWrapper>
</Responsive>
</TitleWrapper>
</TitleWrapper>
<MyPreferenceSubTitle />
</TitleContainer>
{isEmpty ? (
<EmptyStateWrapper>
<WorkPreferenceMemberListWrapper isEmpty={isEmpty}>
Expand All @@ -100,6 +117,7 @@ const WorkPreferenceMatchedMemberList = () => {
: '나의 작업 스타일을 5초만에 알아보고\n찰떡 케미 앱잼 멤버 확인해요!'}
</Text>

{/* TODO: 작업선택 모달 오픈로직 추가 */}
{!hasWorkPreference && (
<Button variant='fill' theme='white' onClick={handleClickStartButton}>
작업 스타일 선택하기
Expand Down Expand Up @@ -174,6 +192,17 @@ const TooltipWrapper = styled.div`
content: '';
}
`;

const TitleContainer = styled.div`
display: flex;
flex-direction: column;
gap: 6px;

@media ${MOBILE_MEDIA_QUERY} {
gap: 2px;
}
`;

const TitleWrapper = styled.div`
display: flex;
gap: 8px;
Expand Down Expand Up @@ -243,4 +272,26 @@ const EmptyStateContent = styled.div`
width: 100%;
height: 100%;
`;

const StyledRefreshIcon = styled(RefreshIcon)`
flex-shrink: 0;
cursor: pointer;
width: 32px;
height: 32px;

@media ${MOBILE_MEDIA_QUERY} {
width: 24px;
height: 24px;
}
`;

const SubTitle = styled.p`
${fonts.TITLE_18_SB};

color: ${colors.gray200};

@media ${MOBILE_MEDIA_QUERY} {
${fonts.BODY_13_M};
}
`;
export default WorkPreferenceMatchedMemberList;
Loading