From babd3bc48fafe65dff2f40c91d0aab301e1091d6 Mon Sep 17 00:00:00 2001 From: joojjang Date: Sun, 29 Sep 2024 06:09:22 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor(cta):=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=AA=A8=EB=93=88=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/cta/index.tsx | 58 +++++++++++++++++++++++++++++ src/pages/review-write/index.tsx | 48 ++++-------------------- 2 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 src/components/common/cta/index.tsx diff --git a/src/components/common/cta/index.tsx b/src/components/common/cta/index.tsx new file mode 100644 index 0000000..b6fcc9b --- /dev/null +++ b/src/components/common/cta/index.tsx @@ -0,0 +1,58 @@ +import styled from '@emotion/styled'; + +type CTAProps = { + label: string; + disabled?: boolean; + onClick: () => void; +}; + +export const CTA = ({ label, disabled, onClick }: CTAProps) => { + return ( + + {label} + + ); +}; + +export default CTA; + +const StyledCTA = styled.button<{ disabled?: boolean }>` + width: 100%; + height: 100%; + border: none; + border-radius: 10px; + background-color: var(--color-green-01); + color: var(--color-white); + font-size: var(--font-size-md); + font-weight: bold; + outline: none; + + &:disabled { + cursor: not-allowed; + color: var(--color-grey-01); + background-color: var(--color-grey-02); + } + + /* &:hover와 &:focus는 disabled가 false일 때만 적용 */ + &:hover, + &:focus { + ${({ disabled }) => + !disabled && + ` + opacity: 0.8 !important; + background-color: var(--color-green-01) !important; + color: var(--color-white) !important; + `} + } +`; + +// 컨테이너 필요할 때 따로 임포트하여 사용 +export const CTAContainer = styled.div` + position: sticky; + bottom: 0; + display: flex; + width: 100%; + height: 4rem; + padding: 8px 16px; + background-color: var(--color-white); +`; diff --git a/src/pages/review-write/index.tsx b/src/pages/review-write/index.tsx index 20511e6..b55be2d 100644 --- a/src/pages/review-write/index.tsx +++ b/src/pages/review-write/index.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { postReview } from '@/apis/review/review.api'; +import CTA, { CTAContainer } from '@/components/common/cta'; import { StarRating } from '@/components/common/star-rating'; import TopBar from '@/components/features/layout/top-bar'; import { useChallengeStore } from '@/store/useChallengeStore'; @@ -184,11 +185,13 @@ const ReviewWrite = () => { 될 수 있습니다. - - - 등록하기 - - + + + ); @@ -288,38 +291,3 @@ const Content = styled.textarea<{ valid?: boolean }>` : 'var(--color-class-05) 1px solid'}; } `; - -const CTABox = styled(Box)` - position: sticky; - bottom: 0; - display: flex; - width: 100%; - height: 4rem; - padding: 8px 16px; - background-color: var(--color-white); -`; - -const SubmitButton = styled.button<{ disabled?: boolean }>` - width: 100%; - height: 100%; - border: none; - border-radius: 10px; - background-color: var(--color-green-01); - color: var(--color-white); - font-size: var(--font-size-md); - font-weight: bold; - outline: none; - - &:disabled { - cursor: not-allowed; - color: var(--color-grey-01); - background-color: var(--color-grey-02); - } - - &:focus, - &:hover { - opacity: 0.8 !important; - background-color: var(--color-green-01) !important; - color: var(--color-white) !important; - } -`; From 2dfe6e3397b18f39c3964676ddd43ce8b0dc20ec Mon Sep 17 00:00:00 2001 From: joojjang Date: Sun, 29 Sep 2024 06:28:32 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor(cta,=20challenge-item):=20cta=20?= =?UTF-8?q?=EA=B3=B5=ED=86=B5=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - padding과 margin에 대한 건 아직 잘 모르겠음 왜 이렇게 하니까 의도한 대로 나오는 건지... --- src/components/common/cta/index.tsx | 7 ++++--- .../components/challenge-item/index.tsx | 5 ++++- .../components/challenge-item/styles.ts | 13 ------------- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/components/common/cta/index.tsx b/src/components/common/cta/index.tsx index b6fcc9b..b810088 100644 --- a/src/components/common/cta/index.tsx +++ b/src/components/common/cta/index.tsx @@ -17,8 +17,7 @@ export const CTA = ({ label, disabled, onClick }: CTAProps) => { export default CTA; const StyledCTA = styled.button<{ disabled?: boolean }>` - width: 100%; - height: 100%; + width: calc(100% - 16px); // 부모 요소의 좌우 padding 빼고 border: none; border-radius: 10px; background-color: var(--color-green-01); @@ -26,6 +25,8 @@ const StyledCTA = styled.button<{ disabled?: boolean }>` font-size: var(--font-size-md); font-weight: bold; outline: none; + padding: 10px 8px; + margin: 0 auto; &:disabled { cursor: not-allowed; @@ -33,7 +34,7 @@ const StyledCTA = styled.button<{ disabled?: boolean }>` background-color: var(--color-grey-02); } - /* &:hover와 &:focus는 disabled가 false일 때만 적용 */ + /* &:hover와 &:focus는 disabled === false일 때만 적용 */ &:hover, &:focus { ${({ disabled }) => diff --git a/src/pages/challenge-detail/components/challenge-item/index.tsx b/src/pages/challenge-detail/components/challenge-item/index.tsx index 0ba4453..af7603a 100644 --- a/src/pages/challenge-detail/components/challenge-item/index.tsx +++ b/src/pages/challenge-detail/components/challenge-item/index.tsx @@ -4,7 +4,9 @@ import * as S from './styles'; import { joinChallenge } from '@/apis/challenge-detail/challenge.detail.api'; import { type Challenge } from '@/apis/challenge-detail/challenge.detail.response'; import { Chip } from '@/components/common/chip'; +import CTA from '@/components/common/cta'; import { getDynamicPath } from '@/routes/protected-route'; +import { Box } from '@chakra-ui/react'; type Props = { challenge: Challenge; @@ -71,7 +73,8 @@ const ChallengeItem = ({ challenge, maxDifficulty }: Props) => { - 참여하기 + + ); }; diff --git a/src/pages/challenge-detail/components/challenge-item/styles.ts b/src/pages/challenge-detail/components/challenge-item/styles.ts index 7ffa057..ac66182 100644 --- a/src/pages/challenge-detail/components/challenge-item/styles.ts +++ b/src/pages/challenge-detail/components/challenge-item/styles.ts @@ -68,16 +68,3 @@ export const Bar = styled(MaxBar)<{ width: number }>` export const TimesPeriodContent = styled(Text)` margin: 0 0 0 auto; `; - -export const CTA = styled.button` - width: calc(100% - 16px); // 부모 요소의 좌우 padding 빼고 - padding: 10px 8px; - margin: auto; - border-radius: 10px; - background-color: var(--color-green-01); - color: var(--color-white); - font-weight: bold; - font-size: var(--font-size-md); - - margin-top: 16px; -`; From 529436495d54901a1b461c061813e59c508729c0 Mon Sep 17 00:00:00 2001 From: joojjang Date: Sun, 29 Sep 2024 06:30:42 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix(cta):=20default=20export=EB=A1=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 --- src/components/common/cta/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/cta/index.tsx b/src/components/common/cta/index.tsx index b810088..ca8ad21 100644 --- a/src/components/common/cta/index.tsx +++ b/src/components/common/cta/index.tsx @@ -6,7 +6,7 @@ type CTAProps = { onClick: () => void; }; -export const CTA = ({ label, disabled, onClick }: CTAProps) => { +const CTA = ({ label, disabled, onClick }: CTAProps) => { return ( {label} From 830b4b7b5bde21be07122128dc5ba70967727c86 Mon Sep 17 00:00:00 2001 From: joojjang Date: Sun, 29 Sep 2024 06:49:44 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor(textarea):=20=EB=AA=A8=EB=93=88?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/form/textarea/index.tsx | 48 +++++++++++++++++++ src/pages/review-write/index.tsx | 32 ++----------- 2 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 src/components/common/form/textarea/index.tsx diff --git a/src/components/common/form/textarea/index.tsx b/src/components/common/form/textarea/index.tsx new file mode 100644 index 0000000..c2b1b2d --- /dev/null +++ b/src/components/common/form/textarea/index.tsx @@ -0,0 +1,48 @@ +import styled from '@emotion/styled'; + +type TextareaProps = { + placeholder?: string; + value: string; + onChange: (e: React.ChangeEvent) => void; + valid?: boolean; +}; + +const Textarea = ({ placeholder, value, onChange, valid }: TextareaProps) => { + return ( + + ); +}; + +export default Textarea; + +const StyledTextarea = styled.textarea<{ valid?: boolean }>` + font-size: var(--font-size-sm); + color: var(--color-black); + border-radius: 20px; + border: ${({ valid }) => + valid + ? 'var(--color-grey-02) 1px solid' + : 'var(--color-class-05) 1px solid'}; + padding: 12px; + width: 100%; + height: 180px; + resize: none; + outline: none; + + &::placeholder { + color: var(--color-grey-01); + opacity: 1; /* Firefox에서 placeholder 색상을 명시적으로 설정하기 위해 추가 */ + } + + &:focus { + border: ${({ valid }) => + valid + ? 'var(--color-green-01) 1px solid' + : 'var(--color-class-05) 1px solid'}; + } +`; diff --git a/src/pages/review-write/index.tsx b/src/pages/review-write/index.tsx index b55be2d..a831f59 100644 --- a/src/pages/review-write/index.tsx +++ b/src/pages/review-write/index.tsx @@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom'; import { postReview } from '@/apis/review/review.api'; import CTA, { CTAContainer } from '@/components/common/cta'; +import Textarea from '@/components/common/form/textarea'; import { StarRating } from '@/components/common/star-rating'; import TopBar from '@/components/features/layout/top-bar'; import { useChallengeStore } from '@/store/useChallengeStore'; @@ -62,12 +63,14 @@ const ReviewWrite = () => { const handleContentChange = (e: React.ChangeEvent) => { const newContent = e.target.value; setContent(newContent); + // console.log(content); // test if (newContent.trim() && newContent.length >= 20) { setIsContentValid(true); } else { setIsContentValid(false); } + // console.log(isContentValid); // test }; const handleSaveReview = () => { @@ -156,7 +159,7 @@ const ReviewWrite = () => { 소감 - ` color: var(--color-green-01); `} `; - -const Content = styled.textarea<{ valid?: boolean }>` - font-size: var(--font-size-sm); - color: var(--color-black); - border-radius: 20px; - border: ${({ valid }) => - valid - ? 'var(--color-grey-02) 1px solid' - : 'var(--color-class-05) 1px solid'}; - padding: 12px; - width: 100%; - height: 180px; - resize: none; - outline: none; - - &::placeholder { - color: var(--color-grey-01); - opacity: 1; /* Firefox에서 placeholder 색상을 명시적으로 설정하기 위해 추가 */ - } - - &:focus { - border: ${({ valid }) => - valid - ? 'var(--color-green-01) 1px solid' - : 'var(--color-class-05) 1px solid'}; - } -`;