From f77c836b9d583494c39444d54ed2c62709cacd52 Mon Sep 17 00:00:00 2001 From: fr0gydev Date: Thu, 3 Jul 2025 23:45:02 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=EB=9D=BC=EC=9A=B0=ED=84=B0?= =?UTF-8?q?=EC=97=90=20=EC=83=88=20=EB=9D=BC=EC=9A=B0=ED=84=B0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 195a6ff2..8f0c8eaa 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -9,6 +9,7 @@ import Signup from './signup/Signup'; import SignupGenre from './signup/SignupGenre'; import SignupNickname from './signup/SignupNickname'; import SignupDone from './signup/SignupDone'; +import CreateGroup from './group/CreateGroup'; const Router = () => { const router = createBrowserRouter( @@ -20,6 +21,7 @@ const Router = () => { } /> } /> + } /> , ), ); From 92f335ff091af9ce65ed395bbeb845db0e232e33 Mon Sep 17 00:00:00 2001 From: fr0gydev Date: Thu, 3 Jul 2025 23:50:33 +0900 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B8=B0=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=8D=BC?= =?UTF-8?q?=EB=B8=94=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/group/CreateGroup.styled.ts | 174 +++++++++++++++++++++++++ src/pages/group/CreateGroup.tsx | 178 ++++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 src/pages/group/CreateGroup.styled.ts create mode 100644 src/pages/group/CreateGroup.tsx diff --git a/src/pages/group/CreateGroup.styled.ts b/src/pages/group/CreateGroup.styled.ts new file mode 100644 index 00000000..3140ac68 --- /dev/null +++ b/src/pages/group/CreateGroup.styled.ts @@ -0,0 +1,174 @@ +import styled from '@emotion/styled'; + +export const Container = styled.div` + display: flex; + flex-direction: column; + background-color: #121212; + min-width: 360px; + max-width: 767px; + min-height: 100vh; + margin: 0 auto; + padding: 96px 20px 100px 20px; + box-sizing: border-box; +`; + +export const Section = styled.div` + margin-bottom: 32px; +`; + +export const SectionTitle = styled.div` + color: #fefefe; + font-size: 18px; + font-weight: 600; + margin-bottom: 16px; +`; + +export const SearchBox = styled.div` + display: flex; + align-items: center; + background-color: #282828; + border-radius: 12px; + padding: 12px 16px; + gap: 12px; +`; + +export const SearchIcon = styled.div` + font-size: 16px; + color: #888; +`; + +export const SearchInput = styled.input` + background: none; + border: none; + outline: none; + color: #fefefe; + font-size: 16px; + flex: 1; + + &::placeholder { + color: #888; + font-size: 16px; + } +`; + +export const GenreButtonGroup = styled.div` + display: flex; + flex-wrap: wrap; + gap: 12px; +`; + +export const GenreButton = styled.button<{ active: boolean }>` + background-color: ${({ active }) => (active ? '#3D3D3D' : '#282828')}; + border: none; + border-radius: 20px; + padding: 8px 16px; + color: ${({ active }) => (active ? '#FEFEFE' : '#888')}; + font-size: 14px; + font-weight: 500; + cursor: pointer; + transition: all 0.2s; +`; + +export const TextAreaBox = styled.div` + position: relative; + background-color: #282828; + border-radius: 12px; + padding: 12px 16px; +`; + +export const TextArea = styled.textarea` + background: none; + border: none; + outline: none; + color: #fefefe; + font-size: 16px; + width: 100%; + resize: none; + font-family: inherit; + + &::placeholder { + color: #888; + font-size: 16px; + } +`; + +export const CharacterCount = styled.div` + position: absolute; + bottom: 12px; + right: 16px; + color: #888; + font-size: 12px; +`; + +export const DatePickerContainer = styled.div` + color: #fefefe; +`; + +export const DatePickerRow = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; + +export const DateSelector = styled.div` + display: flex; + align-items: center; + gap: 8px; +`; + +export const DateText = styled.span` + color: #fefefe; + font-size: 16px; + font-weight: 500; +`; + +export const MemberLimitContainer = styled.div` + display: flex; + align-items: center; + gap: 16px; +`; + +export const MemberNumber = styled.span` + color: #fefefe; + font-size: 32px; + font-weight: 600; +`; + +export const MemberText = styled.span` + color: #fefefe; + font-size: 16px; + font-weight: 400; +`; + +export const PrivacyToggleContainer = styled.div` + display: flex; + align-items: center; + justify-content: space-between; +`; + +export const PrivacyLabel = styled.span` + color: #fefefe; + font-size: 16px; + font-weight: 500; +`; + +export const ToggleSwitch = styled.div<{ active: boolean }>` + width: 48px; + height: 28px; + background-color: ${({ active }) => (active ? '#6868FF' : '#3D3D3D')}; + border-radius: 14px; + position: relative; + cursor: pointer; + transition: background-color 0.3s; +`; + +export const ToggleSlider = styled.div<{ active: boolean }>` + width: 20px; + height: 20px; + background-color: #fefefe; + border-radius: 50%; + position: absolute; + top: 4px; + left: ${({ active }) => (active ? '24px' : '4px')}; + transition: left 0.3s; +`; diff --git a/src/pages/group/CreateGroup.tsx b/src/pages/group/CreateGroup.tsx new file mode 100644 index 00000000..10c0b59a --- /dev/null +++ b/src/pages/group/CreateGroup.tsx @@ -0,0 +1,178 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import TitleHeader from '../../components/common/TitleHeader'; +import leftarrow from '../../assets/leftArrow.svg'; +import { + Container, + Section, + SectionTitle, + SearchBox, + SearchInput, + SearchIcon, + GenreButtonGroup, + GenreButton, + TextAreaBox, + TextArea, + CharacterCount, + DatePickerContainer, + DatePickerRow, + DateSelector, + DateText, + MemberLimitContainer, + MemberNumber, + MemberText, + PrivacyToggleContainer, + PrivacyLabel, + ToggleSwitch, + ToggleSlider, +} from './CreateGroup.styled.ts'; + +const CreateGroup = () => { + const navigate = useNavigate(); + const [bookTitle, setBookTitle] = useState(''); + const [selectedGenre, setSelectedGenre] = useState(''); + const [description, setDescription] = useState(''); + const [introduction, setIntroduction] = useState(''); + const [startDate, setStartDate] = useState({ year: 2025, month: 1, day: 1 }); + const [endDate, setEndDate] = useState({ year: 2025, month: 1, day: 1 }); + const [memberLimit, setMemberLimit] = useState(1); + const [isPrivate, setIsPrivate] = useState(false); + + const handleBackClick = () => { + navigate(-1); + }; + + const handleCompleteClick = () => { + // 완료 로직 추후 구현 + console.log('모임 생성 완료'); + }; + + const genres = ['문학', '과학·IT', '사회과학', '인문학', '예술']; + + const isFormValid = bookTitle.trim() !== '' && selectedGenre !== ''; + + return ( + <> + } + title="모임 만들기" + rightButton="완료" + onLeftClick={handleBackClick} + onRightClick={handleCompleteClick} + isNextActive={isFormValid} + /> + +
+ 책 선택 + + 🔍 + setBookTitle(e.target.value)} + /> + +
+ +
+ 책 장르 + + {genres.map(genre => ( + setSelectedGenre(genre)} + > + {genre} + + ))} + +
+ 책을 가장 잘 설명하는 장르를 하나 골라주세요. +
+
+ +
+ 방 제목 + +