From 5b9a3cc6e0df31e479720e08b042ead2a0c45ab4 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Wed, 6 Dec 2023 09:57:14 +0900 Subject: [PATCH 01/17] =?UTF-8?q?:lipstick:=20Header=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20width=20100%=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/select/page.tsx | 15 +++++++++++++++ src/components/Layout/Header.tsx | 1 + 2 files changed, 16 insertions(+) create mode 100644 src/app/select/page.tsx diff --git a/src/app/select/page.tsx b/src/app/select/page.tsx new file mode 100644 index 00000000..b348ce1e --- /dev/null +++ b/src/app/select/page.tsx @@ -0,0 +1,15 @@ +import Header from '@/components/Layout/Header'; +import { css } from '@styled-system/css'; + +export default function SelectPage() { + return ( +
+
+
+ ); +} + +const MainWrapperCss = css({ + width: '100%', + height: '100vh', +}); diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index 2afc2c6c..629ee172 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -27,6 +27,7 @@ const headerBlankCss = { const wrapperCss = flex({ padding: '10px 16px', + width: '100%', gap: '6px', background: 'transparent', position: 'fixed', From 7c981830961d427e7fdea479e72e3f71574f2628 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 00:27:02 +0900 Subject: [PATCH 02/17] =?UTF-8?q?:lipstick:=20RadioInput=20and=20RadioInpu?= =?UTF-8?q?tWithEmoji=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/select/RadioInput.tsx | 75 ++++++++++++++++++++++++++ src/app/select/RadioInputWithEmoji.tsx | 25 +++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/app/select/RadioInput.tsx create mode 100644 src/app/select/RadioInputWithEmoji.tsx diff --git a/src/app/select/RadioInput.tsx b/src/app/select/RadioInput.tsx new file mode 100644 index 00000000..189632de --- /dev/null +++ b/src/app/select/RadioInput.tsx @@ -0,0 +1,75 @@ +import { type InputHTMLAttributes, type PropsWithChildren } from 'react'; +import CheckCircleIcon from '@/app/select/CheckCircleIcon'; +import { css } from '@styled-system/css'; +import { flex } from '@styled-system/patterns'; + +const purple = '#8D96F0'; +const lightPurple = '#EFF1FF'; +const grey100 = '#F2F4F6'; + +/** + * 디자인 시스템이 확정되지 않아서 component 페이지에 넣지 않고 select 폴더에 넣었습니다. + */ +export default function RadioInput({ + children, + ...props +}: PropsWithChildren, 'type'>>) { + return ( + + ); +} + +const subtitle = { + fontSize: '16px', + fontWeight: 600, + lineHeight: '24px', +}; + +const labelCss = css({ + cursor: 'pointer', +}); + +const RadioInputWrapperCss = flex({ + padding: '10px 16px', + borderRadius: '36px', + ...subtitle, + background: grey100, + + justifyContent: 'space-between', + + alignItems: 'center', + + transition: '0.3s ease', + + '& svg': { + display: 'none', + }, +}); + +const InputWrapperCss = css({ + position: 'absolute', + opacity: 0, + height: 0, + width: 0, + _checked: { + '& ~ div': { + color: purple, + backgroundColor: lightPurple, + '& svg': { + display: 'block', + }, + }, + }, +}); diff --git a/src/app/select/RadioInputWithEmoji.tsx b/src/app/select/RadioInputWithEmoji.tsx new file mode 100644 index 00000000..581ce296 --- /dev/null +++ b/src/app/select/RadioInputWithEmoji.tsx @@ -0,0 +1,25 @@ +import Image from 'next/image'; +import RadioInput from '@/app/select/RadioInput'; +import { css } from '@styled-system/css'; + +export default function RadioInputWithImg({ + imgSrc, + label, + ...props +}: { + imgSrc: string; + label: string; + name: string; + value: string; +}) { + return ( + + {label} + {label} + + ); +} + +const emojiBoxCss = css({ + marginRight: '8px', +}); From c7cb0ca85ad94e6f7b04fb731d16b3652fc914b5 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 00:29:26 +0900 Subject: [PATCH 03/17] =?UTF-8?q?:sparkles:=20header=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EC=97=90=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Layout/Header.tsx | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/components/Layout/Header.tsx b/src/components/Layout/Header.tsx index 629ee172..4f036f40 100644 --- a/src/components/Layout/Header.tsx +++ b/src/components/Layout/Header.tsx @@ -1,4 +1,7 @@ +'use client'; + import Image from 'next/image'; +import { useRouter } from 'next/navigation'; import { flex } from '@/styled-system/patterns'; import { css } from '@styled-system/css'; @@ -7,10 +10,16 @@ interface Props { } function Header({ title }: Props) { + const router = useRouter(); + + const handleButtonClick = () => { + router.back(); + }; + return ( <>
-

{title}

@@ -21,13 +30,14 @@ function Header({ title }: Props) { } const headerBlankCss = { - height: '42px;', + height: '40px;', width: '100%', }; const wrapperCss = flex({ - padding: '10px 16px', width: '100%', + + padding: '10px 16px', gap: '6px', background: 'transparent', position: 'fixed', @@ -35,9 +45,14 @@ const wrapperCss = flex({ zIndex: 100, }); +const buttonCss = css({ + cursor: 'pointer', +}); + const headingCss = css({ color: '#6B7684', fontSize: '16px', + lineHeight: '20px', fontFamily: 'Pretendard', fontWeight: '600', }); From 7a961b008819a08f2dbb44f70254d95331192bd0 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 00:31:02 +0900 Subject: [PATCH 04/17] =?UTF-8?q?:bento:=20emoji=20assets=20and=20checkCir?= =?UTF-8?q?cle=20icon=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/emoji-book.png | Bin 0 -> 5296 bytes public/images/emoji-exercise.png | Bin 0 -> 4349 bytes public/images/emoji-labtop.png | Bin 0 -> 2998 bytes public/images/emoji-open-book.png | Bin 0 -> 5965 bytes public/images/emoji-pen.png | Bin 0 -> 4860 bytes public/images/emoji-speech-bubble.png | Bin 0 -> 3437 bytes src/app/select/CheckCircleIcon.tsx | 21 ++++++++++++++++ src/app/select/page.tsx | 34 +++++++++++++++++++++++++- 8 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 public/images/emoji-book.png create mode 100644 public/images/emoji-exercise.png create mode 100644 public/images/emoji-labtop.png create mode 100644 public/images/emoji-open-book.png create mode 100644 public/images/emoji-pen.png create mode 100644 public/images/emoji-speech-bubble.png create mode 100644 src/app/select/CheckCircleIcon.tsx diff --git a/public/images/emoji-book.png b/public/images/emoji-book.png new file mode 100644 index 0000000000000000000000000000000000000000..368313720894330e56bbe34c4f603e921c0fb242 GIT binary patch literal 5296 zcma)=Wmgmo*M&h!7`nTWhLIe)I~+ohlm>~RLy+!n7#gH=Xc&+VL1_?%zR3ZR?tXp# z!MoSG&R+X`KI?qgF<@;KJRE8q6ciLZHC093f9~`@USs~7Nwx+P{|wtz)zAY4g$eXO zP?a*@n*Up(dg!Xiqts8*9{daFc5+&BC@76dfJX}q6ckb=HAOjnU(_QL<9O3W!{^0i z|H743e)<)+Ew{hQS`DLRYMQ$9EuY`(`^sj>v+Bo4U!o2ueN!YP{63C`LvR^^r7!$? zo`Ti>wW>3lZ0H+sbhth>+h^im&Q3oXrMBT;_Qv5yzl`EuJ{^8~`0KW;(z2F!W#~U? zbG>BeAMo(-a`Ljcj7IqX6)=U+mFB;spgTbo{-^zOLmSUV!O?GBS>#<6dv=?LJpWWq38Oj1UbxIk>*y@4o+(CDJZ) zjo41=pIUuE$$K7^0!j&@8GQyT;SUBfr1qoO;&)E3u7z0pP*8VxT|?xL&+NV3 z_q(u{ZAZOX9!5M@uU;(p0x*B*^!KMbRvre!kePWRRReALz#Y*3B&jMZZzhpqO3Tg{ z=Fg-Fghj%{*>+%a)rp&%V#E?^YY1ySEUa(Bq!<5u4_{HS{AY~+cMj&{+k72nov+xV zwwk5#;o;0x0ZWieaIwD*3*3@=!qM*l(N2Fm2MZ)|kjE8f(u8r_7NAeNj+rjmjev#+WXLY)*b zG&vChiYS!u!G{rGU=XV(Q8Rdq=d$Qq#u^9S2|yDLKNJs_X;hBmmW%jQRHE4doy4mpEfI zI%}-89Z6`Jgj_)<7Hc&jwU$Qu!p{gD)?_|><``8c5$b73>t8WWW*0x|@t-(-VFdCa zg}=^eJ1NaXd!L*~U#<_6$<@hM3|K0$TZtA0VCZisbZ!D_oXI-*%Vwgmc0un$^>AjNcm2f$fqY9TGDZv z52(=n5o_ufD!)Yknt>$|W~o7+hsuGqg7=KcZ{=7}k9dJ`2L0nLedfNubzUv~WgeB7 zl67BHVU+g6iaww!a>`+GBTjNz<3J41KPl6!2R=A+%#v0nuV@3@ntq3Of@v%!M&kXM zeO;aOFE1NAaJiF;G{kju67_GyD3k*PO68QZP%%q5aD_J%fdsb_k);c_~nc$$Q>omDBG$Ar2DZnUtBF99q)ZP>H|B_ zUr)ZX<5Q~Aj~hE1{?xk?l1gB4sYlFqB{JA$Iv9Y=3oy!6Y2wqkS+^PIJs9Vq9sV&P z6o%pH!(J|~ZMbtEtthFi$fVn0l`7A?ZDOy8#r8|vdef!sNxHvujt^SbP`CRN^+P}z zXZT*J$bdt0MR04y+r7+n=w=>frV@_DbxOUTXCM{%AZPU!icgO6`DDrPiMfgu1z_`{ zWd7N19S+Ar`&w8)F;EpV+QikrC?;L87@JgQD5X7C?{gsEvb;K1e4K8bl(zH3s zdu5`kXv(+c^AT#gD`sv=QW?tkAD7r~6IN!pR}A2!eOOyav0RRO1Gd0hAffm*(j`l& zqEbCvyP~3mct!rHmc>E~H%UtXwT)cQlOsAMF96@mngh2>)jh@&w}yQ6CLk}9io;or zxQ*4kETn9Zig?9l)9TiPXxoFt0rVw&GrYt+x1USEYQPn=f8SOxSPeFkw`&Br1;Z#B z*MyP`z9#PAb?C`;%f9RU4-(^w<@!S8?;b3|t zi>HE!&EYl9RAe>9Pt}UyDQTI49n*eQQ@!U;FOW2b&FXhB5&xIae54dY*`)#z(+Tm% zdp|!^e!^TGKVT3~2GR7egQk5*?y%g)+4N7M4WZLVV6fWS3iVMN^wC{XZEp3RR87n5 z0$flQu{YxsQtmtOScW!_0o{wi_u!4o*fGwS_rG$RPUOBQd7#=3GF6o=MbbCj&{uyR zD>9}nUg|?$d<@cRK4YZl2qsByzWqu@R?#?UHgrp)Pd*lw)1FQ<#-=+u^mC1DT>3ht z**eSD5&xlxts3i!QM@Uc6t6`|&IDpFZsnYBn-bu^Ubz>$`3W)@1mE6xM>iqA$I;Z{96+3E2ELp>q` zsnV-Qf_S8xB|wulM#++Ayi?jS*0W(sAer#J`caDF7h`LULDLSm@9XOr`|*K2@+K0^ zSfO=nmZcw1IsIWLlWCg6N13IolyPp7j>|jcEt0#w?dR4sZ4M-4S*LIyzWIvu-szOc zwGy&000(Vopo>ta4wfB({}aOD{JgM7fooBZ^LE*nQq8@waFb2g4b;tqs%X-W`gzcF|huG~WJa*TmgcU z{aNQw&=;%BgPE`HzFRt&ad+vWh8_aDWa4zF^a2Y*8g&CyFX`~J)F+stHWjXiauVn5 zSN1#peNl;Sx#G!0etg#U+Q06O^wvRTD+5Md!!?b7R9hNGU} z9)w%dL)B;DuY4x^A}%_?F75OqVeifEzOtz}QG1rTUkmo_P^)RJKa&tGcf^cA6`*_H zD;n3reek|CXc?{uuB6YEa-|{9R>Hh2lhBc zZ#$hx{RQpSdyg(sO{X~6R{YyLq2#f;A$6-1!R-B+c(rZ1{UcE-pValWA;ej)ORL(x zthp|Rf@f76H`K(;`}i$=65M@)DDglM6QNkbb^r+0I$NjvuB&xk72zra4*+7;X8XNH z$O_}((T3}Y^Tow7x3?5XfkVLV@d-Fbkk`2*9`Da6;xr@F)3l@LB)e+v0WDedzDh^! zm8>(l+c8kiKnJmZzBxk<-B~UQiGNFf@j_5;p~27zI4}lRU72vD?c|o~x$qB3XcM)m zN?kra;O(1g^qbr82|3khYpYlFWNchResK(L&4|;4kQ|R9^RU#F3FM^eCHvt8$Rcz zGBXj9>K2~kAJ6CUf#w z)J~MovtGfk1$Ol`_&I5RZJTi-P22Q~4VB=WoaMfG8iD^L;0S7}FnAsH@(}2H)IB=? zNS0Bv(GjCT6CZx4KP>=S={Ns@ym+4-HiVG4RVwlBNuZcFU!?OWdoa0j`l%grcZQUN z=i}=+*PriGw)03JH_{Bjw8u`M?Y4}|&H3rI785;eJMbfnxkj==R$vQb1Hua0SUMmx zYqwwdSX!&#GZ+s*x*wQM1hH0KC-0ve-%MdEv7wWXmk5;CHY+NTElYr2P+bF*CX|HX z8pgtIs~2G|2xkX~+#M(BgjaU^X`44m#x8{Xir2GdV&Ru@-iOvr2N!jqtNmnbUQ1VR zY63=0gsB)s-(Sl9n$b0OTV&TbVsd5sLW|gwoCvhSk1%z(NE0Np=>Szvu`MVg{`~n< zHat8GV^ceKhz;QK$+8;G_=2Hxs78aIQr>c&gRHM55rUY07wFO3(pUA#yUk47Svqvn z!F4*LOL@*@-C!ch0E}{v7n%`k71aej-yvQ88$6LbA7vREOJhIrKWbf+UOT*!UgMmN zDyLWmI6!?Ov)#o8!4k2#4Stf&F6?|?Vj~OUR1piQ-8HjaDuVbWd_&a7h-MZyE%i4m z-Pdy*A_nKxRn@3fuq)#rd_n%6Tjr;iPZiG2&PV)yG&H}OIs$pb_GK1Uj{?^{u^4FR zaI<1phm`6Wk&=5ZP{!21TK<>Fq>hh#+?`D*SRa@_lIRkfyp=3B(hMt92tGUMPAmQG zkx(jf=w>``LH`)VCE6QGBi$3S0^o-|-JcJ18PF$QcfP9(>nAbf@0O9FoGh=Z$xiqF zGP;sJ>V2Q@cFHYAnuSKhPunU66VNEqGVEb+xD6G3^L2`9a9^2)@H*{uXBluQn*W^9 z)?N_UNwh{smoWeQqe8S@y5<@Ssr>W^5gsqch@2YlaNW-<^z^BF-JXMhxurX8u)NW1 zZ02!<;XLL;ub-Qlk;$BK_Kdof*zHml@AJGiF9KGd3)-?4dn9{Z&#-(HV4#XFtX}BJ z)zohHjBZeLk8u|S1Dj=wJi{Y@;7N!4IgP$;@cje`cxgTF3t^ z!I;QQDH`sUo9!5CW*Q23Cxym51sK|}F}%i_lDb*NoR23Uvv?1_T@@?Nq|SZvuyjOv zbgoEbUCqrc0Sl)DaXcdJGE8a4GtiFj=4r`CYJQy#RusTf2{40vpC9kC%zQT^#3gju zq+7z*V%rxM%CSy*{BTT>CByxv&3?T%XFBack{a(zz#}<0U2o7cqHHkwOaZwvw*x2A z&wsOeJc%GInz$D2Tf4oFbqDYl_<8fe!ZmyBQ`kG}u$hu-Q4=aWz+2%JOn9f~^H|W` zbAW5Eg(Y^))^2NShsW8LiP_&(mp0KLrb$eKzcAXD!>NGn4YSbT|F>39U$6wh1^7Xu Tz8wDwMiezAZN++d^U(hTkFXzJ literal 0 HcmV?d00001 diff --git a/public/images/emoji-exercise.png b/public/images/emoji-exercise.png new file mode 100644 index 0000000000000000000000000000000000000000..aa977ca74ce330193bab80effe16dc142738ae17 GIT binary patch literal 4349 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 literal 0 HcmV?d00001 diff --git a/public/images/emoji-open-book.png b/public/images/emoji-open-book.png new file mode 100644 index 0000000000000000000000000000000000000000..2852bc0db349bb5c03656b9296951ed63b706097 GIT binary patch literal 5965 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 SyZg_qBG6XXhu5p3BmM*6^b|J$ literal 0 HcmV?d00001 diff --git a/public/images/emoji-speech-bubble.png b/public/images/emoji-speech-bubble.png new file mode 100644 index 0000000000000000000000000000000000000000..8d6cbbf77fe90b0dbf524c39510c72986df7d4a1 GIT binary patch literal 3437 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 literal 0 HcmV?d00001 diff --git a/src/app/select/CheckCircleIcon.tsx b/src/app/select/CheckCircleIcon.tsx new file mode 100644 index 00000000..a5e0674e --- /dev/null +++ b/src/app/select/CheckCircleIcon.tsx @@ -0,0 +1,21 @@ +import { type SVGProps } from 'react'; + +export default function CheckCircleIcon(props: SVGProps) { + return ( + + + + + + + + + + + ); +} diff --git a/src/app/select/page.tsx b/src/app/select/page.tsx index b348ce1e..eca0e855 100644 --- a/src/app/select/page.tsx +++ b/src/app/select/page.tsx @@ -1,15 +1,47 @@ +import RadioInputWithEmoji from '@/app/select/RadioInputWithEmoji'; import Header from '@/components/Layout/Header'; import { css } from '@styled-system/css'; export default function SelectPage() { return (
-
+
+
+

+ 하루 10분
+ 어떤 일에 투자하고 싶은가요? +

+
+ + + + +
); } +const grey800 = '#333D4B'; +const purple = '#8D96F0'; + const MainWrapperCss = css({ width: '100%', height: '100vh', }); + +const containerCss = css({ + padding: '24px 16px', +}); + +const MainTitleCss = css({ + marginTop: '2px', + fontSize: '24px', + fontWeight: 700, + lineHeight: '30px', + + color: grey800, + '& strong': { + color: purple, + fontWeight: 700, + }, +}); From 9dd6c423dd4bd8b3d2e7768e1d7406d2a8a9cf59 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 11:33:33 +0900 Subject: [PATCH 05/17] =?UTF-8?q?:truck:=20=ED=8C=8C=EC=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=98=A4=ED=83=80=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../images/{emoji-labtop.png => emoji-laptop.png} | Bin ...ioInputWithEmoji.tsx => RadioInputWithImg.tsx} | 14 +++++--------- 2 files changed, 5 insertions(+), 9 deletions(-) rename public/images/{emoji-labtop.png => emoji-laptop.png} (100%) rename src/app/select/{RadioInputWithEmoji.tsx => RadioInputWithImg.tsx} (57%) diff --git a/public/images/emoji-labtop.png b/public/images/emoji-laptop.png similarity index 100% rename from public/images/emoji-labtop.png rename to public/images/emoji-laptop.png diff --git a/src/app/select/RadioInputWithEmoji.tsx b/src/app/select/RadioInputWithImg.tsx similarity index 57% rename from src/app/select/RadioInputWithEmoji.tsx rename to src/app/select/RadioInputWithImg.tsx index 581ce296..ec386ea0 100644 --- a/src/app/select/RadioInputWithEmoji.tsx +++ b/src/app/select/RadioInputWithImg.tsx @@ -1,17 +1,13 @@ import Image from 'next/image'; -import RadioInput from '@/app/select/RadioInput'; +import RadioInput, { type RadioInputProps } from '@/app/select/RadioInput'; import { css } from '@styled-system/css'; -export default function RadioInputWithImg({ - imgSrc, - label, - ...props -}: { +interface RadioInputWithEmojiProps extends RadioInputProps { imgSrc: string; label: string; - name: string; - value: string; -}) { +} + +export default function RadioInputWithImg({ imgSrc, label, ...props }: RadioInputWithEmojiProps) { return ( {label} From dfbf4d6ff92ed5e30f40cdfd2ecd985c8e8b9514 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 11:36:07 +0900 Subject: [PATCH 06/17] =?UTF-8?q?:bug:=20=EB=B2=84=ED=8A=BC=20type=20props?= =?UTF-8?q?=20overriding=20=EB=90=98=EA=B2=8C=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Button.tsx b/src/components/Button.tsx index eabeda54..8411effc 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -4,7 +4,7 @@ interface ButtonProps extends ButtonHTMLAttributes {} const Button: React.FC = ({ className, children, ...props }) => { return ( - ); From 66241fd1b6222698aa49f4dca1506e8ade0d8936 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 11:36:51 +0900 Subject: [PATCH 07/17] =?UTF-8?q?:sparkles:=20getQueryString=20util=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/utils/getQueryString.ts | 36 ++++++++++++++++++++++++++++++++++++ src/utils/index.ts | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/utils/getQueryString.ts diff --git a/src/utils/getQueryString.ts b/src/utils/getQueryString.ts new file mode 100644 index 00000000..17d0e35f --- /dev/null +++ b/src/utils/getQueryString.ts @@ -0,0 +1,36 @@ +type QueryString = Record; + +export const getQueryString = (params?: QueryString) => { + // 인자가 없을 경우 null반환 + if (!params) return null; + + const queryStringArray: string[] = []; + + Object.entries(params).forEach(([key, initialValue]) => { + const value = + typeof initialValue === 'boolean' || typeof initialValue === 'number' + ? JSON.stringify(initialValue) + : initialValue; + // 객체 여부 확인 + const isObject = initialValue?.constructor === Object; + + if (!value) return; + // 객체일 경우 에러 + if (isObject) throw new Error(`객체는 올 수 없습니다.`); + // 배열값이 들어올 경우 중복 제거 후 변환 + if (Array.isArray(value)) { + const uniqueValue = Array.from(new Set(value)); + queryStringArray.push(`${key}=${uniqueValue.join(`&${key}=`)}`); + return; + } + queryStringArray.push(`${key}=${value}`); + }); + // 쿼리스트링 형태로 변환 + return queryStringArray.join('&'); +}; + +export const withQueryString = (url: string, params?: QueryString) => { + const queryString = getQueryString(params); + if (!queryString) return url; + return `${url}?${queryString}`; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts index 486b124c..7cb4cbc2 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1 @@ -// format 이런 친구들? (ex. formatCurrency) +export * from './getQueryString'; From 77db25a9b74cd88ee1ac8dc5af70fe9c561e2bd2 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 11:38:34 +0900 Subject: [PATCH 08/17] =?UTF-8?q?:lipstick:=20flex=20=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EC=9B=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/layout.tsx | 3 +++ src/app/select/page.tsx | 32 +++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 08192796..cb336afc 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -27,4 +27,7 @@ const containerCss = { maxWidth: '475px', margin: '0 auto', minHeight: '100vh', + + display: 'flex', + flexDirection: 'column', }; diff --git a/src/app/select/page.tsx b/src/app/select/page.tsx index eca0e855..2b9984c9 100644 --- a/src/app/select/page.tsx +++ b/src/app/select/page.tsx @@ -1,21 +1,17 @@ -import RadioInputWithEmoji from '@/app/select/RadioInputWithEmoji'; +import SelectMissionForm from '@/app/select/SelectMissionForm'; import Header from '@/components/Layout/Header'; import { css } from '@styled-system/css'; export default function SelectPage() { return ( -
+
-

+

하루 10분
어떤 일에 투자하고 싶은가요?

-
- - - - +
); @@ -24,24 +20,30 @@ export default function SelectPage() { const grey800 = '#333D4B'; const purple = '#8D96F0'; -const MainWrapperCss = css({ +const mainWrapperCss = css({ + flex: 1, + display: 'flex', + flexDirection: 'column', + width: '100%', - height: '100vh', }); const containerCss = css({ + display: 'flex', + flexDirection: 'column', + flex: 1, + padding: '24px 16px', }); -const MainTitleCss = css({ +const mainTitleCss = css({ marginTop: '2px', - fontSize: '24px', - fontWeight: 700, - lineHeight: '30px', + + textStyle: 'title2', color: grey800, '& strong': { color: purple, - fontWeight: 700, + textStyle: 'title2', }, }); From eb73fb869f5cff0b4f2b1488f00e216036fffd73 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 11:46:03 +0900 Subject: [PATCH 09/17] =?UTF-8?q?:truck:=20RadioInput=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20component=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=98=AE=EA=B8=B4=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{app/select => components}/RadioInput.tsx | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) rename src/{app/select => components}/RadioInput.tsx (62%) diff --git a/src/app/select/RadioInput.tsx b/src/components/RadioInput.tsx similarity index 62% rename from src/app/select/RadioInput.tsx rename to src/components/RadioInput.tsx index 189632de..750bc56d 100644 --- a/src/app/select/RadioInput.tsx +++ b/src/components/RadioInput.tsx @@ -1,4 +1,4 @@ -import { type InputHTMLAttributes, type PropsWithChildren } from 'react'; +import { type ChangeEvent, type InputHTMLAttributes, type PropsWithChildren } from 'react'; import CheckCircleIcon from '@/app/select/CheckCircleIcon'; import { css } from '@styled-system/css'; import { flex } from '@styled-system/patterns'; @@ -7,16 +7,21 @@ const purple = '#8D96F0'; const lightPurple = '#EFF1FF'; const grey100 = '#F2F4F6'; +export interface RadioInputProps extends Omit, 'type' | 'onChange'> { + onChange?: (value: string) => void; +} + /** - * 디자인 시스템이 확정되지 않아서 component 페이지에 넣지 않고 select 폴더에 넣었습니다. + * 디자인 시스템이 확정시 고도화 */ -export default function RadioInput({ - children, - ...props -}: PropsWithChildren, 'type'>>) { +export default function RadioInput({ children, onChange, ...props }: PropsWithChildren) { + const handleChange = (e: ChangeEvent) => { + onChange && onChange(e.target.value); + }; + return (
); } - +// TODO : 컬러 theme으로 적용 const grey800 = '#333D4B'; const purple = '#8D96F0'; diff --git a/src/app/select/select.constants.ts b/src/app/select/select.constants.ts new file mode 100644 index 00000000..8b7c51ea --- /dev/null +++ b/src/app/select/select.constants.ts @@ -0,0 +1,32 @@ +export const MISSION_CATEGORIES = [ + { + label: '운동', + value: 'exercise', + imgSrc: '/images/emoji-exercise.png', + }, + { + label: '공부', + value: 'study', + imgSrc: '/images/emoji-book.png', + }, + { + label: '글 읽기', + value: 'reading', + imgSrc: '/images/emoji-open-book.png', + }, + { + label: '글 쓰기', + value: 'writing', + imgSrc: '/images/emoji-pen.png', + }, + { + label: '영상 보기 / 팟캐스트 듣기', + value: 'video', + imgSrc: '/images/emoji-laptop.png', + }, + { + label: '기타', + value: 'etc', + imgSrc: '/images/emoji-speech-bubble.png', + }, +]; diff --git a/src/constants/router.ts b/src/constants/router.ts new file mode 100644 index 00000000..96e13a6d --- /dev/null +++ b/src/constants/router.ts @@ -0,0 +1,5 @@ +export const ROUTER = { + HOME: '/', + SELECT: '/select', + TIMER: '/timer', +}; From b8b31ee5ebf8f46ac576cca4e8cefd33ad4f722a Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 13:07:13 +0900 Subject: [PATCH 11/17] =?UTF-8?q?:sparkles:=20type=20=EC=B6=94=EB=A1=A0?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20object=20utils=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/utils/index.ts | 1 + src/utils/object.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/utils/object.ts diff --git a/src/utils/index.ts b/src/utils/index.ts index 7cb4cbc2..4d42901d 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1 +1,2 @@ export * from './getQueryString'; +export * from './object'; diff --git a/src/utils/object.ts b/src/utils/object.ts new file mode 100644 index 00000000..eb57de37 --- /dev/null +++ b/src/utils/object.ts @@ -0,0 +1,15 @@ +export type ObjectKeys> = `${Exclude}`; + +export const getObjectValues = >( + obj: Type, +): Array]> => { + if (typeof obj !== 'object') throw new Error('객체가 아닙니다.'); + // 타입 단언을 사용하여 값의 타입을 추론합니다. + return Object.values(obj) as Array]>; +}; + +export const getObjectKeys = >(obj: Type): Array> => { + if (typeof obj !== 'object') throw new Error('객체가 아닙니다.'); + + return Object.keys(obj) as Array>; +}; From 651ff7b8c01d6c30e9f4ee352c91478f28aba10d Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 13:08:06 +0900 Subject: [PATCH 12/17] =?UTF-8?q?:sparkles:=20searchParams=20value=20?= =?UTF-8?q?=EC=9D=98=20type=20=EC=B6=94=EB=A1=A0=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20useSearchParamsTypedValue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useSearchParamsTyped.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/hooks/useSearchParamsTyped.tsx diff --git a/src/hooks/useSearchParamsTyped.tsx b/src/hooks/useSearchParamsTyped.tsx new file mode 100644 index 00000000..38629c01 --- /dev/null +++ b/src/hooks/useSearchParamsTyped.tsx @@ -0,0 +1,11 @@ +import { useSearchParams } from 'next/navigation'; + +const useSearchParamsTypedValue = (key: string) => { + const searchParams = useSearchParams(); + if (!searchParams) return { searchParams: null }; + if (!searchParams.has(key)) return { searchParams: null }; + + return { searchParams: searchParams.get(key) as T }; +}; + +export default useSearchParamsTypedValue; From 2df4a75acea5322b1605b7b8dffa455716bd1db0 Mon Sep 17 00:00:00 2001 From: Dongmin Ahn Date: Thu, 7 Dec 2023 13:08:26 +0900 Subject: [PATCH 13/17] =?UTF-8?q?:sparkles:=20searchParams=20value=20?= =?UTF-8?q?=EB=A5=BC=20=EC=9D=B4=EC=9A=A9=ED=95=B4=EC=84=9C=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EB=B3=B4=EC=97=AC=EC=A4=80?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/select/SelectMissionForm.tsx | 7 ++++--- src/app/select/select.constants.ts | 28 ++++++++++++++-------------- src/app/timer/page.tsx | 9 ++++++++- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/app/select/SelectMissionForm.tsx b/src/app/select/SelectMissionForm.tsx index 72254a80..7dda8b56 100644 --- a/src/app/select/SelectMissionForm.tsx +++ b/src/app/select/SelectMissionForm.tsx @@ -7,6 +7,7 @@ import { MISSION_CATEGORIES } from '@/app/select/select.constants'; import Button from '@/components/Button'; import { ROUTER } from '@/constants/router'; import { withQueryString } from '@/utils'; +import { getObjectValues } from '@/utils/object'; import { css } from '@styled-system/css'; import { flex } from '@styled-system/patterns'; @@ -30,14 +31,14 @@ export default function SelectMissionForm() { return (
- {MISSION_CATEGORIES.map((category) => ( + {getObjectValues(MISSION_CATEGORIES).map((category) => ( ))}
diff --git a/src/app/select/select.constants.ts b/src/app/select/select.constants.ts index 8b7c51ea..e32adf47 100644 --- a/src/app/select/select.constants.ts +++ b/src/app/select/select.constants.ts @@ -1,32 +1,32 @@ -export const MISSION_CATEGORIES = [ - { +export const MISSION_CATEGORIES = { + exercise: { + id: 'exercise', label: '운동', - value: 'exercise', imgSrc: '/images/emoji-exercise.png', }, - { + study: { + id: 'study', label: '공부', - value: 'study', imgSrc: '/images/emoji-book.png', }, - { + reading: { + id: 'reading', label: '글 읽기', - value: 'reading', imgSrc: '/images/emoji-open-book.png', }, - { + writing: { + id: 'writing', label: '글 쓰기', - value: 'writing', imgSrc: '/images/emoji-pen.png', }, - { + video: { + id: 'video', label: '영상 보기 / 팟캐스트 듣기', - value: 'video', imgSrc: '/images/emoji-laptop.png', }, - { + etc: { + id: 'etc', label: '기타', - value: 'etc', imgSrc: '/images/emoji-speech-bubble.png', }, -]; +} as const; diff --git a/src/app/timer/page.tsx b/src/app/timer/page.tsx index cd14a574..61c3968e 100644 --- a/src/app/timer/page.tsx +++ b/src/app/timer/page.tsx @@ -1,14 +1,21 @@ 'use client'; +import { MISSION_CATEGORIES } from '@/app/select/select.constants'; import TimerView from '@/app/timer/TimerView'; import useTimer from '@/app/timer/useTimer'; import useTimerStatus from '@/app/timer/useTimerStatus'; import Header from '@/components/Layout/Header'; +import useSearchParamsTypedValue from '@/hooks/useSearchParamsTyped'; +import { type ObjectKeys } from '@/utils'; import { css } from '@styled-system/css'; export default function TimerPage() { const { step, stepLabel, onNextStep } = useTimerStatus(); const { formattedTime } = useTimer(step); + const { searchParams } = useSearchParamsTypedValue>('category'); + + const category = MISSION_CATEGORIES[searchParams ?? 'exercise'].label; + const onFinish = () => { onNextStep('stop'); alert('정말 끝내시겠습니까?'); @@ -25,7 +32,7 @@ export default function TimerPage() {

{stepLabel.title}

{stepLabel.desc}

- +
{step === 'ready' && (