From 77e761c91c203e840afd26a4a12f4c7cae889406 Mon Sep 17 00:00:00 2001 From: wonil Date: Tue, 26 Nov 2024 06:05:28 +0900 Subject: [PATCH 1/9] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20=EA=B2=AC=EC=A2=85?= =?UTF-8?q?=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/breeds.json | 119 +++++++++++++++++++++++++++ src/modals/SearchModal/index.tsx | 18 ++++ src/modals/SearchModal/styles.ts | 44 ++++++++++ src/pages/RegisterPage/Dog/index.tsx | 4 +- 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/data/breeds.json create mode 100644 src/modals/SearchModal/index.tsx create mode 100644 src/modals/SearchModal/styles.ts diff --git a/src/data/breeds.json b/src/data/breeds.json new file mode 100644 index 0000000..c43ab32 --- /dev/null +++ b/src/data/breeds.json @@ -0,0 +1,119 @@ +{ + "breeds": [ + "래브라도 리트리버", + "골든 리트리버", + "저먼 셰퍼드", + "도베르만", + "그레이트 데인", + "버니즈 마운틴 독", + "뉴펀들랜드", + "로트와일러", + "세인트 버나드", + "아이리시 울프하운드", + "잉글리시 마스티프", + "그레이트 피레니즈", + "시베리안 허스키", + "알래스칸 맬러뮤트", + "보더 콜리", + "비글", + "불독", + "차우차우", + "달마시안", + "사모예드", + "시바견", + "웰시코기", + "진도견", + "아키타", + "바셋하운드", + "브리타니", + "콜리", + "잉글리시 세터", + "잉글리시 스프링거 스패니얼", + "벨기에 말리노이즈", + "포인터", + "에어데일 테리어", + "휘펫", + "불 테리어", + "스탠더드 푸들", + "아메리칸 에스키모", + "보더 테리어", + "웨스트하이랜드 화이트 테리어", + "프렌치 불독", + "포메라니안", + "치와와", + "요크셔테리어", + "미니어처 슈나우저", + "미니어처 푸들", + "토이 푸들", + "말티즈", + "시츄", + "닥스훈트", + "비숑 프리제", + "파피용", + "퍼그", + "페키니즈", + "잭 러셀 테리어", + "미니어처 핀셔", + "캐벌리어 킹 찰스 스패니얼", + "보스턴 테리어", + "이탈리안 그레이하운드", + "스코티시 테리어", + "실키 테리어", + "케언 테리어", + "노리치 테리어", + "아프간 하운드", + "살루키", + "바센지", + "차이니즈 샤페이", + "아메리칸 코카 스패니얼", + "잉글리시 코카 스패니얼", + "클럼버 스패니얼", + "필드 스패니얼", + "저먼 와이어헤어드 포인터", + "체서피크 베이 리트리버", + "컬리코티드 리트리버", + "플랫코티드 리트리버", + "아이리시 세터", + "고든 세터", + "올드 잉글리시 시프도그", + "셔틀랜드 시프도그", + "벨기안 시프도그", + "오스트레일리안 캐틀 독", + "핀란드 스피츠", + "케이스혼드", + "티베탄 마스티프", + "불마스티프", + "네아폴리탄 마스티프", + "블러드하운드", + "그레이하운드", + "노르웨이언 엘크하운드", + "아이리시 워터 스패니얼", + "웨일즈 스프링거 스패니얼", + "스탠더드 슈나우저", + "자이언트 슈나우저", + "스코티시 디어하운드", + "맨체스터 테리어", + "노퍽 테리어", + "래빗 닥스훈트", + "롱헤어드 닥스훈트", + "아메리칸 불리", + "버니두들", + "골든두들", + "래브라두들", + "포르투갈 워터 독", + "오스트레일리안 셰퍼드", + "벨기에 터뷰런", + "블랙 러시안 테리어", + "불 마스티프", + "체서피크 베이 리트리버", + "샤페이", + "클럼버 스패니얼", + "컬리 코티드 리트리버", + "댄디 딘몬트 테리어", + "잉글리시 폭스하운드", + "필드 스패니얼", + "핀란드 라프훈드", + "자이언트 슈나우저", + "아이비전 하운드" + ] +} diff --git a/src/modals/SearchModal/index.tsx b/src/modals/SearchModal/index.tsx new file mode 100644 index 0000000..effa9db --- /dev/null +++ b/src/modals/SearchModal/index.tsx @@ -0,0 +1,18 @@ +import * as S from './styles' + +export default function SearchModal() { + const handleOverlay = () => { + console.log('바깥 클릭') + } + + const handleClickSearchArea = (e: React.MouseEvent) => { + e.stopPropagation() + } + return ( + + + + + + ) +} diff --git a/src/modals/SearchModal/styles.ts b/src/modals/SearchModal/styles.ts new file mode 100644 index 0000000..55e76ab --- /dev/null +++ b/src/modals/SearchModal/styles.ts @@ -0,0 +1,44 @@ +import styled from 'styled-components' + +export const SearchModalOverlay = styled.div` + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: yellow; +` + +export const SearchArea = styled.div` + position: relative; + border: solid 1px red; + height: 47%; + margin: 80px 20px; + + &::before { + content: '견종'; + position: absolute; + top: -26px; + left: 2px; + width: auto; + height: 30px; + } +` + +export const SearchInput = styled.input` + width: 100%; + background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; + border: none; + text-align: center; + padding: 17px 32px; + border-radius: 12px; + font-size: ${({ theme }) => theme.typography._20}; + font-weight: 700; + + &:focus { + box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`}; + } + &::placeholder { + font-weight: 400; + } +` diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index e85e069..7a2f9e8 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -1,6 +1,6 @@ import * as S from './styles' import { Helmet } from 'react-helmet-async' -import DogProfileSection from '~modals/RegisterDogModal/DogProfileSection' +import SearchModal from '~modals/SearchModal' export default function RegisterDogPage() { return ( @@ -9,7 +9,7 @@ export default function RegisterDogPage() { DDang | 반려견 정보 등록 - + ) } From ed5958f52ca121404778bc960dbb68fb0d10f201 Mon Sep 17 00:00:00 2001 From: wonil Date: Tue, 26 Nov 2024 11:05:26 +0900 Subject: [PATCH 2/9] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EA=B2=AC=EC=A2=85=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B8=B0=EB=8A=A5=20=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DogProfileDetailSection/index.tsx | 15 +++-- .../DogProfileDetailSection/styles.ts | 5 +- src/modals/SearchModal/index.tsx | 62 +++++++++++++++++-- src/modals/SearchModal/styles.ts | 44 +++++++++++-- src/pages/RegisterPage/Dog/index.tsx | 4 +- 5 files changed, 110 insertions(+), 20 deletions(-) diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index dbe2981..f5866ed 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -5,12 +5,17 @@ import GenderSelectButton from '~components/GenderSelectButton' import { Typo24 } from '~components/Typo/index' import Check from '~assets/check.svg' import Header from '~components/Header/index' +import SearchModal from '~modals/SearchModal' +import { useModalStore } from '~stores/modalStore' export default function DogProfileDetailSection() { const [isNeutered, setIsNeutered] = useState(false) const [selectedGender, setSelectedGender] = useState<'male' | 'female' | null>(null) + const [breed, setBreed] = useState('') const [weight, setWeight] = useState('') + const { pushModal, popModal } = useModalStore() + const [displayValue, setDisplayValue] = useState('') const [inputType, setInputType] = useState('text') @@ -46,11 +51,9 @@ export default function DogProfileDetailSection() { } } - const handleClickPrev = () => {} - return ( <> -
+
@@ -79,9 +82,11 @@ export default function DogProfileDetailSection() { - 견종 입력 + pushModal()} hasBreed={!!breed}> + {breed ? breed : '견종 입력'} + ` width: 100%; border: none; text-align: center; padding: 17px 32px; font-size: ${({ theme }) => theme.typography._20}; - color: ${({ theme }) => theme.colors.grayscale.font_3}; + color: ${({ theme, hasBreed }) => (hasBreed ? 'black' : theme.colors.grayscale.font_3)}; + font-weight: ${({ hasBreed }) => (hasBreed ? 'bold' : 'default')}; cursor: pointer; ` diff --git a/src/modals/SearchModal/index.tsx b/src/modals/SearchModal/index.tsx index effa9db..daf112a 100644 --- a/src/modals/SearchModal/index.tsx +++ b/src/modals/SearchModal/index.tsx @@ -1,17 +1,67 @@ import * as S from './styles' +import { useState, useEffect } from 'react' +import breeds from '~/data/breeds.json' +import { useModalStore } from '~/stores/modalStore' -export default function SearchModal() { - const handleOverlay = () => { - console.log('바깥 클릭') - } +interface SearchModalProps { + setBreed: (breed: string) => void +} + +export default function SearchModal({ setBreed }: SearchModalProps) { + const { popModal } = useModalStore() + const [searchTerm, setSearchTerm] = useState('') + const [searchResults, setSearchResults] = useState([]) + + useEffect(() => { + if (searchTerm === '') { + setSearchResults([]) + return + } + + const filteredResults = breeds.breeds + .filter(breed => breed.includes(searchTerm)) + .sort((a, b) => (!a.startsWith(searchTerm) && b.startsWith(searchTerm) ? 1 : -1)) + setSearchResults(filteredResults) + }, [searchTerm]) const handleClickSearchArea = (e: React.MouseEvent) => { e.stopPropagation() } + + const highlightText = (text: string) => { + if (!searchTerm) return text + + const parts = text.split(new RegExp(`(${searchTerm})`, 'gi')) + return parts.map((part, index) => + part.toLowerCase() === searchTerm.toLowerCase() ? {part} : part + ) + } + + const handleBreedClick = (e: React.MouseEvent) => { + const target = e.target as HTMLElement + if (target.closest('[data-breed]')) { + const breed = target.closest('[data-breed]')?.getAttribute('data-breed') + if (breed) setBreed(breed) + popModal() + } + } + return ( - + - + setSearchTerm(e.target.value)} + /> + + {searchResults.map((result, index) => ( + + {highlightText(result)} + + ))} + 기타 + ) diff --git a/src/modals/SearchModal/styles.ts b/src/modals/SearchModal/styles.ts index 55e76ab..c1eca56 100644 --- a/src/modals/SearchModal/styles.ts +++ b/src/modals/SearchModal/styles.ts @@ -6,17 +6,27 @@ export const SearchModalOverlay = styled.div` bottom: 0; left: 0; right: 0; - background-color: yellow; + padding-top: 140px; + + @media (max-height: 750px) { + padding-top: 120px; + } + + @media (max-height: 700px) { + padding-top: 100px; + } ` export const SearchArea = styled.div` position: relative; - border: solid 1px red; - height: 47%; - margin: 80px 20px; + height: 45%; + margin: 0 20px; + display: flex; + flex-direction: column; + gap: 4px; &::before { - content: '견종'; + /* content: '견종'; */ position: absolute; top: -26px; left: 2px; @@ -42,3 +52,27 @@ export const SearchInput = styled.input` font-weight: 400; } ` + +export const SearchResultsWrapper = styled.div` + border-radius: 12px; + background-color: white; + flex: 1; + overflow-y: auto; + padding: 4px; +` + +export const SearchResult = styled.div` + border-radius: 12px; + /* font-size: 15px; */ + height: 55px; + padding: 16px 20px; + cursor: pointer; + + &:hover { + background-color: ${({ theme }) => theme.colors.brand.lighten_3}; + } +` +export const Highlight = styled.span` + color: ${({ theme }) => theme.colors.brand.darken}; + font-weight: bold; +` diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index 7a2f9e8..a9b8af2 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -1,6 +1,6 @@ import * as S from './styles' import { Helmet } from 'react-helmet-async' -import SearchModal from '~modals/SearchModal' +import DogProfileDetailSection from '~modals/RegisterDogModal/DogProfileDetailSection' export default function RegisterDogPage() { return ( @@ -9,7 +9,7 @@ export default function RegisterDogPage() { DDang | 반려견 정보 등록 - + ) } From d705f0597dc21e4259ac6a46b5b22832849931ab Mon Sep 17 00:00:00 2001 From: wonil Date: Tue, 26 Nov 2024 11:20:16 +0900 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=8E=A8=20Design:=20=EA=B2=80=EC=83=89?= =?UTF-8?q?=EB=AA=A8=EB=8B=AC=20=EC=8A=A4=ED=81=AC=EB=A1=A4=EB=B0=94=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modals/SearchModal/styles.ts | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/modals/SearchModal/styles.ts b/src/modals/SearchModal/styles.ts index c1eca56..eefc097 100644 --- a/src/modals/SearchModal/styles.ts +++ b/src/modals/SearchModal/styles.ts @@ -24,15 +24,6 @@ export const SearchArea = styled.div` display: flex; flex-direction: column; gap: 4px; - - &::before { - /* content: '견종'; */ - position: absolute; - top: -26px; - left: 2px; - width: auto; - height: 30px; - } ` export const SearchInput = styled.input` @@ -59,6 +50,24 @@ export const SearchResultsWrapper = styled.div` flex: 1; overflow-y: auto; padding: 4px; + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background-color: ${({ theme }) => theme.colors.grayscale.gc_2}; + border-radius: 12px; + } + + &::-webkit-scrollbar-thumb { + background-color: ${({ theme }) => theme.colors.grayscale.font_1}; + border-radius: 10px; + } + + &::-webkit-scrollbar-thumb:hover { + background: #555; + } ` export const SearchResult = styled.div` From e8b81397a39bfb371f0cf5c5e7ffcecc8b3569a9 Mon Sep 17 00:00:00 2001 From: wonil Date: Tue, 26 Nov 2024 12:47:28 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=E2=9C=A8=20Feat:=20SearchModal=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DogProfileDetailSection/index.tsx | 14 ++++++++++++++ .../DogProfileDetailSection/styles.ts | 9 +++++++-- .../RegisterDogModal/DogProfileSection/styles.ts | 6 +++++- src/modals/SearchModal/index.tsx | 4 +++- src/modals/SearchModal/styles.ts | 1 - src/pages/RegisterPage/Dog/index.tsx | 2 ++ 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index f5866ed..f8ec19b 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -8,7 +8,20 @@ import Header from '~components/Header/index' import SearchModal from '~modals/SearchModal' import { useModalStore } from '~stores/modalStore' +interface DogProfileType { + isNeutered: boolean + selectedGender: string | null + breed: string + weight: string +} + export default function DogProfileDetailSection() { + const [dogProfile, setDogProfile] = useState({ + isNeutered: false, + selectedGender: null, + breed: '', + weight: '', + }) const [isNeutered, setIsNeutered] = useState(false) const [selectedGender, setSelectedGender] = useState<'male' | 'female' | null>(null) const [breed, setBreed] = useState('') @@ -92,6 +105,7 @@ export default function DogProfileDetailSection() { onChange={onChangeWeightInput} onFocus={handleFocus} onBlur={handleBlur} + hasWeight={!!weight} /> 확인 diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts index 871439b..a2aa1b7 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts @@ -3,7 +3,11 @@ import { styled } from 'styled-components' export const DogProfileDetailSection = styled.div` padding: 120px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; - height: 100dvh; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; display: flex; flex-direction: column; @@ -80,13 +84,14 @@ export const PickerBtn = styled.div<{ hasBreed: boolean }>` cursor: pointer; ` -export const WeightInput = styled.input` +export const WeightInput = styled.input<{ hasWeight: boolean }>` width: 100%; border: none; text-align: center; padding: 17px 32px; border-radius: 12px; font-size: ${({ theme }) => theme.typography._20}; + font-weight: ${({ hasWeight }) => (hasWeight ? 'bold' : 'default')}; &:focus { box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`}; } diff --git a/src/modals/RegisterDogModal/DogProfileSection/styles.ts b/src/modals/RegisterDogModal/DogProfileSection/styles.ts index 34b5424..5c8db1a 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileSection/styles.ts @@ -3,7 +3,11 @@ import { styled } from 'styled-components' export const DogProfileSection = styled.div` padding: 120px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; - height: 100dvh; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; display: flex; flex-direction: column; diff --git a/src/modals/SearchModal/index.tsx b/src/modals/SearchModal/index.tsx index daf112a..4075be0 100644 --- a/src/modals/SearchModal/index.tsx +++ b/src/modals/SearchModal/index.tsx @@ -14,7 +14,7 @@ export default function SearchModal({ setBreed }: SearchModalProps) { useEffect(() => { if (searchTerm === '') { - setSearchResults([]) + setSearchResults(breeds.breeds.sort((a, b) => a.localeCompare(b))) return } @@ -53,6 +53,7 @@ export default function SearchModal({ setBreed }: SearchModalProps) { placeholder='견종을 검색하세요' value={searchTerm} onChange={e => setSearchTerm(e.target.value)} + autoFocus /> {searchResults.map((result, index) => ( @@ -60,6 +61,7 @@ export default function SearchModal({ setBreed }: SearchModalProps) { {highlightText(result)} ))} + 믹스견 기타 diff --git a/src/modals/SearchModal/styles.ts b/src/modals/SearchModal/styles.ts index eefc097..d66f929 100644 --- a/src/modals/SearchModal/styles.ts +++ b/src/modals/SearchModal/styles.ts @@ -72,7 +72,6 @@ export const SearchResultsWrapper = styled.div` export const SearchResult = styled.div` border-radius: 12px; - /* font-size: 15px; */ height: 55px; padding: 16px 20px; cursor: pointer; diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index a9b8af2..9105698 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -1,5 +1,6 @@ import * as S from './styles' import { Helmet } from 'react-helmet-async' +import DogProfileSection from '~modals/RegisterDogModal/DogProfileSection' import DogProfileDetailSection from '~modals/RegisterDogModal/DogProfileDetailSection' export default function RegisterDogPage() { @@ -10,6 +11,7 @@ export default function RegisterDogPage() { + {/* */} ) } From 4c284bc8c738e6b3df6f5a2c949bc0352da00e65 Mon Sep 17 00:00:00 2001 From: wonil Date: Wed, 27 Nov 2024 10:17:00 +0900 Subject: [PATCH 5/9] =?UTF-8?q?=F0=9F=94=A8=20Setting:=20=EB=B0=98?= =?UTF-8?q?=EB=A0=A4=EA=B2=AC=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A0=84?= =?UTF-8?q?=EC=97=AD=20=EA=B4=80=EB=A6=AC=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DogProfileDetailSection/index.tsx | 50 +++++++------------ .../DogProfileSection/index.tsx | 20 +++----- src/modals/SearchModal/index.tsx | 10 ++-- .../Dog/SelectSectionButton/index.tsx | 8 +-- src/pages/RegisterPage/Dog/index.tsx | 39 +-------------- src/stores/dogProfileStore.ts | 34 +++++++++++++ 6 files changed, 69 insertions(+), 92 deletions(-) create mode 100644 src/stores/dogProfileStore.ts diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index f8ec19b..8b37587 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -7,39 +7,23 @@ import Check from '~assets/check.svg' import Header from '~components/Header/index' import SearchModal from '~modals/SearchModal' import { useModalStore } from '~stores/modalStore' - -interface DogProfileType { - isNeutered: boolean - selectedGender: string | null - breed: string - weight: string -} +import { useDogProfileStore } from '~/stores/dogProfileStore' export default function DogProfileDetailSection() { - const [dogProfile, setDogProfile] = useState({ - isNeutered: false, - selectedGender: null, - breed: '', - weight: '', - }) - const [isNeutered, setIsNeutered] = useState(false) - const [selectedGender, setSelectedGender] = useState<'male' | 'female' | null>(null) - const [breed, setBreed] = useState('') - const [weight, setWeight] = useState('') - + const { dogProfile, setDogProfile } = useDogProfileStore() const { pushModal, popModal } = useModalStore() const [displayValue, setDisplayValue] = useState('') const [inputType, setInputType] = useState('text') const handleGenderSelect = (gender: 'male' | 'female') => { - setSelectedGender(gender) + setDogProfile({ gender }) } const onChangeWeightInput = (e: React.ChangeEvent) => { const value = e.target.value if (value === '') { - setWeight('') + setDogProfile({ weight: '' }) setDisplayValue('') return } @@ -47,20 +31,20 @@ export default function DogProfileDetailSection() { if (/^\d*\.?\d*$/.test(value)) { const formatted = value.includes('.') ? value.match(/^\d*\.?\d{0,2}/)![0] : value - setWeight(formatted) + setDogProfile({ weight: formatted }) setDisplayValue(inputType === 'number' ? formatted : `${formatted}kg`) } } const handleFocus = () => { setInputType('number') - setDisplayValue(weight) + setDisplayValue(dogProfile.weight) } const handleBlur = () => { setInputType('text') - if (weight) { - setDisplayValue(`${weight}kg`) + if (dogProfile.weight) { + setDisplayValue(`${dogProfile.weight}kg`) } } @@ -78,25 +62,25 @@ export default function DogProfileDetailSection() { handleGenderSelect('male')} /> handleGenderSelect('female')} /> - setIsNeutered(!isNeutered)}> - - {isNeutered && check} + setDogProfile({ isNeutered: !dogProfile.isNeutered })}> + + {dogProfile.isNeutered && check} - 중성화 했어요 + 중성화 했어요 - pushModal()} hasBreed={!!breed}> - {breed ? breed : '견종 입력'} + pushModal()} hasBreed={!!dogProfile.breed}> + {dogProfile.breed || '견종 입력'} 확인 diff --git a/src/modals/RegisterDogModal/DogProfileSection/index.tsx b/src/modals/RegisterDogModal/DogProfileSection/index.tsx index a05b871..a4c5847 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileSection/index.tsx @@ -11,21 +11,15 @@ import { validateDogProfile } from '~utils/validateDogProfile' import DogProfileDetailSection from '../DogProfileDetailSection' import Toast from '~components/Toast' import { useToastStore } from '~/stores/toastStore' -import { DogProfileType } from '~pages/RegisterPage/Dog' +import { useDogProfileStore } from '~/stores/dogProfileStore' -interface Props { - dogProfile: DogProfileType - setDogProfile: (profile: DogProfileType | ((prev: DogProfileType) => DogProfileType)) => void -} - -export default function DogProfileSection({ dogProfile, setDogProfile }: Props) { +export default function DogProfileSection() { const { popModal, pushModal } = useModalStore() const { showToast } = useToastStore() + const { dogProfile, setDogProfile } = useDogProfileStore() const handleDatePickerOpen = () => { - pushModal( - setDogProfile(prev => ({ ...prev, birth: date }))} /> - ) + pushModal( setDogProfile({ birth: date })} />) } const handleNextClick = () => { @@ -47,12 +41,12 @@ export default function DogProfileSection({ dogProfile, setDogProfile }: Props)
알려주세요!
- setDogProfile(prev => ({ ...prev, image }))} /> + setDogProfile({ image })} /> setDogProfile(prev => ({ ...prev, name: e.target.value }))} + onChange={e => setDogProfile({ name: e.target.value })} /> {dogProfile.birth || '생년월일 선택'} @@ -60,7 +54,7 @@ export default function DogProfileSection({ dogProfile, setDogProfile }: Props) setDogProfile(prev => ({ ...prev, intro: e.target.value }))} + onChange={e => setDogProfile({ intro: e.target.value })} > 한줄 소개 입력 diff --git a/src/modals/SearchModal/index.tsx b/src/modals/SearchModal/index.tsx index 4075be0..e5fbe5f 100644 --- a/src/modals/SearchModal/index.tsx +++ b/src/modals/SearchModal/index.tsx @@ -2,12 +2,10 @@ import * as S from './styles' import { useState, useEffect } from 'react' import breeds from '~/data/breeds.json' import { useModalStore } from '~/stores/modalStore' +import { useDogProfileStore } from '~/stores/dogProfileStore' -interface SearchModalProps { - setBreed: (breed: string) => void -} - -export default function SearchModal({ setBreed }: SearchModalProps) { +export default function SearchModal() { + const { setDogProfile } = useDogProfileStore() const { popModal } = useModalStore() const [searchTerm, setSearchTerm] = useState('') const [searchResults, setSearchResults] = useState([]) @@ -41,7 +39,7 @@ export default function SearchModal({ setBreed }: SearchModalProps) { const target = e.target as HTMLElement if (target.closest('[data-breed]')) { const breed = target.closest('[data-breed]')?.getAttribute('data-breed') - if (breed) setBreed(breed) + if (breed) setDogProfile({ breed }) popModal() } } diff --git a/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx b/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx index a62bc83..7679fe7 100644 --- a/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx +++ b/src/pages/RegisterPage/Dog/SelectSectionButton/index.tsx @@ -7,12 +7,14 @@ interface SelectSectionButtonProps { title: string description: string src: string - onClick: () => void + modal: ReactNode } -export default function SelectSectionButton({ title, description, src, onClick }: SelectSectionButtonProps) { +export default function SelectSectionButton({ title, description, src, modal }: SelectSectionButtonProps) { + const { pushModal } = useModalStore() + return ( - + pushModal(modal)}> {title} diff --git a/src/pages/RegisterPage/Dog/index.tsx b/src/pages/RegisterPage/Dog/index.tsx index a229d6f..b42dfbe 100644 --- a/src/pages/RegisterPage/Dog/index.tsx +++ b/src/pages/RegisterPage/Dog/index.tsx @@ -1,48 +1,13 @@ import * as S from './styles' import { Helmet } from 'react-helmet-async' -import { useEffect, useState } from 'react' import { Typo24 } from '~components/Typo/index' import SelectSectionButton from './SelectSectionButton' import addDogProfile from '~assets/add-dog-profile.svg' import addFamilycode from '~assets/add-family-code.svg' import DogProfileSection from '~modals/RegisterDogModal/DogProfileSection' import FamilyCodeSection from '~modals/RegisterDogModal/FamilyCodeSection' -import { useModalStore } from '~stores/modalStore' -export interface DogProfileType { - name: string - image: string | undefined - birth: string - intro: string - gender: 'male' | 'female' | null - isNeutered: boolean - breed: string - weight: string -} export default function RegisterDogPage() { - const { pushModal } = useModalStore() - const [dogProfile, setDogProfile] = useState({ - name: '', - image: undefined, - birth: '', - intro: '', - gender: null, - isNeutered: false, - breed: '', - weight: '', - }) - - useEffect(() => { - console.log(dogProfile) - }, [dogProfile]) - - const handleDogProfileClick = () => { - pushModal() - } - - const handleFamilyCodeClick = () => { - pushModal() - } return ( @@ -60,13 +25,13 @@ export default function RegisterDogPage() { title='반려견 프로필 추가하기' description='반려견 프로필을 추가해보세요' src={addDogProfile} - onClick={handleDogProfileClick} + modal={} /> } /> diff --git a/src/stores/dogProfileStore.ts b/src/stores/dogProfileStore.ts new file mode 100644 index 0000000..2b8b811 --- /dev/null +++ b/src/stores/dogProfileStore.ts @@ -0,0 +1,34 @@ +import { create } from 'zustand' + +export interface DogProfileType { + name: string + image: string | undefined + birth: string + intro: string + gender: 'male' | 'female' | null + isNeutered: boolean + breed: string + weight: string +} + +interface DogProfileStore { + dogProfile: DogProfileType + setDogProfile: (profile: Partial) => void +} + +export const useDogProfileStore = create(set => ({ + dogProfile: { + name: '', + image: undefined, + birth: '', + intro: '', + gender: null, + isNeutered: false, + breed: '', + weight: '', + }, + setDogProfile: profile => + set(state => ({ + dogProfile: { ...state.dogProfile, ...profile }, + })), +})) From 27b9d59e8fff4d826773f606b106540e44e3f504 Mon Sep 17 00:00:00 2001 From: wonil Date: Wed, 27 Nov 2024 10:50:21 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=F0=9F=90=9B=20Fix:=20z-index=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modals/DatePickerModal/styles.ts | 2 ++ src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx | 2 +- src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts | 1 + src/modals/RegisterDogModal/DogProfileSection/index.tsx | 3 +-- src/modals/RegisterDogModal/DogProfileSection/styles.ts | 1 + src/modals/SearchModal/styles.ts | 2 ++ 6 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modals/DatePickerModal/styles.ts b/src/modals/DatePickerModal/styles.ts index b7121ab..eda6f45 100644 --- a/src/modals/DatePickerModal/styles.ts +++ b/src/modals/DatePickerModal/styles.ts @@ -19,6 +19,8 @@ const slideDown = keyframes` ` export const ModalOverlay = styled.div` + background-color: rgba(0, 0, 0, 0.4); + z-index: 200; position: fixed; top: 0; left: 0; diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index 8b37587..01d7f23 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -50,8 +50,8 @@ export default function DogProfileDetailSection() { return ( <> -
+
반려견 상세 정보를 diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts index a2aa1b7..d18f523 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts @@ -1,6 +1,7 @@ import { styled } from 'styled-components' export const DogProfileDetailSection = styled.div` + z-index: 300; padding: 120px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; position: absolute; diff --git a/src/modals/RegisterDogModal/DogProfileSection/index.tsx b/src/modals/RegisterDogModal/DogProfileSection/index.tsx index a4c5847..0257f97 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileSection/index.tsx @@ -1,5 +1,4 @@ import * as S from './styles' -import { useEffect } from 'react' import { ActionButton } from '~components/Button/ActionButton' import TwoLineInput from '~components/Input/TwoLineInput' import Header from '~components/Header/index' @@ -33,8 +32,8 @@ export default function DogProfileSection() { return ( <> -
+
반려견 기본 정보를 diff --git a/src/modals/RegisterDogModal/DogProfileSection/styles.ts b/src/modals/RegisterDogModal/DogProfileSection/styles.ts index 5c8db1a..31cd0bf 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileSection/styles.ts @@ -1,6 +1,7 @@ import { styled } from 'styled-components' export const DogProfileSection = styled.div` + z-index: 100; padding: 120px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; position: absolute; diff --git a/src/modals/SearchModal/styles.ts b/src/modals/SearchModal/styles.ts index d66f929..052d0c1 100644 --- a/src/modals/SearchModal/styles.ts +++ b/src/modals/SearchModal/styles.ts @@ -1,6 +1,8 @@ import styled from 'styled-components' export const SearchModalOverlay = styled.div` + background-color: rgba(0, 0, 0, 0.4); + z-index: 400; position: fixed; top: 0; bottom: 0; From b32f0e77a43333ea854282117fb49fdc2b9ec263 Mon Sep 17 00:00:00 2001 From: wonil Date: Wed, 27 Nov 2024 12:10:35 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EB=B0=98=EB=A0=A4?= =?UTF-8?q?=EA=B2=AC=20=EB=93=B1=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CheckDogProfileSection/index.tsx | 5 ++-- .../CheckDogProfileSection/styles.ts | 7 ++++- .../DogProfileDetailSection/index.tsx | 23 +++++++++++++- .../DogProfileDetailSection/styles.ts | 4 +++ .../DogProfileSection/index.tsx | 16 +++++++++- .../FamilyCodeSection/index.tsx | 30 ++++++++++++++++--- .../FamilyCodeSection/styles.ts | 11 ++++++- src/stores/dogProfileStore.ts | 12 +------- src/types/dogProfile.ts | 10 +++++++ src/utils/validateDogProfile.ts | 21 +++++++++---- 10 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 src/types/dogProfile.ts diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx index d060017..5451e0b 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/index.tsx @@ -4,14 +4,15 @@ import Header from '~components/Header/index' import { Typo24 } from '~components/Typo/index' import { Profile } from '~components/Profile' import Tag from '~components/Tag' +import { useModalStore } from '~stores/modalStore' export default function CheckDogProfileSection() { - const handleClickPrev = () => {} + const { popModal } = useModalStore() return ( <> -
+
diff --git a/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts b/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts index 248cf84..920d7c6 100644 --- a/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts +++ b/src/modals/RegisterDogModal/CheckDogProfileSection/styles.ts @@ -1,9 +1,14 @@ import { styled } from 'styled-components' export const CheckDogProfileSection = styled.div` + z-index: 200; padding: 180px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; - height: 100dvh; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; display: flex; flex-direction: column; diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index 01d7f23..cf133f2 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -8,10 +8,14 @@ import Header from '~components/Header/index' import SearchModal from '~modals/SearchModal' import { useModalStore } from '~stores/modalStore' import { useDogProfileStore } from '~/stores/dogProfileStore' +import { validateDogDetailProfile } from '~utils/validateDogProfile' +import { useToastStore } from '~stores/toastStore' +import Toast from '~components/Toast' export default function DogProfileDetailSection() { const { dogProfile, setDogProfile } = useDogProfileStore() const { pushModal, popModal } = useModalStore() + const { showToast } = useToastStore() const [displayValue, setDisplayValue] = useState('') const [inputType, setInputType] = useState('text') @@ -48,6 +52,15 @@ export default function DogProfileDetailSection() { } } + const handleComfirmClick = () => { + const alertMessage = validateDogDetailProfile(dogProfile) + if (alertMessage) { + showToast(alertMessage) + return + } + console.log('이제 백엔드로 전송') + } + return ( <> @@ -92,7 +105,15 @@ export default function DogProfileDetailSection() { hasWeight={!!dogProfile.weight} /> - 확인 + + + 확인 + + + ) diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts index d18f523..a238239 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts @@ -107,3 +107,7 @@ export const WeightInput = styled.input<{ hasWeight: boolean }>` -moz-appearance: textfield; } ` + +export const ToastWrapper = styled.div` + position: relative; +` diff --git a/src/modals/RegisterDogModal/DogProfileSection/index.tsx b/src/modals/RegisterDogModal/DogProfileSection/index.tsx index 0257f97..76b0533 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileSection/index.tsx @@ -30,10 +30,24 @@ export default function DogProfileSection() { pushModal() } + const handlePrevClick = () => { + setDogProfile({ + name: '', + image: undefined, + birth: '', + intro: '', + gender: null, + isNeutered: false, + breed: '', + weight: '', + }) + popModal() + } + return ( <> -
+
반려견 기본 정보를 diff --git a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx index 14ad870..0646c8e 100644 --- a/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx +++ b/src/modals/RegisterDogModal/FamilyCodeSection/index.tsx @@ -1,15 +1,32 @@ import * as S from './styles' +import { useState } from 'react' import { ActionButton } from '~components/Button/ActionButton' import PrevButton from '~components/Button/PrevButton' import { Typo24 } from '~components/Typo/index' import Header from '~components/Header/index' +import { useModalStore } from '~stores/modalStore' +import CheckDogProfileSection from '../CheckDogProfileSection' +import { useToastStore } from '~stores/toastStore' +import { validateFamilyCode } from '~utils/validateDogProfile' +import Toast from '~components/Toast' export default function FamilyCodeSection() { - const handleClickPrev = () => {} + const { pushModal, popModal } = useModalStore() + const [familyCode, setFamilyCode] = useState('') + const { showToast } = useToastStore() + + const handleClickNext = () => { + const alertMessage = validateFamilyCode(familyCode) + if (alertMessage) { + showToast(alertMessage) + return + } + pushModal() + } return ( <> -
+
@@ -21,9 +38,14 @@ export default function FamilyCodeSection() { 코드를 입력해 주세요. - + setFamilyCode(e.target.value)} /> - 다음 + + + 다음 + + + ) diff --git a/src/modals/RegisterDogModal/FamilyCodeSection/styles.ts b/src/modals/RegisterDogModal/FamilyCodeSection/styles.ts index e56d421..c064e44 100644 --- a/src/modals/RegisterDogModal/FamilyCodeSection/styles.ts +++ b/src/modals/RegisterDogModal/FamilyCodeSection/styles.ts @@ -1,9 +1,14 @@ import { styled } from 'styled-components' export const FamilyCodeSection = styled.div` + z-index: 100; padding: 0 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; - height: 100dvh; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; display: flex; flex-direction: column; @@ -46,3 +51,7 @@ export const FamilyCodeInput = styled.input` font-weight: 400; } ` + +export const ToastWrapper = styled.div` + position: relative; +` diff --git a/src/stores/dogProfileStore.ts b/src/stores/dogProfileStore.ts index 2b8b811..257774f 100644 --- a/src/stores/dogProfileStore.ts +++ b/src/stores/dogProfileStore.ts @@ -1,15 +1,5 @@ import { create } from 'zustand' - -export interface DogProfileType { - name: string - image: string | undefined - birth: string - intro: string - gender: 'male' | 'female' | null - isNeutered: boolean - breed: string - weight: string -} +import { DogProfileType } from '~types/dogProfile' interface DogProfileStore { dogProfile: DogProfileType diff --git a/src/types/dogProfile.ts b/src/types/dogProfile.ts new file mode 100644 index 0000000..e5c677d --- /dev/null +++ b/src/types/dogProfile.ts @@ -0,0 +1,10 @@ +export interface DogProfileType { + name: string + image: string | undefined + birth: string + intro: string + gender: 'male' | 'female' | null + isNeutered: boolean + breed: string + weight: string +} diff --git a/src/utils/validateDogProfile.ts b/src/utils/validateDogProfile.ts index ced4bed..a61ee83 100644 --- a/src/utils/validateDogProfile.ts +++ b/src/utils/validateDogProfile.ts @@ -1,11 +1,7 @@ -interface DogProfileType { - name: string - image: string | undefined - birth: string - intro: string -} +import { DogProfileType } from '~types/dogProfile' const regex = /^[가-힣]+$/ +const familyCodeDummyData = ['TYK14TK2', '1234'] export const validateDogProfile = (dogProfile: DogProfileType): string | null => { if (!dogProfile.name) return '반려견의 이름을 입력해주세요' @@ -16,3 +12,16 @@ export const validateDogProfile = (dogProfile: DogProfileType): string | null => if (dogProfile.intro.length > 40) '한줄 소개는 최대 40자까지만 적어주세요' return null } + +export const validateDogDetailProfile = (dogProfile: DogProfileType): string | null => { + if (!dogProfile.gender) return '성별을 선택해주세요' + if (!dogProfile.breed) return '견종을 선택해주세요' + if (!dogProfile.weight) return '몸무게를 입력해주세요' + return null +} + +export const validateFamilyCode = (familyCode: string): string | null => { + if (!familyCode) return '가족 코드를 입력해주세요' + if (!familyCodeDummyData.includes(familyCode)) return '가족 코드가 유효하지 않습니다' + return null +} From 7b8710cb9d221e92d4f892ad54639b3958089434 Mon Sep 17 00:00:00 2001 From: wonil Date: Wed, 27 Nov 2024 12:14:47 +0900 Subject: [PATCH 8/9] =?UTF-8?q?=F0=9F=8E=A8=20Design:=20=EB=B0=98=EB=A0=A4?= =?UTF-8?q?=EA=B2=AC=20=EB=93=B1=EB=A1=9D=20=EC=B2=AB=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=82=AC=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/RegisterPage/Dog/styles.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/RegisterPage/Dog/styles.ts b/src/pages/RegisterPage/Dog/styles.ts index c77bbfa..7c79e9d 100644 --- a/src/pages/RegisterPage/Dog/styles.ts +++ b/src/pages/RegisterPage/Dog/styles.ts @@ -3,7 +3,11 @@ import { styled } from 'styled-components' export const RegisterDogPage = styled.div` padding: 120px 20px 24px 20px; background-color: ${({ theme }) => theme.colors.grayscale.gc_4}; - height: 100dvh; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; @media (max-height: 700px) { padding: 100px 20px 24px 20px; From 45db168774c48b024fbcc041149fd861a4ac5a13 Mon Sep 17 00:00:00 2001 From: wonil Date: Wed, 27 Nov 2024 12:32:58 +0900 Subject: [PATCH 9/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20Refactor:=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20prop=20=EC=95=9E=EC=97=90=20'$'=20=ED=91=9C?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/GenderSelectButton/index.tsx | 4 ++-- src/components/GenderSelectButton/styles.ts | 10 +++++----- src/components/Toast/index.tsx | 3 +-- src/components/Toast/styles.ts | 6 +++--- src/modals/DatePickerModal/index.tsx | 2 +- src/modals/DatePickerModal/styles.ts | 4 ++-- .../DogProfileDetailSection/index.tsx | 8 ++++---- .../DogProfileDetailSection/styles.ts | 18 +++++++++--------- .../DogProfileSection/DogImageUploader.tsx | 2 +- .../DogProfileSection/index.tsx | 2 +- .../DogProfileSection/styles.ts | 10 +++++----- 11 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/components/GenderSelectButton/index.tsx b/src/components/GenderSelectButton/index.tsx index 0a388c9..e7e658a 100644 --- a/src/components/GenderSelectButton/index.tsx +++ b/src/components/GenderSelectButton/index.tsx @@ -11,8 +11,8 @@ interface GenderSelectButtonProps { export default function GenderSelectButton({ gender, isActive, onClick }: GenderSelectButtonProps) { return ( - - + + {gender === 'male' ? '남' : '여'} ) diff --git a/src/components/GenderSelectButton/styles.ts b/src/components/GenderSelectButton/styles.ts index 836203f..c550326 100644 --- a/src/components/GenderSelectButton/styles.ts +++ b/src/components/GenderSelectButton/styles.ts @@ -1,10 +1,10 @@ import { styled } from 'styled-components' -export const GenderBtn = styled.button<{ isActive: boolean }>` - border: solid 2px ${({ isActive, theme }) => (isActive ? theme.colors.brand.darken : theme.colors.grayscale.gc_1)}; +export const GenderBtn = styled.button<{ $isActive: boolean }>` + border: solid 2px ${({ $isActive, theme }) => ($isActive ? theme.colors.brand.darken : theme.colors.grayscale.gc_1)}; border-radius: 8px; width: auto; height: 102px; - color: ${({ isActive, theme }) => (isActive ? theme.colors.brand.darken : theme.colors.grayscale.font_3)}; + color: ${({ $isActive, theme }) => ($isActive ? theme.colors.brand.darken : theme.colors.grayscale.font_3)}; display: flex; flex-direction: column; @@ -13,9 +13,9 @@ export const GenderBtn = styled.button<{ isActive: boolean }>` gap: 0.2rem; ` -export const GenderIcon = styled.img<{ isActive: boolean }>` +export const GenderIcon = styled.img<{ $isActive: boolean }>` filter: ${props => - props.isActive + props.$isActive ? 'invert(12%) sepia(70%) saturate(924%) hue-rotate(351deg) brightness(96%) contrast(97%)' : 'invert(31%) sepia(4%) saturate(61%) hue-rotate(332deg) brightness(99%) contrast(97%)'}; ` diff --git a/src/components/Toast/index.tsx b/src/components/Toast/index.tsx index 4496dd4..f94c498 100644 --- a/src/components/Toast/index.tsx +++ b/src/components/Toast/index.tsx @@ -1,4 +1,3 @@ -// components/Toast/index.tsx import * as S from './styles' import { useEffect } from 'react' import { useToastStore } from '~/stores/toastStore' @@ -16,7 +15,7 @@ export default function Toast() { }, [isVisible]) return ( - + {content} ) diff --git a/src/components/Toast/styles.ts b/src/components/Toast/styles.ts index 3a4f825..ba26058 100644 --- a/src/components/Toast/styles.ts +++ b/src/components/Toast/styles.ts @@ -1,6 +1,6 @@ import { styled } from 'styled-components' -export const ToastWrapper = styled.div<{ isVisible: boolean }>` +export const ToastWrapper = styled.div<{ $isVisible: boolean }>` position: absolute; top: -50px; @@ -8,8 +8,8 @@ export const ToastWrapper = styled.div<{ isVisible: boolean }>` display: flex; justify-content: center; - visibility: ${({ isVisible }) => (isVisible ? 'visiblie' : 'hidden')}; - opacity: ${({ isVisible }) => (isVisible ? 1 : 0)}; + visibility: ${({ $isVisible }) => ($isVisible ? 'visiblie' : 'hidden')}; + opacity: ${({ $isVisible }) => ($isVisible ? 1 : 0)}; transition: opacity 0.3s ease, visibility 0.3s ease; diff --git a/src/modals/DatePickerModal/index.tsx b/src/modals/DatePickerModal/index.tsx index 56b626f..a0ea97d 100644 --- a/src/modals/DatePickerModal/index.tsx +++ b/src/modals/DatePickerModal/index.tsx @@ -40,7 +40,7 @@ export default function DatePickerModal({ date, setDate }: DatePickerModalProps) return ( - + 확인 ` +export const DatePickerModal = styled.div<{ $isExiting: boolean }>` background-color: white; width: 100%; - animation: ${({ isExiting }) => (isExiting ? slideDown : slideUp)} 0.3s ease-out; + animation: ${({ $isExiting }) => ($isExiting ? slideDown : slideUp)} 0.3s ease-out; > div { padding: 1rem; diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx index cf133f2..473f9b1 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/index.tsx @@ -85,14 +85,14 @@ export default function DogProfileDetailSection() { /> setDogProfile({ isNeutered: !dogProfile.isNeutered })}> - + {dogProfile.isNeutered && check} - 중성화 했어요 + 중성화 했어요 - pushModal()} hasBreed={!!dogProfile.breed}> + pushModal()} $hasBreed={!!dogProfile.breed}> {dogProfile.breed || '견종 입력'} diff --git a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts index a238239..3f0620a 100644 --- a/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts +++ b/src/modals/RegisterDogModal/DogProfileDetailSection/styles.ts @@ -48,10 +48,10 @@ export const CheckboxWrapper = styled.div` gap: 0.5rem; ` -export const CheckboxCircle = styled.div<{ isChecked: boolean }>` +export const CheckboxCircle = styled.div<{ $isChecked: boolean }>` width: 24px; height: 24px; - border: 2px solid ${({ isChecked }) => (isChecked ? '#000' : '#ccc')}; + border: 2px solid ${({ $isChecked }) => ($isChecked ? '#000' : '#ccc')}; border-radius: 50%; display: flex; @@ -60,8 +60,8 @@ export const CheckboxCircle = styled.div<{ isChecked: boolean }>` cursor: pointer; ` -export const CheckboxLabel = styled.span<{ isChecked: boolean }>` - color: ${({ isChecked }) => (isChecked ? '#000' : '#ccc')}; +export const CheckboxLabel = styled.span<{ $isChecked: boolean }>` + color: ${({ $isChecked }) => ($isChecked ? '#000' : '#ccc')}; ` export const InputArea = styled.div` @@ -74,25 +74,25 @@ export const InputArea = styled.div` } ` -export const PickerBtn = styled.div<{ hasBreed: boolean }>` +export const PickerBtn = styled.div<{ $hasBreed: boolean }>` width: 100%; border: none; text-align: center; padding: 17px 32px; font-size: ${({ theme }) => theme.typography._20}; - color: ${({ theme, hasBreed }) => (hasBreed ? 'black' : theme.colors.grayscale.font_3)}; - font-weight: ${({ hasBreed }) => (hasBreed ? 'bold' : 'default')}; + color: ${({ theme, $hasBreed }) => ($hasBreed ? 'black' : theme.colors.grayscale.font_3)}; + font-weight: ${({ $hasBreed }) => ($hasBreed ? 'bold' : 'default')}; cursor: pointer; ` -export const WeightInput = styled.input<{ hasWeight: boolean }>` +export const WeightInput = styled.input<{ $hasWeight: boolean }>` width: 100%; border: none; text-align: center; padding: 17px 32px; border-radius: 12px; font-size: ${({ theme }) => theme.typography._20}; - font-weight: ${({ hasWeight }) => (hasWeight ? 'bold' : 'default')}; + font-weight: ${({ $hasWeight }) => ($hasWeight ? 'bold' : 'default')}; &:focus { box-shadow: ${({ theme }) => `inset 0 0 0 1px ${theme.colors.grayscale.font_1}`}; } diff --git a/src/modals/RegisterDogModal/DogProfileSection/DogImageUploader.tsx b/src/modals/RegisterDogModal/DogProfileSection/DogImageUploader.tsx index 77260f4..d7a8db1 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/DogImageUploader.tsx +++ b/src/modals/RegisterDogModal/DogProfileSection/DogImageUploader.tsx @@ -27,7 +27,7 @@ export default function DogImageUploader({ image, setImage }: DogImageUploaderPr 반려견 사진 추가
반려견 사진 추가
- {image && } + {image && } ) diff --git a/src/modals/RegisterDogModal/DogProfileSection/index.tsx b/src/modals/RegisterDogModal/DogProfileSection/index.tsx index 76b0533..c88a660 100644 --- a/src/modals/RegisterDogModal/DogProfileSection/index.tsx +++ b/src/modals/RegisterDogModal/DogProfileSection/index.tsx @@ -61,7 +61,7 @@ export default function DogProfileSection() { value={dogProfile.name} onChange={e => setDogProfile({ name: e.target.value })} /> - + {dogProfile.birth || '생년월일 선택'} ` +export const DogImage = styled.img<{ $hasImage: boolean }>` position: absolute; - z-index: ${({ hasImage }) => (hasImage ? '100' : '-100')}; + z-index: ${({ $hasImage }) => ($hasImage ? '100' : '-100')}; top: 0; left: 0; width: 100%; @@ -96,14 +96,14 @@ export const NameInput = styled.input` } ` -export const DatePickerBtn = styled.div<{ hasBirth: boolean }>` +export const DatePickerBtn = styled.div<{ $hasBirth: boolean }>` width: 100%; border: none; text-align: center; padding: 17px 32px; font-size: ${({ theme }) => theme.typography._20}; - color: ${({ theme, hasBirth }) => (hasBirth ? 'black' : theme.colors.grayscale.font_3)}; - font-weight: ${({ hasBirth }) => (hasBirth ? '700' : '400')}; + color: ${({ theme, $hasBirth }) => ($hasBirth ? 'black' : theme.colors.grayscale.font_3)}; + font-weight: ${({ $hasBirth }) => ($hasBirth ? '700' : '400')}; cursor: pointer; ` export const ActionButtonArea = styled.div`