Skip to content

Commit

Permalink
Feat: 공유/참여 기능 구현 및 스타일링
Browse files Browse the repository at this point in the history
  • Loading branch information
seungjun222 committed Jan 17, 2024
1 parent 9a1f257 commit e90bf3a
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 39 deletions.
14 changes: 9 additions & 5 deletions src/components/Trip/PlanTripButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { PlanIcon, RightIcon } from '@components/common/icons/Icons';

const PlanTripButton = () => {
return (
<button className="body3 my-6 flex w-full items-center justify-between rounded-[8px] bg-[#F3F4F5] px-[15px] py-[15px] text-gray7 text-main1">
<div className="flex items-center justify-start">
<PlanIcon />
여행 계획하기
<button className="body3 mb-10 mt-6 flex w-full items-center justify-between rounded-[8px] bg-[#F3F4F5] px-[15px] py-[15px] text-gray7 text-main1">
<div className="flex items-center justify-start ">
<div>
<PlanIcon />
</div>
<p className="ml-1.5 text-gray5">여행 계획하기</p>
</div>
<div>
<RightIcon fill="#888888" />
</div>
<RightIcon />
</button>
);
};
Expand Down
95 changes: 91 additions & 4 deletions src/components/Trip/TripInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,107 @@ import { useRecoilValue, useRecoilState } from 'recoil';
import { isModalOpenState, modalChildrenState } from '@recoil/modal';
import TripSurveyMember from '@components/common/modal/children/TripSurveyMember';
import { Modal } from '@components/common/modal';
import { useQuery } from '@tanstack/react-query';
import { getTripsMembers } from '@api/trips';
import { tripIdState } from '@recoil/socket';
import { ReactComponent as NullUser } from '@assets/images/NullUser.svg';
import { DownIcon } from '@components/common/icons/Icons';
import { useState } from 'react';

const ShareList = () => {
const tripId = Number(useRecoilValue(tripIdState));
const { data: tripsMembers } = useQuery({
queryKey: ['tripsMembers', tripId],
queryFn: () => getTripsMembers(tripId),
});
const members = tripsMembers?.data?.data?.tripMemberSimpleInfos;

return (
<>
<hr className="my-3 border-solid border-gray2" />
<div>
{members.map((member: any, index: number) => {
return (
<div
className={`mb-2 flex cursor-pointer items-center text-gray5`}
key={index}>
{member.profileImageUrl &&
member.profileImageUrl !== 'http://asiduheimage.jpg' ? (
<img
src={member.profileImageUrl}
alt="유저 프로필"
className="h-[32px] w-[32px] rounded-full"
/>
) : (
<NullUser className="h-[32px] w-[32px]" />
)}
<div className="ml-3">{member.nickname}</div>
</div>
);
})}
</div>
</>
);
};

