From 48191ee3cd411e933ab3e1fc8e0e784fc6cbc529 Mon Sep 17 00:00:00 2001 From: NekoGroove01 Date: Tue, 6 Aug 2024 00:15:17 +0900 Subject: [PATCH 1/8] =?UTF-8?q?Style:=20Share=20Group=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=204~8=20Photo=20=EC=95=84=EC=9D=B4=ED=85=9C=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ShareGroup/ShareGroupCarousel/Styles.ts | 5 ++--- src/components/ShareGroup/ShareGroupImageItem/Styles.ts | 4 ++-- src/utils/UseCarousel.tsx | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/ShareGroup/ShareGroupCarousel/Styles.ts b/src/components/ShareGroup/ShareGroupCarousel/Styles.ts index a6ed676..75f0748 100644 --- a/src/components/ShareGroup/ShareGroupCarousel/Styles.ts +++ b/src/components/ShareGroup/ShareGroupCarousel/Styles.ts @@ -17,10 +17,9 @@ export const CarouselTrack = styled.div<{ `; export const CarouselBlankItem = styled.div<{ isRight?: boolean }>` - height: 200px; background: red; - margin-right: ${(props) => (props.isRight ? '4rem' : 0)}; - margin-left: ${(props) => (props.isRight ? 0 : '4rem')}; + margin-right: ${(props) => (props.isRight ? '18%' : 0)}; + margin-left: ${(props) => (props.isRight ? 0 : '18%')}; `; export const Dot = styled.div<{ active: boolean }>` diff --git a/src/components/ShareGroup/ShareGroupImageItem/Styles.ts b/src/components/ShareGroup/ShareGroupImageItem/Styles.ts index 45e6734..2ea950a 100644 --- a/src/components/ShareGroup/ShareGroupImageItem/Styles.ts +++ b/src/components/ShareGroup/ShareGroupImageItem/Styles.ts @@ -3,8 +3,8 @@ import styled from 'styled-components'; export const Layout = styled.div<{ selected: boolean }>` border: ${({ selected, theme }) => selected ? `5px solid ${theme.colors.accent}` : '1px solid #fff'}; - width: 8rem; - height: 6rem; + width: 10rem; + height: 8rem; border-radius: 18px; `; diff --git a/src/utils/UseCarousel.tsx b/src/utils/UseCarousel.tsx index 1b259fb..2928679 100644 --- a/src/utils/UseCarousel.tsx +++ b/src/utils/UseCarousel.tsx @@ -12,7 +12,7 @@ export const useCarousel = ( const updateOffset = useCallback(() => { if (containerRef.current) { const containerWidth = containerRef.current.offsetWidth; - const newOffset = -currentIndex * containerWidth + currentIndex * 124.5; + const newOffset = -currentIndex * containerWidth * 0.65; setOffset(newOffset); } From 62d24bf03ffbaf41fe8498d7734847c5f8b725dd Mon Sep 17 00:00:00 2001 From: NekoGroove01 Date: Wed, 7 Aug 2024 21:03:42 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Feat:=20group=20=EC=A1=B0=ED=9A=8C=20api=20?= =?UTF-8?q?=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/getMyShareGroup.ts | 50 +++++++++++++++++++ .../ShareGroupFolderView.tsx | 2 +- .../ShareGroupFolder/ShareGroupFolder.tsx | 18 +++++-- .../ShareGroupMain/ShareGroupMain.tsx | 12 +++-- src/recoil/states/share_group.ts | 1 + 5 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 src/apis/getMyShareGroup.ts diff --git a/src/apis/getMyShareGroup.ts b/src/apis/getMyShareGroup.ts new file mode 100644 index 0000000..4b56088 --- /dev/null +++ b/src/apis/getMyShareGroup.ts @@ -0,0 +1,50 @@ +import { authInstance } from './instance'; + +interface IShareGroupInfo { + shareGroupId: number; + name: string; + image: string; + memberCount: number; + inviteUrl: string; + createdAt: string; +} + +interface profile { + profileId: number; // 프로필 id + name: string; // 프로필 이름 + image: string; // URL 형식 + memberId: number; // 해당 프로필로 참여한 회원의 id. 생략할지 고민중 +} + +interface IShareGroupMember { + shareGroupId: number; + name: string; + image: string; + memberCount: number; + inviteUrl: string; + createdAt: string; + profileInfoList: profile[]; +} + +// eslint-disable-next-line prettier/prettier +export async function getMyShareGroup(): Promise { + try { + const response = await authInstance().get('/shareGroups/my'); + return response.data.shareGroupInfoList; + } catch (error) { + console.error('Error fetching share group:', error); + throw error; + } +} + +export async function getShareGroupMembers( + shareGroupId: number, +): Promise { + try { + const response = await authInstance().get(`/shareGroups/${shareGroupId}`); + return response.data; + } catch (error) { + console.error('Error fetching share group members:', error); + throw error; + } +} diff --git a/src/components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView.tsx b/src/components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView.tsx index 6235b3b..9cf6c84 100644 --- a/src/components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView.tsx +++ b/src/components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView.tsx @@ -7,7 +7,7 @@ import { useRecoilState } from 'recoil'; import { shareGroupMemberListState } from 'recoil/states/share_group'; const ShareGroupFolderView: React.FC = () => { - const [items, setItems] = useRecoilState(shareGroupMemberListState); + const [items] = useRecoilState(shareGroupMemberListState); return ( diff --git a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx index eb85ace..5fcdbbd 100644 --- a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx +++ b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx @@ -1,16 +1,26 @@ // Share Group 1,2페이지 레이아웃 -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import Header from 'components/Header/Header'; import * as S from './Styles'; import ShareGroupFolderView from 'components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView'; import { useParams } from 'react-router-dom'; +import { useRecoilState } from 'recoil'; +import { shareGroupMemberListState } from 'recoil/states/share_group'; +import { getShareGroupMembers } from 'apis/getMyShareGroup'; const ShareGroupFolder: React.FC = () => { const { id } = useParams<{ id: string }>(); + const [shareGroupMember, setShareGroupMember] = useRecoilState( + shareGroupMemberListState, + ); - const getShareGroup = async (id: string): Promise => { - // shareGroupId로 api call - }; + // useEffect(() => { + // getShareGroupMembers(Number(id)).then((res) => { + // const { profileInfoList } = res; + // if (profileInfoList === null) return; + // setShareGroupMember(profileInfoList); + // }); + // }, [id]); return ( diff --git a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx index 22eb918..81b5518 100644 --- a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx +++ b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx @@ -7,16 +7,18 @@ import ShareGruopListView from 'components/ShareGroup/ShareGroupListView/ShareGr import ShareGroupAddButton from 'components/ShareGroup/ShareGroupAddButton/ShareGroupAddButton'; import { useRecoilState } from 'recoil'; import { shareGroupListState } from 'recoil/states/share_group'; +import { getMyShareGroup } from 'apis/getMyShareGroup'; const ShareGroupMain: React.FC = () => { - // 회원 정보를 바탕으로 공유 그룹 리스트를 가져와야 함' const [shareGroupList, setShareGroup] = useRecoilState(shareGroupListState); const [showButton, setShowButton] = useState(false); - useEffect(() => { - // 공유 그룹 리스트를 가져옴 - // setShareGroup(shareGroupList); - }, []); + // useEffect(() => { + // getMyShareGroup().then((res) => { + // if (res === null) return; + // setShareGroup(res); + // }); + // }, []); const handleClick = () => { setShowButton(!showButton); diff --git a/src/recoil/states/share_group.ts b/src/recoil/states/share_group.ts index bf35542..c994bec 100644 --- a/src/recoil/states/share_group.ts +++ b/src/recoil/states/share_group.ts @@ -12,6 +12,7 @@ interface ShareGroup { name: string; // 공유 그룹 이름 image: string; // 공유 그룹 이미지 URL memberCount: number; // 공유 그룹에 참여한 회원 수 + inviteUrl?: string; createdAt: string; // 공유 그룹 생성일 } From 146e8e690bf3a6c6cb513d3d107183fadfcac313 Mon Sep 17 00:00:00 2001 From: NekoGroove01 Date: Mon, 12 Aug 2024 14:45:09 +0900 Subject: [PATCH 3/8] =?UTF-8?q?Feat:=20API=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/deleteShareGroup.ts | 10 +++++++ src/apis/getMyInviteCode.ts | 29 +++++++++++++++++++ src/apis/getMyShareGroup.ts | 13 +++++++-- .../ShareGroupFolder/ShareGroupFolder.tsx | 14 ++++----- .../ShareGroupMain/ShareGroupMain.tsx | 13 +++++---- 5 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 src/apis/deleteShareGroup.ts create mode 100644 src/apis/getMyInviteCode.ts diff --git a/src/apis/deleteShareGroup.ts b/src/apis/deleteShareGroup.ts new file mode 100644 index 0000000..e4a0b5b --- /dev/null +++ b/src/apis/deleteShareGroup.ts @@ -0,0 +1,10 @@ +import { authInstance } from './instance'; + +export async function deleteShareGroup(shareGroupId: number): Promise { + try { + await authInstance().delete(`/shareGroups/${shareGroupId}`); + } catch (error) { + console.error('Error deleting share group:', error); + throw error; + } +} diff --git a/src/apis/getMyInviteCode.ts b/src/apis/getMyInviteCode.ts new file mode 100644 index 0000000..487e60f --- /dev/null +++ b/src/apis/getMyInviteCode.ts @@ -0,0 +1,29 @@ +import { authInstance } from './instance'; + +interface IInviteCode { + inviteCode: string; + inviteUrl: string; +} + +export async function getMyInviteCode({ + shareGroupId, +}: { + shareGroupId: number; +}): Promise { + try { + const response = await authInstance().get( + `/shareGroups/${shareGroupId}/invite`, + ); + if (response.status === 200) { + return { + inviteCode: response.data.inviteCode, + inviteUrl: response.data.inviteUrl, + }; + } else { + throw new Error('Failed to fetch invite code'); + } + } catch (error) { + console.error('Error fetching invite code:', error); + throw error; + } +} diff --git a/src/apis/getMyShareGroup.ts b/src/apis/getMyShareGroup.ts index 4b56088..6122df2 100644 --- a/src/apis/getMyShareGroup.ts +++ b/src/apis/getMyShareGroup.ts @@ -1,3 +1,4 @@ +import { ApiResponse } from 'recoil/types/notice'; import { authInstance } from './instance'; interface IShareGroupInfo { @@ -30,7 +31,11 @@ interface IShareGroupMember { export async function getMyShareGroup(): Promise { try { const response = await authInstance().get('/shareGroups/my'); - return response.data.shareGroupInfoList; + if (response.status === 200) { + return response.data.shareGroupInfoList; + } else { + throw new Error('Failed to fetch share group'); + } } catch (error) { console.error('Error fetching share group:', error); throw error; @@ -42,7 +47,11 @@ export async function getShareGroupMembers( ): Promise { try { const response = await authInstance().get(`/shareGroups/${shareGroupId}`); - return response.data; + if (response.status === 200) { + return response.data; + } else { + throw new Error('Failed to fetch share group members'); + } } catch (error) { console.error('Error fetching share group members:', error); throw error; diff --git a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx index 5fcdbbd..d37e74c 100644 --- a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx +++ b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx @@ -14,13 +14,13 @@ const ShareGroupFolder: React.FC = () => { shareGroupMemberListState, ); - // useEffect(() => { - // getShareGroupMembers(Number(id)).then((res) => { - // const { profileInfoList } = res; - // if (profileInfoList === null) return; - // setShareGroupMember(profileInfoList); - // }); - // }, [id]); + useEffect(() => { + getShareGroupMembers(Number(id)).then((res) => { + const { profileInfoList } = res; + if (profileInfoList === null) return; + setShareGroupMember(profileInfoList); + }); + }, [id]); return ( diff --git a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx index 81b5518..859e150 100644 --- a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx +++ b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx @@ -13,12 +13,13 @@ const ShareGroupMain: React.FC = () => { const [shareGroupList, setShareGroup] = useRecoilState(shareGroupListState); const [showButton, setShowButton] = useState(false); - // useEffect(() => { - // getMyShareGroup().then((res) => { - // if (res === null) return; - // setShareGroup(res); - // }); - // }, []); + useEffect(() => { + getMyShareGroup().then((res) => { + if (res === null) return; + console.log(res); + setShareGroup(res); + }); + }, []); const handleClick = () => { setShowButton(!showButton); From dbc21cc605a100af03bc5090b62457d7c186ef68 Mon Sep 17 00:00:00 2001 From: eomseona Date: Mon, 12 Aug 2024 18:10:56 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20vote=20=ED=88=AC=ED=91=9C=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 9 +++ package.json | 1 + src/components/Common/DropDown/Styles.ts | 2 +- src/components/Header/Styles.ts | 4 +- src/components/MyPage/MyPageMain.tsx | 31 +++------- src/components/MyPage/Styles.ts | 5 +- .../Vote/EmptyVoteBox/EmptyVoteBox.tsx | 2 +- src/components/Vote/VoteModal/VoteModal.tsx | 62 +++++++++---------- src/pages/EnterMain/EnterMain.tsx | 11 +++- src/pages/Vote/Styles.ts | 6 ++ src/pages/Vote/VoteMainPage.tsx | 4 +- src/pages/Vote/VotePage/Styles.ts | 54 ++++++++++++++-- src/pages/Vote/VotePage/VotePage.tsx | 37 ++++++++--- src/recoil/states/enter.ts | 13 ++++ src/recoil/states/share_group.ts | 1 - src/recoil/types/enter.ts | 6 ++ src/recoil/types/vote.ts | 1 + 17 files changed, 176 insertions(+), 73 deletions(-) create mode 100644 src/recoil/types/enter.ts diff --git a/package-lock.json b/package-lock.json index 9b00acf..f0f8234 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "react-scripts": "^5.0.1", "react-swipeable": "^7.0.1", "recoil": "^0.7.7", + "recoil-persist": "^5.1.0", "request": "^2.88.2", "source-map": "^0.7.4", "styled-components": "^6.1.11", @@ -13971,6 +13972,14 @@ } } }, + "node_modules/recoil-persist": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/recoil-persist/-/recoil-persist-5.1.0.tgz", + "integrity": "sha512-sew4k3uBVJjRWKCSFuBw07Y1p1pBOb0UxLJPxn4G2bX/9xNj+r2xlqYy/BRfyofR/ANfqBU04MIvulppU4ZC0w==", + "peerDependencies": { + "recoil": "^0.7.2" + } + }, "node_modules/recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", diff --git a/package.json b/package.json index 44a9f6e..d80f522 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "react-scripts": "^5.0.1", "react-swipeable": "^7.0.1", "recoil": "^0.7.7", + "recoil-persist": "^5.1.0", "request": "^2.88.2", "source-map": "^0.7.4", "styled-components": "^6.1.11", diff --git a/src/components/Common/DropDown/Styles.ts b/src/components/Common/DropDown/Styles.ts index bab5d2d..8194e73 100644 --- a/src/components/Common/DropDown/Styles.ts +++ b/src/components/Common/DropDown/Styles.ts @@ -38,7 +38,7 @@ export const ExpendLayout = styled.div` position: ${({ noIndexTag }) => (noIndexTag ? 'absolute' : 'relative')}; top: 10%; left: 2rem; - z-index: 1; + z-index: 2; `; export const IconLayout = styled.div` diff --git a/src/components/Header/Styles.ts b/src/components/Header/Styles.ts index 7b684a4..dc50f53 100644 --- a/src/components/Header/Styles.ts +++ b/src/components/Header/Styles.ts @@ -11,4 +11,6 @@ export const Layout = styled.div` padding: 0 1rem; `; -export const IconLayout = styled.button``; +export const IconLayout = styled.button` + cursor: pointer; +`; diff --git a/src/components/MyPage/MyPageMain.tsx b/src/components/MyPage/MyPageMain.tsx index 8648609..3efbbba 100644 --- a/src/components/MyPage/MyPageMain.tsx +++ b/src/components/MyPage/MyPageMain.tsx @@ -1,28 +1,22 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import * as S from './Styles'; import logoblurred from '../../assets/logo/typo-blurred.png'; import background from 'assets/background/cloudLeft.png'; -import { getMyInfo } from 'apis/getMyInfo'; -import { useSetRecoilState } from 'recoil'; +import { useRecoilValue, useSetRecoilState } from 'recoil'; import { myPageModalState, modalMessageState, modalDataState, } from 'recoil/states/mypage'; - -interface responseType { - name: string; - email: string; - image: string; - memberId: number; // memberId 추가 -} +import { UserState } from 'recoil/states/enter'; const MyPageMain = () => { - const [data, setData] = useState(); + const userInfo = useRecoilValue(UserState); const setModalOpen = useSetRecoilState(myPageModalState); const setModalMessage = useSetRecoilState(modalMessageState); const setModalData = useSetRecoilState(modalDataState); + const openLogoutModal = () => { setModalMessage('로그아웃 하시겠습니까?'); setModalOpen(true); @@ -30,24 +24,19 @@ const MyPageMain = () => { const openWithdrawalModal = () => { setModalMessage('탈퇴하시겠습니까? 데이터는 복구할 수 없습니다.'); - if (data) { - setModalData({ memberId: data.memberId }); + if (userInfo) { + setModalData({ memberId: userInfo.memberId }); setModalOpen(true); } else setModalOpen(true); }; - useEffect(() => { - getMyInfo() - .then((res) => setData(res.data)) - .catch((error) => console.error(error)); - }, []); return ( - + - {data?.email} - {data?.name} + {userInfo?.email} + {userInfo?.name} diff --git a/src/components/MyPage/Styles.ts b/src/components/MyPage/Styles.ts index a486b12..39d8599 100644 --- a/src/components/MyPage/Styles.ts +++ b/src/components/MyPage/Styles.ts @@ -18,7 +18,7 @@ export const ProfileContainer = styled.div` transform: translate(-50%, -50%); `; -export const Profile = styled.div<{ image?: string }>` +export const Profile = styled.img` position: absolute; width: 35%; height: 16%; @@ -26,8 +26,7 @@ export const Profile = styled.div<{ image?: string }>` top: 35%; left: 50%; transform: translate(-50%, -50%); - background-image: ${(props) => - props.image ? `url(${props.image})` : `url(${I.Profile})`}; + object-fit: cover; `; export const EmailText = styled.div` diff --git a/src/components/Vote/EmptyVoteBox/EmptyVoteBox.tsx b/src/components/Vote/EmptyVoteBox/EmptyVoteBox.tsx index 75c3747..f01902d 100644 --- a/src/components/Vote/EmptyVoteBox/EmptyVoteBox.tsx +++ b/src/components/Vote/EmptyVoteBox/EmptyVoteBox.tsx @@ -14,7 +14,7 @@ const EmptyVoteBox: React.FC = () => { 아직 안건이 없어요. 새로운 안건을 추가해주세요. - + 안건 추가하기 diff --git a/src/components/Vote/VoteModal/VoteModal.tsx b/src/components/Vote/VoteModal/VoteModal.tsx index 9af83d2..c28dba9 100644 --- a/src/components/Vote/VoteModal/VoteModal.tsx +++ b/src/components/Vote/VoteModal/VoteModal.tsx @@ -1,14 +1,13 @@ import React, { useState } from 'react'; import * as S from './Styles'; import { CloseModal, NextArrow } from 'assets/icon'; -import { useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilState, useSetRecoilState } from 'recoil'; import { isModalOpen, selectedPic } from 'recoil/states/vote'; -import { ParticularAgendaVote } from 'apis/vote'; + const VoteModal = () => { const setIsOpen = useSetRecoilState(isModalOpen); - const data = useRecoilValue(selectedPic); + const [data, setData] = useRecoilState(selectedPic); const [comment, setComment] = useState(''); - const [isSubmitting, setIsSubmitting] = useState(false); const handleChange = (e: React.ChangeEvent) => { setComment(e.target.value); @@ -16,33 +15,32 @@ const VoteModal = () => { const handleIconClick = () => { setIsOpen(false); }; - const handleSubmit = async () => { - setIsSubmitting(true); // API 호출 시작 - try { - // 투표할 내용 - const voteData = [ - { - comment: comment, - agendaPhotoId: data.pictureId, // 선택된 사진 ID - }, - ]; - - // 특정 안건에 대한 투표 API 호출 - await ParticularAgendaVote(data.pictureId, voteData); - console.log('Vote successfully submitted!'); - - setIsOpen(false); // 모달 닫기 - } catch (error) { - if (error instanceof Error) { - console.error('Error submitting vote:', error.message); - alert('투표 제출 중 오류가 발생했습니다. 다시 시도해 주세요.'); - } else { - console.error('Unknown error occurred:', error); - alert('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.'); - } - } finally { - setIsSubmitting(false); // API 호출 종료 - } + const handleSubmit = () => { + setData({ ...data, comment: comment }); + setIsOpen(false); + // try { + // // 투표할 내용 + // const voteData = [ + // { + // comment: comment, + // agendaPhotoId: data.pictureId, // 선택된 사진 ID + // }, + // ]; + // // 특정 안건에 대한 투표 API 호출 + // await ParticularAgendaVote(data.pictureId, voteData); + // console.log('Vote successfully submitted!'); + // setIsOpen(false); // 모달 닫기 + // } catch (error) { + // if (error instanceof Error) { + // console.error('Error submitting vote:', error.message); + // alert('투표 제출 중 오류가 발생했습니다. 다시 시도해 주세요.'); + // } else { + // console.error('Unknown error occurred:', error); + // alert('알 수 없는 오류가 발생했습니다. 다시 시도해 주세요.'); + // } + // } finally { + // setIsSubmitting(false); // API 호출 종료 + // } }; return ( @@ -59,7 +57,7 @@ const VoteModal = () => { onChange={handleChange} value={comment} /> - + 투표 하기 diff --git a/src/pages/EnterMain/EnterMain.tsx b/src/pages/EnterMain/EnterMain.tsx index ef39b1c..c178ff1 100644 --- a/src/pages/EnterMain/EnterMain.tsx +++ b/src/pages/EnterMain/EnterMain.tsx @@ -1,11 +1,20 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import * as S from './Styles'; import sky from '../../assets/background/sky.png'; import TypoBlurred from '../../assets/logo/typo-blurred.png'; import symbol from '../../assets/logo/symbol.png'; import { Link, Outlet } from 'react-router-dom'; +import { getMyInfo } from 'apis/getMyInfo'; +import { useSetRecoilState } from 'recoil'; +import { UserState } from 'recoil/states/enter'; const EnterMain = () => { + const setUserInfo = useSetRecoilState(UserState); + useEffect(() => { + getMyInfo() + .then((res) => setUserInfo(res.data)) + .catch((error) => console.error(error)); + }, []); return ( <> diff --git a/src/pages/Vote/Styles.ts b/src/pages/Vote/Styles.ts index c0d304b..9305d08 100644 --- a/src/pages/Vote/Styles.ts +++ b/src/pages/Vote/Styles.ts @@ -30,3 +30,9 @@ export const BackLayout = styled.div` background: rgba(0, 0, 0, 0.5); z-index: 2; `; + +export const DropDownBox = styled.div` + position: absolute; + top: 10%; + left: 0; +`; diff --git a/src/pages/Vote/VoteMainPage.tsx b/src/pages/Vote/VoteMainPage.tsx index a9de0ab..4eeecf7 100644 --- a/src/pages/Vote/VoteMainPage.tsx +++ b/src/pages/Vote/VoteMainPage.tsx @@ -41,7 +41,9 @@ const VoteMainPage = () => { {(isOpen || isAlerted) && } {isAlerted && }
- + + + {component} ); diff --git a/src/pages/Vote/VotePage/Styles.ts b/src/pages/Vote/VotePage/Styles.ts index 086405d..95e7291 100644 --- a/src/pages/Vote/VotePage/Styles.ts +++ b/src/pages/Vote/VotePage/Styles.ts @@ -1,3 +1,4 @@ +import { CloseBtnRound } from 'assets/icon'; import styled from 'styled-components'; export const Layout = styled.div` @@ -8,19 +9,64 @@ export const Layout = styled.div` gap: 1.5rem 0.5rem; `; -export const ImgLayout = styled.div` +export const Container = styled.div` width: 8rem; position: relative; - border-radius: 0.5rem; - overflow: hidden; `; -export const ImgBox = styled.img` +export const ImgLayout = styled.div` width: 8rem; height: 6rem; + border-radius: 0.9rem; + border: 2px solid white; + overflow: hidden; +`; + +export const ImgBox = styled.img` + width: 100%; + height: 100%; + cursor: pointer; + object-fit: cover; +`; + +export const VoterLayout = styled.div<{ click?: boolean }>` + width: 100%; + display: flex; + align-items: center; + position: absolute; + bottom: -10%; + border-radius: 1.6rem; + background: ${(props) => + props.click ? 'rgba(255, 255, 255, 0.92)' : 'none'}; + backdrop-filter: ${(props) => (props.click ? 'blur(2px)' : 'none')}; +`; + +export const VoterContainer = styled.div<{ click?: boolean }>` + display: ${(props) => (props.click ? 'block' : 'none')}; + width: 5rem; + height: 100%; + padding-left: 0.2rem; + color: #1d3a72; + font-size: 0.7rem; + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +`; + +export const VoterBox = styled.img` + width: 1.9rem; + height: 1.9rem; + border-radius: 50%; + border: 2px solid white; cursor: pointer; `; +export const CloseButton = styled(CloseBtnRound)` + position: absolute; + right: 0.3rem; +`; + export const ButtonLayout = styled.button` width: 90%; position: absolute; diff --git a/src/pages/Vote/VotePage/VotePage.tsx b/src/pages/Vote/VotePage/VotePage.tsx index da4eb49..ce49c2e 100644 --- a/src/pages/Vote/VotePage/VotePage.tsx +++ b/src/pages/Vote/VotePage/VotePage.tsx @@ -1,12 +1,12 @@ -import React from 'react'; +import React, { useState } from 'react'; import * as S from './Styles'; import VoteTitle from 'components/Vote/VoteTitle/VoteTitle'; import { CloudNextBtn } from 'assets/icon'; import VoteModal from 'components/Vote/VoteModal/VoteModal'; -import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; +import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'; import { isModalOpen, selectedPic, registeredPics } from 'recoil/states/vote'; -import VoterBox from 'components/Vote/VoterBox/VoterBox'; import { useLocation, useNavigate } from 'react-router-dom'; +import { UserState } from 'recoil/states/enter'; const VotePage = () => { const [isOpen, setIsOpen] = useRecoilState(isModalOpen); @@ -14,7 +14,11 @@ const VotePage = () => { const location = useLocation(); const title = location.state?.title; const pictures = useRecoilValue(registeredPics); - const setSelectedPic = useSetRecoilState(selectedPic); + const [selectedPicture, setSelectedPic] = useRecoilState(selectedPic); + const resetSelect = useResetRecoilState(selectedPic); + const profile = useRecoilValue(UserState); + const [click, setClick] = useState(false); + const handleClickBtn = () => { navigate('/vote/list'); }; @@ -22,15 +26,34 @@ const VotePage = () => { setIsOpen(true); setSelectedPic(pictures[idx]); }; + const handleCloseClick = () => { + resetSelect(); + }; + return ( <> {isOpen && } {pictures.map((pic, idx) => ( - - handleImgClick(idx)} /> - + + + handleImgClick(idx)} /> + + {selectedPicture.comment && + selectedPicture.pictureId === pic.pictureId && ( + + setClick(!click)} + /> + + {selectedPicture.comment} + + + + )} + ))} diff --git a/src/recoil/states/enter.ts b/src/recoil/states/enter.ts index 7efb48f..0d6c1ff 100644 --- a/src/recoil/states/enter.ts +++ b/src/recoil/states/enter.ts @@ -1,4 +1,11 @@ import { atom } from 'recoil'; +import { UserStateType } from 'recoil/types/enter'; +import { recoilPersist } from 'recoil-persist'; + +const { persistAtom } = recoilPersist({ + key: 'persist-atom-key', + storage: localStorage, +}); export const loginState = atom({ key: 'loginState', @@ -9,3 +16,9 @@ export const clauseState = atom({ key: 'clauseState', default: { isClauseIn: false }, }); + +export const UserState = atom({ + key: 'UserState', + default: undefined, + effects_UNSTABLE: [persistAtom], +}); diff --git a/src/recoil/states/share_group.ts b/src/recoil/states/share_group.ts index d66fd3c..c598d0f 100644 --- a/src/recoil/states/share_group.ts +++ b/src/recoil/states/share_group.ts @@ -12,7 +12,6 @@ interface ShareGroup { name: string; // 공유 그룹 이름 image: string; // 공유 그룹 이미지 URL memberCount: number; // 공유 그룹에 참여한 회원 수 - inviteUrl?: string; createdAt: string; // 공유 그룹 생성일 inviteUrl: string; } diff --git a/src/recoil/types/enter.ts b/src/recoil/types/enter.ts new file mode 100644 index 0000000..be3935d --- /dev/null +++ b/src/recoil/types/enter.ts @@ -0,0 +1,6 @@ +export interface UserStateType { + name: string; + email: string; + image: string; + memberId: number; // memberId 추가 +} diff --git a/src/recoil/types/vote.ts b/src/recoil/types/vote.ts index 1863840..b1f0a22 100644 --- a/src/recoil/types/vote.ts +++ b/src/recoil/types/vote.ts @@ -31,6 +31,7 @@ export interface profileInfo { export interface registeredPicsType { pictureId: number; url: string; + comment?: string; } export interface PostApiResponse { From c539899d934281ff0e40b3b45a56d4691742b3c3 Mon Sep 17 00:00:00 2001 From: eomseona Date: Mon, 12 Aug 2024 18:21:06 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20group=20=EB=9D=BC=EC=9A=B0=ED=8C=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/background/cloud_upper_below.png | Bin 61892 -> 59162 bytes .../ShareGroupAddButton.tsx | 4 ++-- src/pages/Vote/VoteMainPage.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/assets/background/cloud_upper_below.png b/src/assets/background/cloud_upper_below.png index 36d6cc9223e1570866cbc6e6909a403295dee871..36abe1941b96c9ab0e09069087d0319618f3c7c4 100644 GIT binary patch literal 59162 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 LqgJZ&B=G+LE8PIO literal 61892 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 = ({ {showButton && ( - + - + diff --git a/src/pages/Vote/VoteMainPage.tsx b/src/pages/Vote/VoteMainPage.tsx index 4eeecf7..bbdd2d2 100644 --- a/src/pages/Vote/VoteMainPage.tsx +++ b/src/pages/Vote/VoteMainPage.tsx @@ -40,7 +40,7 @@ const VoteMainPage = () => { {(isOpen || isAlerted) && } {isAlerted && } -
+
From 71ad8168c6e057b81ceea30501efee88f03d23df Mon Sep 17 00:00:00 2001 From: eomseona Date: Tue, 13 Aug 2024 01:23:15 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=EC=83=98=ED=94=8C=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20api=20=EC=97=B0=EB=8F=99=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/getMembers.ts | 22 ++++ src/apis/getMyShareGroup.ts | 4 +- src/apis/postPhotoUpload.ts | 8 +- src/apis/postPresignedUrl.ts | 1 - "src/assets/samples/\bemptyProfile.png" | Bin 0 -> 8887 bytes .../ShareGroupCarouselItem.tsx | 13 +- .../ShareGroupCloudButton.tsx | 1 - .../ShareGroupListItem/ShareGroupListItem.tsx | 5 +- .../ShareGroupListView/ShareGruopListView.tsx | 4 + .../ShareGroup/ShareGroupRectButton/Styles.ts | 2 +- .../ShareGroupTopButton.tsx | 13 +- .../ShareGroup/ShareGroupTopButton/Styles.ts | 4 +- .../navigationbar/NavigationBar.tsx | 28 +++- src/components/navigationbar/Styles.ts | 18 ++- src/pages/EnterMain/EnterGuide/EnterGuide.tsx | 32 ++++- src/pages/EnterMain/EnterMain.tsx | 14 +- src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx | 120 ++++++++++++++++-- src/pages/EnterMain/EnterPhoto/Styles.ts | 16 ++- .../EnterMain/EnterProfile/EnterProfile.tsx | 41 +++--- src/pages/EnterMain/EnterProfile/Styles.ts | 27 ++-- .../ShareGroupFolder/ShareGroupFolder.tsx | 8 +- .../ShareGroupMain/ShareGroupMain.tsx | 1 - src/recoil/selectors/sharegroup.ts | 13 ++ src/recoil/states/share_group.ts | 39 ++---- src/recoil/types/members.ts | 9 ++ 25 files changed, 321 insertions(+), 122 deletions(-) create mode 100644 "src/assets/samples/\bemptyProfile.png" create mode 100644 src/recoil/selectors/sharegroup.ts diff --git a/src/apis/getMembers.ts b/src/apis/getMembers.ts index 0cddfb1..0bc03df 100644 --- a/src/apis/getMembers.ts +++ b/src/apis/getMembers.ts @@ -3,6 +3,7 @@ import { emailResponse, marketingResponse, deleteResponse, + samplePhotoResponse, } from '../recoil/types/members'; import axios from 'axios'; @@ -81,3 +82,24 @@ export const deleteUser = async (memberId: number) => { } } }; + +// 샘플 사진 업로드 여부 조회 (GET) +export const getHasSamplePhoto = async () => { + try { + const response = + await authInstance().get(`/members/samplePhoto`); + const { status, code, message, data } = response.data; + + if (status === 200) { + return data.hasSamplePhoto; + } else { + throw new Error(`Error ${code}: ${message}`); + } + } catch (err: unknown) { + if (axios.isAxiosError(err)) { + throw new Error(`Axios error: ${err.message}`); + } else { + throw new Error('샘플 사진 업로드 여부 조회 중 오류 발생.'); + } + } +}; diff --git a/src/apis/getMyShareGroup.ts b/src/apis/getMyShareGroup.ts index 6122df2..9c060d6 100644 --- a/src/apis/getMyShareGroup.ts +++ b/src/apis/getMyShareGroup.ts @@ -32,7 +32,7 @@ export async function getMyShareGroup(): Promise { try { const response = await authInstance().get('/shareGroups/my'); if (response.status === 200) { - return response.data.shareGroupInfoList; + return response.data.data.shareGroupInfoList; } else { throw new Error('Failed to fetch share group'); } @@ -48,7 +48,7 @@ export async function getShareGroupMembers( try { const response = await authInstance().get(`/shareGroups/${shareGroupId}`); if (response.status === 200) { - return response.data; + return response.data.data; } else { throw new Error('Failed to fetch share group members'); } diff --git a/src/apis/postPhotoUpload.ts b/src/apis/postPhotoUpload.ts index 6631d81..af20238 100644 --- a/src/apis/postPhotoUpload.ts +++ b/src/apis/postPhotoUpload.ts @@ -1,7 +1,7 @@ import { PostApiResponse } from 'recoil/types/notice'; import { authInstance } from './instance'; interface requestProp { - shareGroupId: number; + shareGroupId?: number; photoUrlList: string[]; } @@ -9,10 +9,8 @@ export const postPhotoUpload = async ( requestData: requestProp, ): Promise<{ data: any }> => { try { - const res = await authInstance().post( - `/photos/upload`, - requestData, - ); + const url = requestData.shareGroupId ? '/photos/upload' : '/photos/sample'; + const res = await authInstance().post(url, requestData); const { status, code, message, data } = res.data; if (status === 200) { return { data }; diff --git a/src/apis/postPresignedUrl.ts b/src/apis/postPresignedUrl.ts index 51abd87..3a2fede 100644 --- a/src/apis/postPresignedUrl.ts +++ b/src/apis/postPresignedUrl.ts @@ -2,7 +2,6 @@ import { PostApiResponse } from 'recoil/types/notice'; import { authInstance } from './instance'; interface requestProp { - shareGroupId: number; photoNameList: string[]; } diff --git "a/src/assets/samples/\bemptyProfile.png" "b/src/assets/samples/\bemptyProfile.png" new file mode 100644 index 0000000000000000000000000000000000000000..5cb8340fc82f5b0501832fb179d40a4a87c1306c GIT binary patch literal 8887 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 = ({ active={active} onClick={() => navigatte(`/group/detail`, { - state: { shareGroupId: id, profileId: profileId }, + state: { + shareGroupId: id, + profileId: profileId, + profileImage: profileImage, + }, }) } > @@ -30,9 +35,9 @@ const ShareGroupCarouselItem: React.FC = ({ {profileImage ? ( - + ) : ( - + )} {name} diff --git a/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx b/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx index 0a1d938..617a247 100644 --- a/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx +++ b/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx @@ -30,7 +30,6 @@ const ShareGroupCloudButton: React.FC = () => { setFile(fileList); if (nameList) { const requestData = { - shareGroupId: 2, photoNameList: nameList, }; try { diff --git a/src/components/ShareGroup/ShareGroupListItem/ShareGroupListItem.tsx b/src/components/ShareGroup/ShareGroupListItem/ShareGroupListItem.tsx index 073f7f8..06e10ac 100644 --- a/src/components/ShareGroup/ShareGroupListItem/ShareGroupListItem.tsx +++ b/src/components/ShareGroup/ShareGroupListItem/ShareGroupListItem.tsx @@ -1,5 +1,6 @@ import React from 'react'; import * as S from './Styles'; +import defaultProfile from '../../../assets/samples/emptyProfile.png'; interface ListProps { name: string; @@ -17,10 +18,10 @@ const ShareGroupListItem: React.FC = ({ return ( - {image !== '' ? ( + {image ? ( ) : ( - + )} = ({ items }) => { + const setSelectedGroup = useSetRecoilState(selectedGroupName); return ( {items.map((item) => ( setSelectedGroup(item.name)} > diff --git a/src/components/ShareGroup/ShareGroupRectButton/Styles.ts b/src/components/ShareGroup/ShareGroupRectButton/Styles.ts index da46f9a..fc5c709 100644 --- a/src/components/ShareGroup/ShareGroupRectButton/Styles.ts +++ b/src/components/ShareGroup/ShareGroupRectButton/Styles.ts @@ -6,11 +6,11 @@ export const Layout = styled.div` flex-direction: column; align-items: center; justify-content: center; - background: red; `; export const Rect = styled(I.Rectangle)` position: absolute; + width: 45%; `; export const RectText = styled.p` diff --git a/src/components/ShareGroup/ShareGroupTopButton/ShareGroupTopButton.tsx b/src/components/ShareGroup/ShareGroupTopButton/ShareGroupTopButton.tsx index 0127ae2..ddf1e62 100644 --- a/src/components/ShareGroup/ShareGroupTopButton/ShareGroupTopButton.tsx +++ b/src/components/ShareGroup/ShareGroupTopButton/ShareGroupTopButton.tsx @@ -1,18 +1,25 @@ import React from 'react'; import * as S from './Styles'; +import { useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; +import { groupSelectorbyId } from 'recoil/selectors/sharegroup'; const ShareGroupTopButton: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const int = parseInt(id || '0'); + const group = useRecoilValue(groupSelectorbyId(int)); + return ( - 2024 졸업 전시 + {group.name} - 12 + {group.memberCount} - 1232.23.12 + {group.createdAt} diff --git a/src/components/ShareGroup/ShareGroupTopButton/Styles.ts b/src/components/ShareGroup/ShareGroupTopButton/Styles.ts index 4dbe49f..a5a4f86 100644 --- a/src/components/ShareGroup/ShareGroupTopButton/Styles.ts +++ b/src/components/ShareGroup/ShareGroupTopButton/Styles.ts @@ -17,7 +17,7 @@ export const Layout = styled.div` export const Container = styled.div` width: 100%; height: 100%; - padding: 0 1.25rem; + padding: 0 1rem; display: flex; flex-direction: column; justify-content: space-evenly; @@ -25,7 +25,7 @@ export const Container = styled.div` `; export const Title = styled.p` - font-size: 0.9rem; + font-size: 0.7rem; color: ${({ theme }) => theme.colors.tertiary}; font-weight: 600; `; diff --git a/src/components/navigationbar/NavigationBar.tsx b/src/components/navigationbar/NavigationBar.tsx index d90fc5f..7156869 100644 --- a/src/components/navigationbar/NavigationBar.tsx +++ b/src/components/navigationbar/NavigationBar.tsx @@ -1,17 +1,41 @@ -import React from 'react'; +import React, { useState } from 'react'; import * as S from './Styles'; import { AddBtn, HomeBtn, NotificationBtn } from 'assets/icon'; +import ShareGroupRectButton from 'components/ShareGroup/ShareGroupRectButton/ShareGroupRectButton'; +import { getHasSamplePhoto } from 'apis/getMembers'; +import { useNavigate } from 'react-router-dom'; const NavigationBar = () => { + const [isClicked, setIsClicked] = useState(true); + const navigate = useNavigate(); + const handleButtonClick = (add?: boolean) => { + getHasSamplePhoto().then((res) => { + if (!res) navigate('/login/profile'); + else { + if (add) navigate('add/member'); + else navigate('join'); + } + }); + }; return ( - + setIsClicked(!isClicked)}> + {isClicked && ( + + handleButtonClick()}> + + + handleButtonClick()}> + + + + )} ); }; diff --git a/src/components/navigationbar/Styles.ts b/src/components/navigationbar/Styles.ts index caf1200..8136503 100644 --- a/src/components/navigationbar/Styles.ts +++ b/src/components/navigationbar/Styles.ts @@ -1,3 +1,4 @@ +import { NavLink } from 'react-router-dom'; import styled from 'styled-components'; export const Layout = styled.div` @@ -25,7 +26,20 @@ export const IconLayout = styled.div` gap: 30%; `; -export const AddButtonBox = styled.div` - width: 10%; +export const AddButtonBox = styled.button` position: relative; `; + +export const RectContainer = styled.div` + position: absolute; + bottom: 6rem; + width: 100%; + display: flex; + justify-content: space-evenly; + gap: 1rem; + align-items: center; +`; + +export const RectBox = styled.div` + cursor: pointer; +`; diff --git a/src/pages/EnterMain/EnterGuide/EnterGuide.tsx b/src/pages/EnterMain/EnterGuide/EnterGuide.tsx index 42cb1ec..2126c96 100644 --- a/src/pages/EnterMain/EnterGuide/EnterGuide.tsx +++ b/src/pages/EnterMain/EnterGuide/EnterGuide.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import * as S from './Styles'; import sky from '../../../assets/background/sky_dark.png'; import * as I from 'assets/icon'; @@ -6,6 +6,23 @@ import { useNavigate } from 'react-router-dom'; const EnterGuide = () => { const navigate = useNavigate(); + const [file, setFile] = useState(); + + const handleAddButtonClick = () => { + const fileInput = document.getElementById('file') as HTMLInputElement; + fileInput.click(); + }; + + const handleChangeFile = (event: React.ChangeEvent) => { + const fileList = event?.target.files; + setFile(fileList); + }; + + useEffect(() => { + if (file) { + navigate('add', { state: { file } }); + } + }, [file]); return ( <> @@ -37,8 +54,17 @@ const EnterGuide = () => { 위 가이드 라인을 준수하는 사진을
2장 이상 추가해주세요. - navigate('add')} /> - 사진 추가하기 +
+ + + 사진 추가하기 +
diff --git a/src/pages/EnterMain/EnterMain.tsx b/src/pages/EnterMain/EnterMain.tsx index c178ff1..f9f0cb0 100644 --- a/src/pages/EnterMain/EnterMain.tsx +++ b/src/pages/EnterMain/EnterMain.tsx @@ -3,17 +3,19 @@ import * as S from './Styles'; import sky from '../../assets/background/sky.png'; import TypoBlurred from '../../assets/logo/typo-blurred.png'; import symbol from '../../assets/logo/symbol.png'; -import { Link, Outlet } from 'react-router-dom'; +import { Link, Outlet, useNavigate } from 'react-router-dom'; import { getMyInfo } from 'apis/getMyInfo'; -import { useSetRecoilState } from 'recoil'; +import { useRecoilState } from 'recoil'; import { UserState } from 'recoil/states/enter'; const EnterMain = () => { - const setUserInfo = useSetRecoilState(UserState); + const [userInfo, setUserInfo] = useRecoilState(UserState); + const navigate = useNavigate(); useEffect(() => { - getMyInfo() - .then((res) => setUserInfo(res.data)) - .catch((error) => console.error(error)); + if (!userInfo) { + getMyInfo().then((res) => setUserInfo(res.data)); + } + navigate('/group'); }, []); return ( <> diff --git a/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx b/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx index 568a953..9e3a09d 100644 --- a/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx +++ b/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx @@ -1,8 +1,93 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import * as S from './Styles'; import sky from '../../../assets/background/sky_dark.png'; +import { useLocation, useNavigate } from 'react-router-dom'; +import { postPresignedUrl } from 'apis/postPresignedUrl'; +import axios from 'axios'; +import { postPhotoUpload } from 'apis/postPhotoUpload'; + +interface responseProp { + photoName: string; + photoUrl: string; + preSignedUrl: string; +} const EnterPhoto = () => { + const navigate = useNavigate(); + const location = useLocation(); + const state = Array.from(location.state?.file as File[]); + const [files, setFiles] = useState(state); + const [previews, setPreviews] = useState([]); + const [response, setResponse] = useState([]); + const [photoUrl, setPhotoUrl] = useState([]); + + const handleCloseClick = (id: number) => { + if (files) { + const newFiles = files.filter((_: any, index: number) => index !== id); + setFiles(newFiles); + } + }; + + const handleAddButtonClick = () => { + const fileInput = document.getElementById('file') as HTMLInputElement; + fileInput.click(); + }; + + const handleChangeFile = (event: React.ChangeEvent) => { + const fileList = event?.target.files; + if (files && fileList) { + const newFiles = files.concat(Array.from(fileList)); // 기존 파일과 새로운 파일 병합 + setFiles(newFiles); + } + }; + + const handleSubmit = async () => { + if (files && files.length < 2) alert('사진을 두 장 이상 선택하세요!'); + else if (files) { + const nameList = files.map((file: File) => file.name); + if (nameList) { + const preSignedData = { + photoNameList: nameList, + }; + try { + const { data } = await postPresignedUrl(preSignedData); + const photoUrls = data.preSignedUrlInfoList.map( + (item: any) => item.photoUrl, + ); + setResponse(data.preSignedUrlInfoList); + setPhotoUrl(photoUrls); + const uploadPromises = files.map(async (fileItem, index) => { + const presignedUrl = response[index]?.preSignedUrl; + if (presignedUrl) { + await axios.put(presignedUrl, fileItem, { + headers: { + 'Content-Type': fileItem.type, // 파일의 MIME 타입 설정 + }, + withCredentials: true, + }); + } + }); + await Promise.all(uploadPromises); // 모든 업로드가 완료될 때까지 대기 + const requestData = { + photoUrlList: photoUrl || [], + }; + postPhotoUpload(requestData); + } catch (error) { + console.error('Error: ', error); + } + navigate('/'); + } + } + }; + + useEffect(() => { + if (files) { + const array = Array.from(files) || []; + const newPreview = array.map((fl: any) => URL.createObjectURL(fl)); + setPreviews(newPreview); + } + }, [files]); + return ( <> @@ -11,20 +96,31 @@ const EnterPhoto = () => { 정면, 측면 사진을 각각 한 장씩 추가 해주세요. + - - - - - - + {previews.map((p, idx) => ( + + + handleCloseClick(idx)} /> + + ))} + {previews.length < 2 ? : null} + {previews.length < 1 ? : null} - - - 사진 추가 + + + + 사진 추가 + - - 사진 선택 완료 + + 사진 선택 완료 ); diff --git a/src/pages/EnterMain/EnterPhoto/Styles.ts b/src/pages/EnterMain/EnterPhoto/Styles.ts index 0f21e3b..0792b5f 100644 --- a/src/pages/EnterMain/EnterPhoto/Styles.ts +++ b/src/pages/EnterMain/EnterPhoto/Styles.ts @@ -53,17 +53,25 @@ export const GuideContainer = styled.div` export const GuideBox = styled.div` width: 6rem; height: 6rem; - border-radius: 5%; position: relative; + border-radius: 5%; background-color: gray; `; +export const GuideImg = styled.img` + width: 100%; + height: 100%; + border-radius: 5%; + object-fit: cover; +`; + export const CloseBtn = styled(I.CloseModal)` - width: 12%; position: absolute; - top: -12%; + top: -10%; right: 0; cursor: pointer; + width: 15%; + z-index: 100; `; export const SubmitBtn = styled(I.Buttonrect)` @@ -90,6 +98,7 @@ export const PhotoAddBtn = styled(I.ButtonSmall)` width: 25%; top: 53%; right: 15%; + cursor: pointer; `; export const PhotoAddText = styled.div` @@ -100,6 +109,7 @@ export const PhotoAddText = styled.div` color: #4879af; font-weight: bolder; font-size: 0.8rem; + cursor: pointer; `; export const PhotoPlus = styled(I.AddSmall)` diff --git a/src/pages/EnterMain/EnterProfile/EnterProfile.tsx b/src/pages/EnterMain/EnterProfile/EnterProfile.tsx index e1aa26a..96f5803 100644 --- a/src/pages/EnterMain/EnterProfile/EnterProfile.tsx +++ b/src/pages/EnterMain/EnterProfile/EnterProfile.tsx @@ -2,32 +2,35 @@ import React from 'react'; import * as S from './Styles'; import skydark from '../../../assets/background/sky_dark.png'; import { Link, Outlet } from 'react-router-dom'; +import { useRecoilState } from 'recoil'; +import { UserState } from 'recoil/states/enter'; +import { getMyInfo } from 'apis/getMyInfo'; const EnterProfile = () => { + const [user, setUserInfo] = useRecoilState(UserState); + if (!user) { + getMyInfo().then((res) => setUserInfo(res.data)); + } return ( <> - - - -
이메일
- -
이름
-
-
- - -
사진 분류를 위해 인공지능을 학습 시킬 거에요.
-
학습에 필요한 얼굴 사진을 추가해 주세요.
-
- - -
사진 추가하기
-
- -
+ + + {user.email} + {user.name} + + + +
사진 분류를 위해 인공지능을 학습 시킬 거에요.
+
학습에 필요한 얼굴 사진을 추가해 주세요.
+
+ + +
사진 추가하기
+
+
diff --git a/src/pages/EnterMain/EnterProfile/Styles.ts b/src/pages/EnterMain/EnterProfile/Styles.ts index 0a79594..a1321c9 100644 --- a/src/pages/EnterMain/EnterProfile/Styles.ts +++ b/src/pages/EnterMain/EnterProfile/Styles.ts @@ -4,18 +4,12 @@ import * as I from 'assets/icon'; export const Layout = styled.div` width: 100%; height: 100%; - z-index: 40; `; export const Background = styled.img` width: 100%; height: 100%; position: absolute; - z-index: 40; -`; - -export const ProfileContainer = styled.div` - z-index: 40; `; export const Name = styled.div` @@ -24,7 +18,6 @@ export const Name = styled.div` `; export const ProfileBox = styled.div` - z-index: 40; color: white; position: absolute; top: 48%; @@ -35,19 +28,21 @@ export const ProfileBox = styled.div` transform: translate(-50%, -50%); `; -export const Profile = styled(I.Profile)` - z-index: 40; +export const Profile = styled.img` position: absolute; - width: 35%; - height: 100%; + width: 7rem; + height: 7rem; + border: 2px solid white; + border-radius: 50%; top: 37%; left: 50%; transform: translate(-50%, -50%); + object-fit: cover; `; export const ProfileLine = styled(I.Line_star)` - z-index: 40; position: absolute; + width: 80%; top: 55%; left: 50%; transform: translate(-50%, -50%); @@ -59,7 +54,6 @@ export const ProfileGuide = styled.div` top: 60%; left: 50%; transform: translate(-50%, -50%); - z-index: 40; font-size: 15px; color: white; text-align: center; @@ -69,24 +63,23 @@ export const ProfileGuide = styled.div` `; export const PhotoAdd = styled(I.Buttonrect)` - z-index: 40; position: absolute; + width: 55%; top: 70%; left: 50%; transform: translate(-50%, -50%); `; export const PhotoPlus = styled(I.AddBtn)` - z-index: 40; position: absolute; + width: 7%; top: 70%; - left: 50%; + left: 54%; transform: translate(150%, -50%); cursor: pointer; `; export const PhotoAddText = styled.div` - z-index: 40; position: absolute; color: #4879af; top: 70%; diff --git a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx index d37e74c..79524a9 100644 --- a/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx +++ b/src/pages/ShareGroup/ShareGroupFolder/ShareGroupFolder.tsx @@ -1,18 +1,16 @@ // Share Group 1,2페이지 레이아웃 -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import Header from 'components/Header/Header'; import * as S from './Styles'; import ShareGroupFolderView from 'components/ShareGroup/ShareGroupFolderView/ShareGroupFolderView'; import { useParams } from 'react-router-dom'; -import { useRecoilState } from 'recoil'; +import { useSetRecoilState } from 'recoil'; import { shareGroupMemberListState } from 'recoil/states/share_group'; import { getShareGroupMembers } from 'apis/getMyShareGroup'; const ShareGroupFolder: React.FC = () => { const { id } = useParams<{ id: string }>(); - const [shareGroupMember, setShareGroupMember] = useRecoilState( - shareGroupMemberListState, - ); + const setShareGroupMember = useSetRecoilState(shareGroupMemberListState); useEffect(() => { getShareGroupMembers(Number(id)).then((res) => { diff --git a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx index 859e150..37b1292 100644 --- a/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx +++ b/src/pages/ShareGroup/ShareGroupMain/ShareGroupMain.tsx @@ -16,7 +16,6 @@ const ShareGroupMain: React.FC = () => { useEffect(() => { getMyShareGroup().then((res) => { if (res === null) return; - console.log(res); setShareGroup(res); }); }, []); diff --git a/src/recoil/selectors/sharegroup.ts b/src/recoil/selectors/sharegroup.ts new file mode 100644 index 0000000..162eabb --- /dev/null +++ b/src/recoil/selectors/sharegroup.ts @@ -0,0 +1,13 @@ +import { selectorFamily } from 'recoil'; +import { shareGroupListState } from 'recoil/states/share_group'; + +export const groupSelectorbyId = selectorFamily({ + key: 'groupSelectorbyId', + get: + (id: number) => + ({ get }) => { + const groups = get(shareGroupListState); + const selectedGroup = groups.filter((val) => val.shareGroupId === id); + return selectedGroup[0]; + }, +}); diff --git a/src/recoil/states/share_group.ts b/src/recoil/states/share_group.ts index c598d0f..549646f 100644 --- a/src/recoil/states/share_group.ts +++ b/src/recoil/states/share_group.ts @@ -36,42 +36,14 @@ export const selectedImageState = atom({ default: null, }); -export const shareGroupListState = atom({ +export const shareGroupListState = atom({ key: 'shareGroupListState', - default: [ - { - shareGroupId: 1, - name: '못 갈 뻔하다가 겨우 간 우리의 뜨거운 보라카이 여행', - image: 'https://i.imgur.com/GfKSahj.jpeg', - memberCount: 3, - createdAt: '2021-08-18', - inviteUrl: '', - }, - ], + default: [], }); export const shareGroupMemberListState = atom({ key: 'shareGroupMemberList', - default: [ - { - profileId: 1, - name: '한석봉', - image: 'https://avatars.githubusercontent.com/u/6400346?v=4', - memberId: 1, - }, - { - profileId: 2, - name: '김동현', - image: 'https://avatars.githubusercontent.com/u/6400346?v=4', - memberId: 2, - }, - { - profileId: 3, - name: '김민수', - image: 'https://avatars.githubusercontent.com/u/6400346?v=4', - memberId: 3, - }, - ], + default: [], }); export const shareGroupDetailSelectedImageState = atom( @@ -108,3 +80,8 @@ export const shareGroupDetailSelectedImageState = atom( }, }, ); + +export const selectedGroupName = atom({ + key: 'selectedGroupName', + default: '', +}); diff --git a/src/recoil/types/members.ts b/src/recoil/types/members.ts index 5990e33..ededbf2 100644 --- a/src/recoil/types/members.ts +++ b/src/recoil/types/members.ts @@ -28,3 +28,12 @@ export interface deleteResponse { deleted_at: string; }; } + +export interface samplePhotoResponse { + status: number; + code: string; + message: string; + data: { + hasSamplePhoto: boolean; + }; +} From 1d14b1c7a9bbb8a0bcd2ea68cabd7ace808f4dea Mon Sep 17 00:00:00 2001 From: eomseona Date: Tue, 13 Aug 2024 01:43:57 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20=EC=82=AC=EC=A7=84=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C=20=EC=9D=BC=EB=B6=80=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShareGroupCloudButton/ShareGroupCloudButton.tsx | 11 ++++++++--- src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx b/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx index 617a247..6767df5 100644 --- a/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx +++ b/src/components/ShareGroup/ShareGroupCloudButton/ShareGroupCloudButton.tsx @@ -3,6 +3,7 @@ import * as S from './Styles'; import { postPresignedUrl } from 'apis/postPresignedUrl'; import axios from 'axios'; import { postPhotoUpload } from 'apis/postPhotoUpload'; +import { useParams } from 'react-router-dom'; interface responseProp { photoName: string; @@ -14,6 +15,7 @@ const ShareGroupCloudButton: React.FC = () => { const [file, setFile] = useState(null); const [response, setResponse] = useState([]); const [photoUrl, setPhotoUrl] = useState(); + const { id } = useParams<{ id: string }>(); const handleAddButtonClick = () => { const fileInput = document.getElementById('file') as HTMLInputElement; @@ -34,8 +36,11 @@ const ShareGroupCloudButton: React.FC = () => { }; try { const { data } = await postPresignedUrl(requestData); + const photoUrls = data.preSignedUrlInfoList.map( + (item: any) => item.photoUrl, + ); setResponse(data.preSignedUrlInfoList); - setPhotoUrl(data.photoUrl); + setPhotoUrl(photoUrls); } catch (error) { console.error('Error: ', error); } @@ -43,7 +48,7 @@ const ShareGroupCloudButton: React.FC = () => { }; const handleUpload = async () => { - if (!response || !file) return; + if (!response || !file || !id) return; try { const uploadPromises = Array.from(file).map(async (fileItem, index) => { const presignedUrl = response[index].preSignedUrl; @@ -58,7 +63,7 @@ const ShareGroupCloudButton: React.FC = () => { }); await Promise.all(uploadPromises); // 모든 업로드가 완료될 때까지 대기 const requestData = { - shareGroupId: 2, + shareGroupId: parseInt(id), photoUrlList: photoUrl || [], }; postPhotoUpload(requestData); diff --git a/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx b/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx index 9e3a09d..974c58c 100644 --- a/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx +++ b/src/pages/EnterMain/EnterPhoto/EnterPhoto.tsx @@ -37,6 +37,10 @@ const EnterPhoto = () => { const fileList = event?.target.files; if (files && fileList) { const newFiles = files.concat(Array.from(fileList)); // 기존 파일과 새로운 파일 병합 + if (newFiles.length > 2) { + alert('사진 등록 개수를 초과했어요!'); + return; + } setFiles(newFiles); } }; From cbca73ba6da0e7868c365bd0f437254ed717e75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=BD=9C=EB=A6=AC/=EA=B9=80=ED=98=9C=EA=B2=BD?= <112871545+khgeung@users.noreply.github.com> Date: Tue, 13 Aug 2024 13:26:29 +0900 Subject: [PATCH 8/8] Rename emptyProfile.png to emptyProfile.png --- .../assets/samples/emptyProfile.png | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename "src/assets/samples/\bemptyProfile.png" => src/assets/samples/emptyProfile.png (100%) diff --git "a/src/assets/samples/\bemptyProfile.png" b/src/assets/samples/emptyProfile.png similarity index 100% rename from "src/assets/samples/\bemptyProfile.png" rename to src/assets/samples/emptyProfile.png