const TripInfo = () => {
const modalChildren = useRecoilValue(modalChildrenState);
const [isModalOpen, setIsModalOpen] = useRecoilState(isModalOpenState);
const tripId = Number(useRecoilValue(tripIdState));
const [isAccordion, setIsAccordion] = useState(false);

const { data: tripsMembers } = useQuery({
queryKey: ['tripsMembers', tripId],
queryFn: () => getTripsMembers(tripId),
});
const members = tripsMembers?.data?.data?.tripMemberSimpleInfos;

const closeModal = () => {
setIsModalOpen(false);
};

const handleClickButton = () => {
setIsAccordion((prev) => !prev);
};

return (
<>
<div className="my-5">
<div className="flex items-center justify-between">
<div className="body1 text-gray7">프로필</div>
<div className="body1 text-gray7"> 1명과 공유중</div>
<div className="flex space-x-[-17.5px]">
{members?.map((member: any, index: number) => (
<div key={index}>
{member.profileImageUrl &&
member.profileImageUrl !== 'http://asiduheimage.jpg' ? (
<img
src={member.profileImageUrl}
alt="유저 프로필"
className="h-[32px] w-[32px] rounded-full border-2 border-solid border-white"
/>
) : (
<NullUser className="h-[32px] w-[32px] border-2 border-solid border-white" />
)}
</div>
))}
</div>

<div className="flex items-center gap-1">
<p className="body1 text-[13px] text-gray7">
{members?.length}명과 공유중
</p>
<div
style={{
transform: isAccordion ? 'rotate(180deg)' : 'rotate(0deg)',
transition: 'transform 0.3s ease',
}}
onClick={handleClickButton}
className="pt-0.5">
<DownIcon color="#888888" size={20} />
</div>
</div>
</div>

{isAccordion && <ShareList />}
<hr className="mb-6 mt-3 border-solid border-gray2" />
<div className="flex items-center justify-between">
<div className="flex items-center">
Expand All @@ -28,9 +113,11 @@ const TripInfo = () => {
<span className="body4 pt-[1px] text-gray4">5</span>
</div>
</div>
<button className="body3 text-gray3">편집</button>
<button className="body3 rounded-lg border-2 border-solid border-gray2 p-2 text-gray4">
편집
</button>
</div>
<span className="body1 text-gray4">23.12.23 ~ 23.12.25</span>
<span className="body1 text-gray4">23.12.23 - 23.12.25</span>
</div>
<Modal isOpen={isModalOpen} closeModal={closeModal}>
{modalChildren === 'TripSurveyMember' && <TripSurveyMember />}
Expand Down
31 changes: 13 additions & 18 deletions src/components/Trip/TripParticipant.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { getTripsSurveyMembers } from '@api/trips';
import { useQuery } from '@tanstack/react-query';
import { tripIdState } from '@recoil/socket';
import { useRecoilValue } from 'recoil';
import { ReactComponent as NullUser } from '@assets/images/NullUser.svg';
import { useRecoilValue } from 'recoil';
import { participantsState } from '@recoil/trip';

interface ParticipantStatusProps {
status: string;
Expand Down Expand Up @@ -32,25 +30,22 @@ const ParticipantList: React.FC<{ infos: any[] }> = ({ infos }) => (
export const ParticipantStatus: React.FC<ParticipantStatusProps> = ({
status,
}) => {
const tripId = Number(useRecoilValue(tripIdState));

const { data: tripsSurveyMembers } = useQuery({
queryKey: ['tripsSurveyMembers', tripId],
queryFn: () => getTripsSurveyMembers(tripId),
});

const participants =
status === '참여'
? tripsSurveyMembers?.data?.data?.tripSurveySetMemberInfos
: tripsSurveyMembers?.data?.data?.nonTripSurveySetMemberInfos;
const participants = useRecoilValue(participantsState);

return (
<div className="flex flex-col">
<div className="mb-4 ml-auto mr-2 text-xs text-gray5">
{participants &&
`${participants.length}${status === '참여' ? '참여' : '미참여'}`}
{status == '참여' ? (
<>{participants?.tripSurveyMemberCount}명 참여</>
) : (
<>{participants?.nonTripSurveySetMemberInfos?.length}명 미참여</>
)}
</div>
{participants && <ParticipantList infos={participants} />}
{status == '참여' ? (
<ParticipantList infos={participants?.tripSurveySetMemberInfos} />
) : (
<ParticipantList infos={participants?.nonTripSurveySetMemberInfos} />
)}
</div>
);
};
37 changes: 27 additions & 10 deletions src/components/Trip/TripPreference.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { useState, useEffect } from 'react';
import { getTripsSurvey } from '@api/trips';
import { useQuery } from '@tanstack/react-query';
import { useParams } from 'react-router-dom';
import { MoreIcon } from '@components/common/icons/Icons';
import { RightIcon } from '@components/common/icons/Icons';
import { MoreIcon, RightIcon, HeartIcon } from '@components/common/icons/Icons';
import {
calculatePercentage,
calculatePercentageRemain,
} from '@utils/calculatePercentage';
import { useSetRecoilState } from 'recoil';
import { modalChildrenState, isModalOpenState } from '@recoil/modal';

import { getTripsSurveyMembers } from '@api/trips';
import { tripIdState } from '@recoil/socket';
import { useRecoilValue, useSetRecoilState, useRecoilState } from 'recoil';
import { participantsState } from '@recoil/trip';
interface RatioBarParams {
value: number;
total: number;
Expand All @@ -28,7 +28,12 @@ interface PercentageParams {
const TripPreferenceButton: React.FC = () => {
return (
<button className="mb-[17.5px] mt-[20px] flex w-[335px] items-center rounded-full bg-white px-6 py-4 text-sm">
<div className="text-gray6">내 여행 취향 설정하러 가기</div>
<div className="flex items-center text-gray6">
<div>
<HeartIcon fill="#888888" color="#888888" size={20} />
</div>
<p className="ml-1.5">내 여행 취향 설정하러 가기</p>
</div>
<div className="ml-auto">
<RightIcon fill="#5E5E5E" />
</div>
Expand Down Expand Up @@ -89,15 +94,25 @@ const Percentage = ({ value, total, color }: PercentageParams) => (
);

const TripPreference: React.FC = () => {
const params = useParams();
const tripId = Number(params.id);
const [A, setA] = useState<[number, number]>([0, 0]);
const [B, setB] = useState<[number, number]>([0, 0]);
const [C, setC] = useState<[number, number]>([0, 0]);
const [D, setD] = useState<[number, number]>([0, 0]);
const [E, setE] = useState<[number, number]>([0, 0]);
const setModalChildren = useSetRecoilState(modalChildrenState);
const setIsModalOpen = useSetRecoilState(isModalOpenState);
const tripId = Number(useRecoilValue(tripIdState));
const [participants, setParticipants] = useRecoilState(participantsState);

const { data: tripsSurveyMembers } = useQuery({
queryKey: ['tripsSurveyMembers', tripId],
queryFn: () => getTripsSurveyMembers(tripId),
});

useEffect(() => {
const participants = tripsSurveyMembers?.data?.data;
setParticipants(participants);
}, [tripsSurveyMembers]);

const { data: tripPreference, isLoading } = useQuery({
queryKey: ['tripPreference', tripId],
Expand Down Expand Up @@ -139,12 +154,14 @@ const TripPreference: React.FC = () => {
};

return (
<div className=" mb-[-20px] ml-[-20px] mr-[-20px] mt-[-20px] flex flex-col items-center bg-gray1 ">
<div className=" m-[-20px] flex flex-col items-center bg-gray1 pb-[20px] ">
<TripPreferenceButton />
<div
onClick={handleButtonClick}
className="mb-[20px] ml-auto mr-[40px] flex cursor-pointer items-center text-sm ">
<div>n명 참여</div>
<div className="text-gray6">
{participants?.tripSurveyMemberCount}명 참여
</div>
<div className="mt-0.5">
<MoreIcon size={20} color="none" fill="#888888" />
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const Accordion: React.FC<AccordionProps> = ({ title, content }) => {
<accordion.Item value="item-1">
<accordion.Header className="flex">
{title}
<accordion.Trigger className="ml-auto">
<DownIcon size={17} className="rotate-on-open" />
<accordion.Trigger>
<DownIcon size={17} className="rotate-on-open ml-1" />
</accordion.Trigger>
</accordion.Header>
<accordion.Content>{content}</accordion.Content>
Expand Down
22 changes: 22 additions & 0 deletions src/recoil/trip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { atom } from 'recoil';

type Participant = {
memberId: number;
nickname: string;
thumbnail: string;
};

export type Participants = {
tripSurveyMemberCount: number;
tripSurveySetMemberInfos: Participant[];
nonTripSurveySetMemberInfos: Participant[];
};

export const participantsState = atom<Participants>({
key: 'participantsState',
default: {
tripSurveyMemberCount: 0,
tripSurveySetMemberInfos: [],
nonTripSurveySetMemberInfos: [],
},
});

0 comments on commit e90bf3a

Please sign in to comment.