diff --git a/apps/admin/src/app/layout.tsx b/apps/admin/src/app/layout.tsx index ca5ba39bd..27e5f111b 100644 --- a/apps/admin/src/app/layout.tsx +++ b/apps/admin/src/app/layout.tsx @@ -6,11 +6,11 @@ export const metadata = { description: '부산소프트웨어마이스터고등학교 입학전형 시스템 마루의 어드민 페이지입니다.', }; -interface PropsType { +interface Props { children: ReactNode; } -const RootLayout = ({ children }: PropsType) => { +const RootLayout = ({ children }: Props) => { return ( diff --git a/apps/admin/src/components/Provider.tsx b/apps/admin/src/components/Provider.tsx index 652c93c43..5542aa1d9 100644 --- a/apps/admin/src/components/Provider.tsx +++ b/apps/admin/src/components/Provider.tsx @@ -3,11 +3,11 @@ import { GlobalStyle } from '@maru/theme'; import { ReactNode } from 'react'; -interface PropsType { +interface Props { children: ReactNode; } -const Provider = ({ children }: PropsType) => { +const Provider = ({ children }: Props) => { return ( <> diff --git a/apps/admin/src/components/common/ListHeader/ListHeader.tsx b/apps/admin/src/components/common/ListHeader/ListHeader.tsx index 4cb664d99..321161d53 100644 --- a/apps/admin/src/components/common/ListHeader/ListHeader.tsx +++ b/apps/admin/src/components/common/ListHeader/ListHeader.tsx @@ -3,11 +3,11 @@ import { flex } from '@maru/utils'; import { ReactNode } from 'react'; import { styled } from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; } -const ListHeader = ({ children }: PropsType) => { +const ListHeader = ({ children }: Props) => { return {children}; }; diff --git a/apps/admin/src/components/common/ListItem/ListItem.tsx b/apps/admin/src/components/common/ListItem/ListItem.tsx index 7e1d84970..6dcf32898 100644 --- a/apps/admin/src/components/common/ListItem/ListItem.tsx +++ b/apps/admin/src/components/common/ListItem/ListItem.tsx @@ -3,11 +3,11 @@ import { flex } from '@maru/utils'; import { ReactNode } from 'react'; import { styled } from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; } -const ListItem = ({ children }: PropsType) => { +const ListItem = ({ children }: Props) => { return {children}; }; diff --git a/apps/admin/src/layouts/AppLayout.tsx b/apps/admin/src/layouts/AppLayout.tsx index 7438fe32c..129e9ccde 100644 --- a/apps/admin/src/layouts/AppLayout.tsx +++ b/apps/admin/src/layouts/AppLayout.tsx @@ -3,11 +3,11 @@ import { flex } from '@maru/utils'; import { ReactNode } from 'react'; import { styled } from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; } -const AppLayout = ({ children }: PropsType) => { +const AppLayout = ({ children }: Props) => { return ( @@ -20,7 +20,7 @@ export default AppLayout; const StyledAppLayout = styled.div` ${flex({ flexDirection: 'row' })} - width: 100vw; + width: 100%; height: 100vh; `; diff --git a/apps/user/public/svg/error.svg b/apps/user/public/svg/error.svg new file mode 100644 index 000000000..122e47188 --- /dev/null +++ b/apps/user/public/svg/error.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/user/public/svg/school_logo.svg b/apps/user/public/svg/school_logo.svg new file mode 100644 index 000000000..ced62d00c --- /dev/null +++ b/apps/user/public/svg/school_logo.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/user/src/app/error.tsx b/apps/user/src/app/error.tsx index 28fd07441..9f2f25fda 100644 --- a/apps/user/src/app/error.tsx +++ b/apps/user/src/app/error.tsx @@ -1,7 +1,53 @@ 'use client'; +import { AppLayout } from '@/layouts'; +import { color } from '@maru/theme'; +import { Button, Column, Row, Text } from '@maru/ui'; +import { flex } from '@maru/utils'; +import Image from 'next/image'; +import { useRouter } from 'next/navigation'; +import styled from 'styled-components'; + const Error = () => { - return
; + const router = useRouter(); + + return ( + + + error + + + 페이지가 작동하지 않습니다 + + + 이런! 우리 쪽에서 문제가 발생했습니다. +
지금 밤돌이로 팀이 문제를 해결하기 위해 열심히 노력하고 있습니다. +
+ 일시적인 문제이니 나중에 다시 시도해주세요. +
+
+ + + + +
+
+ ); }; export default Error; + +const StyledError = styled.div` + ${flex({ flexDirection: 'column', alignItems: 'center' })}; + gap: 56px; + margin: 82px auto 0; + width: fit-content; +`; diff --git a/apps/user/src/app/layout.tsx b/apps/user/src/app/layout.tsx index c32193beb..29b147962 100644 --- a/apps/user/src/app/layout.tsx +++ b/apps/user/src/app/layout.tsx @@ -1,17 +1,17 @@ -import { ReactNode } from 'react'; -import QueryClientProvider from '@/services/QueryClientProvider'; import Provider from '@/components/Provider'; +import QueryClientProvider from '@/services/QueryClientProvider'; +import { ReactNode } from 'react'; export const metadata = { title: '마루', description: '부산소프트웨어마이스터고등학교 입학전형 시스템 마루입니다', }; -interface PropsType { +interface Props { children: ReactNode; } -const RootLayout = ({ children }: PropsType) => { +const RootLayout = ({ children }: Props) => { return ( diff --git a/apps/user/src/app/not-found.tsx b/apps/user/src/app/not-found.tsx index 47e490971..31c9ea66f 100644 --- a/apps/user/src/app/not-found.tsx +++ b/apps/user/src/app/not-found.tsx @@ -1,8 +1,8 @@ 'use client'; import { AppLayout } from '@/layouts'; -import { color, font } from '@maru/theme'; -import { Button } from '@maru/ui'; +import { color } from '@maru/theme'; +import { Button, Column, Text } from '@maru/ui'; import { flex } from '@maru/utils'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; @@ -15,12 +15,16 @@ const NotFound = () => { not-found - 페이지를 찾을 수 없습니다 - - 요청하신 페이지가 사라졌거나, 잘못된 경로를 이용하셨어요. -
- 걱정 마세요, 최고의 탐험가도 때로는 길을 잃을 때가 있죠. -
+ + + 페이지를 찾을 수 없습니다 + + + 요청하신 페이지가 사라졌거나, 잘못된 경로를 이용하셨어요. +
+ 걱정 마세요, 최고의 탐험가도 때로는 길을 잃을 때가 있죠. +
+
@@ -32,19 +36,8 @@ const NotFound = () => { export default NotFound; const StyledNotFound = styled.div` - ${flex({ flexDirection: 'column', alignItems: 'center' })} + ${flex({ flexDirection: 'column', alignItems: 'center' })}; + gap: 56px; margin: 82px auto 0; width: fit-content; `; - -const Title = styled.p` - ${font.H1} - color: ${color.gray900}; - margin: 56px 0 24px; -`; - -const Desc = styled.p` - ${font.p2} - color: ${color.gray600}; - margin-bottom: 56px; -`; diff --git a/apps/user/src/app/notice/[id]/page.tsx b/apps/user/src/app/notice/[id]/page.tsx index c0beff000..dafae8e5c 100644 --- a/apps/user/src/app/notice/[id]/page.tsx +++ b/apps/user/src/app/notice/[id]/page.tsx @@ -12,11 +12,11 @@ import { useRouter } from 'next/navigation'; import { Suspense } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { params: { id: number }; } -const NoticeDetailPage = ({ params: { id } }: PropsType) => { +const NoticeDetailPage = ({ params: { id } }: Props) => { const router = useRouter(); return ( diff --git a/apps/user/src/app/signup/page.tsx b/apps/user/src/app/signup/page.tsx index b728248e9..06f52fb43 100644 --- a/apps/user/src/app/signup/page.tsx +++ b/apps/user/src/app/signup/page.tsx @@ -29,7 +29,7 @@ const SignUpPage = () => { alt="colabo-logo" /> - + 회원가입 @@ -40,8 +40,6 @@ const SignUpPage = () => { name="name" placeholder="이름을 입력해주세요." onChange={handleJoinUserDataChange} - isError={joinUserData.name.length === 0} - errorMessage="필수값입니다." /> ` +const SignUpBox = styled.div` ${flex({ flexDirection: 'column' })}; gap: 36px; width: 446px; diff --git a/apps/user/src/app/signup/signup.hooks.ts b/apps/user/src/app/signup/signup.hooks.ts index 797fb7dfc..588cf77be 100644 --- a/apps/user/src/app/signup/signup.hooks.ts +++ b/apps/user/src/app/signup/signup.hooks.ts @@ -1,7 +1,7 @@ -import { PostJoinAuthReq } from '@/types/auth/remote'; import { useJoinUserMutation, useRequestEmailMutation } from '@/services/auth/mutations'; +import { PostJoinAuthReq } from '@/types/auth/remote'; +import { useBooleanState } from '@maru/hooks'; import { ChangeEventHandler, useState } from 'react'; -import { useBoolean } from '@maru/hooks'; export const useJoinAction = (joinUserData: PostJoinAuthReq, termsAgree: boolean) => { const { joinUserMutate } = useJoinUserMutation(joinUserData); @@ -28,9 +28,9 @@ export const useJoinAction = (joinUserData: PostJoinAuthReq, termsAgree: boolean export const useRequestEmailAction = (email: string) => { // 이메일 요청을 보냈는가? - const { value: isRequestEmail, setValue: setIsRequestEmail } = useBoolean(false); + const { value: isRequestEmail, setValue: setIsRequestEmail } = useBooleanState(false); // 이메일 전송 활성화 비활성화 - const { value: isButtonDisabled, setValue: setIsButtonDisabled } = useBoolean(false); + const { value: isButtonDisabled, setValue: setIsButtonDisabled } = useBooleanState(false); const { requestEmailMutate } = useRequestEmailMutation(email); const handleRequestEmailButtonClick = () => { diff --git a/apps/user/src/components/Provider.tsx b/apps/user/src/components/Provider.tsx index 2d6ab948b..8c70ce6db 100644 --- a/apps/user/src/components/Provider.tsx +++ b/apps/user/src/components/Provider.tsx @@ -1,16 +1,16 @@ 'use client'; -import { RecoilRoot } from 'recoil'; import { GlobalStyle } from '@maru/theme'; -import { ReactNode } from 'react'; import { OverlayProvider } from '@toss/use-overlay'; +import { ReactNode } from 'react'; +import { RecoilRoot } from 'recoil'; import { AuthWrapper } from './common'; -interface PropsType { +interface Props { children: ReactNode; } -const Provider = ({ children }: PropsType) => { +const Provider = ({ children }: Props) => { return ( diff --git a/apps/user/src/components/common/Footer/Footer.tsx b/apps/user/src/components/common/Footer/Footer.tsx index 92d73a89c..a1c75b9e2 100644 --- a/apps/user/src/components/common/Footer/Footer.tsx +++ b/apps/user/src/components/common/Footer/Footer.tsx @@ -15,9 +15,15 @@ const Footer = () => { logo_gray -

주소: 부산광역시 강서구 가락대로 1393 봉림동 15 (46708)

-

교무실(입학처): 051-971-2153, Fax: 051-971-2061

-

행정실:051-971-2152, Fax: 051-971-6325

+ + 주소: 부산광역시 강서구 가락대로 1393 봉림동 15 (46708) + + + 교무실(입학처): 051-971-2153, Fax: 051-971-2061 + + + 행정실:051-971-2152, Fax: 051-971-6325 +
Copyright © 밤돌이로 all rights reserved. @@ -69,8 +75,6 @@ const StyledFooter = styled.div` `; const InfoBox = styled.div` - ${font.p3} - color: ${color.gray600}; ${flex({ flexDirection: 'column' })} gap: 40px; width: 489px; @@ -84,9 +88,9 @@ const ContentBox = styled.div` `; const NavigationBox = styled.div` + // @TODO Link 리팩토링하면서 ${font.p3} color: ${color.gray600}; display: flex; - // @TODO 확인 gap: 132px; `; diff --git a/apps/user/src/components/common/Header/Header.tsx b/apps/user/src/components/common/Header/Header.tsx index 98f9d8731..d6814d204 100644 --- a/apps/user/src/components/common/Header/Header.tsx +++ b/apps/user/src/components/common/Header/Header.tsx @@ -35,10 +35,10 @@ const Header = () => { router.push(ROUTES.MAIN)} alt="logo" /> @@ -81,9 +81,10 @@ export default Header; const StyledHeader = styled.div` ${flex({ flexDirection: 'column', alignItems: 'center', justifyContent: 'center' })} - width: 100%; + max-width: 1448px; height: 126px; background-color: ${color.white}; + margin: 0 auto; padding: 0px 100px; border-bottom: 1px solid ${color.gray200}; `; diff --git a/apps/user/src/components/common/Header/Profile/Profile.tsx b/apps/user/src/components/common/Header/Profile/Profile.tsx index 496facd3e..b86c7a2da 100644 --- a/apps/user/src/components/common/Header/Profile/Profile.tsx +++ b/apps/user/src/components/common/Header/Profile/Profile.tsx @@ -1,18 +1,18 @@ import { ROUTES } from '@/constants/common/constant'; +import { useUser } from '@/hooks'; import { useLogoutUserMutation } from '@/services/auth/mutations'; -import { useBoolean, useOutsideClick } from '@maru/hooks'; +import { useBooleanState, useOutsideClick } from '@maru/hooks'; import { IconArrowDropdown } from '@maru/icon'; import { color, font } from '@maru/theme'; import { Text } from '@maru/ui'; import { flex } from '@maru/utils'; import { useRouter } from 'next/navigation'; -import { useUser } from '@/hooks'; import styled from 'styled-components'; const Profile = () => { const router = useRouter(); const { userData } = useUser(); - const { value: isMenuOpen, toggle: toggleMenuOpen, setFalse: closeMenu } = useBoolean(); + const { value: isMenuOpen, toggle: toggleMenuOpen, setFalse: closeMenu } = useBooleanState(); const { logoutUserMutate } = useLogoutUserMutation(); const menuListBoxRef = useOutsideClick(closeMenu); diff --git a/apps/user/src/components/common/Wrappers/AuthWrapper/AuthWrapper.tsx b/apps/user/src/components/common/Wrappers/AuthWrapper/AuthWrapper.tsx index 596be6c5a..6ea42dc0e 100644 --- a/apps/user/src/components/common/Wrappers/AuthWrapper/AuthWrapper.tsx +++ b/apps/user/src/components/common/Wrappers/AuthWrapper/AuthWrapper.tsx @@ -8,14 +8,14 @@ import { useOverlay } from '@toss/use-overlay'; import { usePathname, useRouter } from 'next/navigation'; import { ReactNode, useEffect } from 'react'; -const NOT_LOGGEDIN_PRIVATE_PAGE: string[] = [ROUTES.FORM]; +const NOT_LOGGEDIN_PRIVATE_PAGE: string[] = [ROUTES.FORM, ROUTES.FIRST_RESULT, ROUTES.FINAL_RESULT]; const LOGGEDIN_PRIVATE_PAGE: string[] = [ROUTES.LOGIN, ROUTES.SIGNUP]; -interface PropsType { +interface Props { children: ReactNode; } -const AuthWrapper = ({ children }: PropsType) => { +const AuthWrapper = ({ children }: Props) => { const router = useRouter(); const pathName = usePathname(); const overlay = useOverlay(); @@ -44,7 +44,10 @@ const AuthWrapper = ({ children }: PropsType) => { router.push(ROUTES.MAIN); close(); }} - onConfirm={() => router.push(ROUTES.LOGIN)} + onConfirm={() => { + router.push(ROUTES.LOGIN); + close(); + }} confirmButtonText="로그인 하러 가기" /> )); diff --git a/apps/user/src/components/common/Wrappers/FormWrapper/FormWrapper.tsx b/apps/user/src/components/common/Wrappers/FormWrapper/FormWrapper.tsx index 374989d70..708105417 100644 --- a/apps/user/src/components/common/Wrappers/FormWrapper/FormWrapper.tsx +++ b/apps/user/src/components/common/Wrappers/FormWrapper/FormWrapper.tsx @@ -1,26 +1,34 @@ 'use client'; import { FORM } from '@/constants/form/initial'; +import { useSaveFormMutation } from '@/services/form/mutations'; import { useSaveFormQuery } from '@/services/form/queries'; import { + useFormStore, useIsSaveFormLoadedStore, - useSetFormStore, useSetNewSubjectStore, useSetSubjectStore, } from '@/store'; +import { useInterval } from '@toss/react'; import { ReactNode, useEffect } from 'react'; -interface PropsType { +interface Props { children: ReactNode; } -const FormWrapper = ({ children }: PropsType) => { +const FormWrapper = ({ children }: Props) => { const { data: saveFormData } = useSaveFormQuery(); + const { saveFormMutate } = useSaveFormMutation(); const [isSaveFormLoaded, setIsSaveFormLoaded] = useIsSaveFormLoadedStore(); - const setForm = useSetFormStore(); + const [form, setForm] = useFormStore(); const setSubjectList = useSetSubjectStore(); const setNewtSubjectList = useSetNewSubjectStore(); + // 2분마다 한번씩 저장 + useInterval(() => { + saveFormMutate(form); + }, 6000 * 10 * 2); + useEffect(() => { if (saveFormData && !isSaveFormLoaded) { setIsSaveFormLoaded(true); diff --git a/apps/user/src/components/faq/CategoryFilter/Category/Category.tsx b/apps/user/src/components/faq/CategoryFilter/Category/Category.tsx index 4b6642238..58ef7b6ce 100644 --- a/apps/user/src/components/faq/CategoryFilter/Category/Category.tsx +++ b/apps/user/src/components/faq/CategoryFilter/Category/Category.tsx @@ -3,13 +3,13 @@ import { flex } from '@maru/utils'; import { ReactNode } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; isSelected: boolean; onClick: () => void; } -const Category = ({ children, isSelected, onClick }: PropsType) => { +const Category = ({ children, isSelected, onClick }: Props) => { return ( {children} @@ -25,7 +25,7 @@ const StyledCategory = styled.button<{ $isSelected: boolean }>` height: 100%; padding: 0px 14px; border-radius: 25px; - color: ${({ $isSelected: isSelected }) => (isSelected ? color.maruDefault : color.gray900)}; - background-color: ${({ $isSelected: isSelected }) => (isSelected ? '#eff5ff' : color.gray100)}; + color: ${(props) => (props.$isSelected ? color.maruDefault : color.gray900)}; + background-color: ${(props) => (props.$isSelected ? '#eff5ff' : color.gray100)}; cursor: pointer; `; diff --git a/apps/user/src/components/faq/CategoryFilter/CategoryFilter.tsx b/apps/user/src/components/faq/CategoryFilter/CategoryFilter.tsx index ff83f7352..edaa6be68 100644 --- a/apps/user/src/components/faq/CategoryFilter/CategoryFilter.tsx +++ b/apps/user/src/components/faq/CategoryFilter/CategoryFilter.tsx @@ -1,8 +1,8 @@ +import { color, font } from '@maru/theme'; +import { flex } from '@maru/utils'; import { Dispatch, SetStateAction, useState } from 'react'; import styled from 'styled-components'; import Category from './Category/Category'; -import { color, font } from '@maru/theme'; -import { flex } from '@maru/utils'; const FAQ_CATEGORY_LIST = [ { id: 0, category: '질문 TOP', value: 'TOP_QUESTION' }, @@ -11,11 +11,11 @@ const FAQ_CATEGORY_LIST = [ { id: 3, category: '관련 제출 서류', value: 'SUBMIT_DOCUMENT' }, ] as const; -interface PropsType { +interface Props { setCategory: Dispatch>; } -const CategoryFilter = ({ setCategory }: PropsType) => { +const CategoryFilter = ({ setCategory }: Props) => { const [selectedCategory, setSelectedCategory] = useState(0); return ( diff --git a/apps/user/src/components/faq/FaqList/FaqItem/FaqItem.tsx b/apps/user/src/components/faq/FaqList/FaqItem/FaqItem.tsx index 8670dd8e7..25301deed 100644 --- a/apps/user/src/components/faq/FaqList/FaqItem/FaqItem.tsx +++ b/apps/user/src/components/faq/FaqList/FaqItem/FaqItem.tsx @@ -5,12 +5,12 @@ import { flex } from '@maru/utils'; import { useState } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { title: string; content: string; } -const FaqItem = ({ content, title }: PropsType) => { +const FaqItem = ({ content, title }: Props) => { const [isOpen, setIsOpen] = useState(false); return ( diff --git a/apps/user/src/components/faq/FaqList/FaqList.tsx b/apps/user/src/components/faq/FaqList/FaqList.tsx index 7894bb01a..faa6b1f4d 100644 --- a/apps/user/src/components/faq/FaqList/FaqList.tsx +++ b/apps/user/src/components/faq/FaqList/FaqList.tsx @@ -3,11 +3,11 @@ import { flex } from '@maru/utils'; import styled from 'styled-components'; import FaqItem from './FaqItem/FaqItem'; -interface PropsType { +interface Props { category: string; } -const FaqList = ({ category }: PropsType) => { +const FaqList = ({ category }: Props) => { const { data: faqListData } = useFaqListQuery(category); return faqListData ? ( diff --git a/apps/user/src/components/form/Calculators/GradeCalculator/GradeCalculatorItem/GradeCalculatorItem.tsx b/apps/user/src/components/form/Calculators/GradeCalculator/GradeCalculatorItem/GradeCalculatorItem.tsx index be01c073f..057b49ee1 100644 --- a/apps/user/src/components/form/Calculators/GradeCalculator/GradeCalculatorItem/GradeCalculatorItem.tsx +++ b/apps/user/src/components/form/Calculators/GradeCalculator/GradeCalculatorItem/GradeCalculatorItem.tsx @@ -1,17 +1,17 @@ -import { Td, Dropdown } from '@maru/ui'; +import { Subject } from '@/types/form/client'; +import { Dropdown, Td } from '@maru/ui'; import { flex } from '@maru/utils'; import { Dispatch, SetStateAction } from 'react'; import styled from 'styled-components'; -import { Subject } from '@/types/form/client'; -interface PropsType { +interface Props { id: number; subjectList: Subject[]; setSubjectList: Dispatch>; achievementLevels: string[]; } -const GradeCalculatorItem = ({ id, subjectList, setSubjectList, achievementLevels }: PropsType) => { +const GradeCalculatorItem = ({ id, subjectList, setSubjectList, achievementLevels }: Props) => { const handleCaculatorItemDataChange = (data: string, name: string) => { setSubjectList((prev) => { const updatedData = [...prev]; diff --git a/apps/user/src/components/form/Calculators/GradeCalculator/NewGradeCalculatorItem/NewGradeCalculatorItem.tsx b/apps/user/src/components/form/Calculators/GradeCalculator/NewGradeCalculatorItem/NewGradeCalculatorItem.tsx index a7a9655c6..5ba7b3237 100644 --- a/apps/user/src/components/form/Calculators/GradeCalculator/NewGradeCalculatorItem/NewGradeCalculatorItem.tsx +++ b/apps/user/src/components/form/Calculators/GradeCalculator/NewGradeCalculatorItem/NewGradeCalculatorItem.tsx @@ -1,11 +1,11 @@ +import { Subject } from '@/types/form/client'; import { color, font } from '@maru/theme'; -import { Button, Td, Dropdown } from '@maru/ui'; +import { Button, Dropdown, Td } from '@maru/ui'; import { flex } from '@maru/utils'; import { ChangeEvent, Dispatch, SetStateAction } from 'react'; -import { Subject } from '@/types/form/client'; import styled from 'styled-components'; -interface PropsType { +interface Props { id: number; achievementLevels: string[]; newSubjectList: Subject[]; @@ -17,7 +17,7 @@ const NewGradeCalculatorItem = ({ achievementLevels, newSubjectList, setNewSubjectList, -}: PropsType) => { +}: Props) => { const newSubjectIndex = newSubjectList.findIndex((item) => item.id === id); const handleDeleteNewSubjectItemButtonClick = (id: number) => { diff --git a/apps/user/src/components/form/CheckFormComplete/CheckFormComplete.tsx b/apps/user/src/components/form/CheckFormComplete/CheckFormComplete.tsx index f20662e63..8e370a9b0 100644 --- a/apps/user/src/components/form/CheckFormComplete/CheckFormComplete.tsx +++ b/apps/user/src/components/form/CheckFormComplete/CheckFormComplete.tsx @@ -4,19 +4,14 @@ import { Row, Text } from '@maru/ui'; import { flex } from '@maru/utils'; import styled from 'styled-components'; -interface PropsType { +interface Props { formStep: string; maxCompleteOfNumber: number; completeOfNumber: number; onClick: () => void; } -const CheckFormComplete = ({ - formStep, - maxCompleteOfNumber, - completeOfNumber, - onClick, -}: PropsType) => { +const CheckFormComplete = ({ formStep, maxCompleteOfNumber, completeOfNumber, onClick }: Props) => { const isFilledFormStep = maxCompleteOfNumber !== completeOfNumber; return ( diff --git a/apps/user/src/components/form/CompleteAlaram/CompleteAlaram.tsx b/apps/user/src/components/form/CompleteAlaram/CompleteAlaram.tsx index 486589c88..4ce9140e1 100644 --- a/apps/user/src/components/form/CompleteAlaram/CompleteAlaram.tsx +++ b/apps/user/src/components/form/CompleteAlaram/CompleteAlaram.tsx @@ -2,13 +2,13 @@ import { IconCancelCircle, IconCheckCircle } from '@maru/icon'; import { color } from '@maru/theme'; import { Column, Text } from '@maru/ui'; -interface PropsType { +interface Props { isComplete: boolean; completeText: string; inCompleteText?: string; } -const CompleteAlaram = ({ isComplete, completeText, inCompleteText }: PropsType) => { +const CompleteAlaram = ({ isComplete, completeText, inCompleteText }: Props) => { return ( void; onConfirm: () => void; } -const DraftFormConfirm = ({ isOpen, onClose, onConfirm }: PropsType) => { +const DraftFormConfirm = ({ isOpen, onClose, onConfirm }: Props) => { return ( void; onConfirm: () => void; } -const FinalFormConfirm = ({ isOpen, onClose, onConfirm }: PropsType) => { +const FinalFormConfirm = ({ isOpen, onClose, onConfirm }: Props) => { return ( { @@ -77,7 +78,7 @@ const Tr = styled.tr` ${flex({ alignItems: 'center' })} `; -const Th = styled.th<{ width: string }>` +const Th = styled.th<{ width: CSSProperties['width'] }>` ${font.context} color: ${color.gray900}; ${flex({ justifyContent: 'center', alignItems: 'center' })} @@ -87,7 +88,7 @@ const Th = styled.th<{ width: string }>` border: 1px solid ${color.gray300}; `; -const Td = styled.td<{ width: string }>` +const Td = styled.td<{ width: CSSProperties['width'] }>` ${font.p2} color: ${color.gray900}; ${flex({ justifyContent: 'center', alignItems: 'center' })} diff --git a/apps/user/src/components/form/FindAddressModal/FindAddressModal.tsx b/apps/user/src/components/form/FindAddressModal/FindAddressModal.tsx index c5cb2ac97..2128d0339 100644 --- a/apps/user/src/components/form/FindAddressModal/FindAddressModal.tsx +++ b/apps/user/src/components/form/FindAddressModal/FindAddressModal.tsx @@ -1,14 +1,14 @@ +import { useSetFormStore } from '@/store'; import { useOutsideClick } from '@maru/hooks'; import DaumPostcode, { Address } from 'react-daum-postcode'; -import { useSetFormStore } from '@/store'; import styled from 'styled-components'; -interface PropsType { +interface Props { isOpen: boolean; onClose: () => void; } -const FindAddressModal = ({ isOpen, onClose }: PropsType) => { +const FindAddressModal = ({ isOpen, onClose }: Props) => { const setForm = useSetFormStore(); const findAddressModalRef = useOutsideClick(onClose); @@ -38,7 +38,7 @@ const BlurBackground = styled.div<{ $isOpen: boolean }>` display: ${(props) => (props.$isOpen ? 'flex' : 'none')}; align-items: center; justify-content: center; - width: 100vw; + width: 100%; height: 100vh; background: rgba(0, 0, 0, 0.4); z-index: 1; diff --git a/apps/user/src/components/form/FindSchoolModal/FindSchoolModal.tsx b/apps/user/src/components/form/FindSchoolModal/FindSchoolModal.tsx index cac7977c9..6916046d3 100644 --- a/apps/user/src/components/form/FindSchoolModal/FindSchoolModal.tsx +++ b/apps/user/src/components/form/FindSchoolModal/FindSchoolModal.tsx @@ -5,12 +5,12 @@ import { Column, Modal, SearchInput } from '@maru/ui'; import { Suspense, useState } from 'react'; import SchoolList from './SchoolList/SchoolList'; -interface PropsType { +interface Props { isOpen: boolean; onClose: () => void; } -const FindSchoolModal = ({ isOpen, onClose }: PropsType) => { +const FindSchoolModal = ({ isOpen, onClose }: Props) => { const setForm = useSetFormStore(); const [selectedSchool, setSelectedSchool] = useState({ name: '', location: '', code: '' }); const { diff --git a/apps/user/src/components/form/FindSchoolModal/SchoolList/SchoolList.tsx b/apps/user/src/components/form/FindSchoolModal/SchoolList/SchoolList.tsx index 947510ed0..7329afd8b 100644 --- a/apps/user/src/components/form/FindSchoolModal/SchoolList/SchoolList.tsx +++ b/apps/user/src/components/form/FindSchoolModal/SchoolList/SchoolList.tsx @@ -7,17 +7,13 @@ import { flex } from '@maru/utils'; import { Dispatch, SetStateAction } from 'react'; import styled, { css } from 'styled-components'; -interface PropsType { +interface Props { selectedSchool: School; setSelectedSchool: Dispatch>; debouncedSchoolSearchQuery: string; } -const SchoolList = ({ - selectedSchool, - setSelectedSchool, - debouncedSchoolSearchQuery, -}: PropsType) => { +const SchoolList = ({ selectedSchool, setSelectedSchool, debouncedSchoolSearchQuery }: Props) => { const { data: schoolListData } = useSchoolListQuery(debouncedSchoolSearchQuery); return schoolListData ? ( @@ -60,8 +56,8 @@ const SchoolItem = styled.div<{ selected: boolean }>` background: ${color.gray50}; cursor: pointer; - ${({ selected }) => - selected && + ${(props) => + props.selected && css` padding: 15px 15px; border: 1px solid ${color.maruDefault}; diff --git a/apps/user/src/components/form/FormController/FormController.tsx b/apps/user/src/components/form/FormController/FormController.tsx index ed707ed7a..5b2682679 100644 --- a/apps/user/src/components/form/FormController/FormController.tsx +++ b/apps/user/src/components/form/FormController/FormController.tsx @@ -3,13 +3,13 @@ import { Button } from '@maru/ui'; import { flex } from '@maru/utils'; import styled from 'styled-components'; -interface PropsType { +interface Props { onPrevious?: () => void; onNext: () => void; step: FormStep; } -const FormController = ({ onPrevious, onNext, step }: PropsType) => { +const FormController = ({ onPrevious, onNext, step }: Props) => { return ( {step === '지원자정보' ? ( diff --git a/apps/user/src/components/main/Faq/MainFaqList/MainFaqItem/MainFaqItem.tsx b/apps/user/src/components/main/Faq/MainFaqList/MainFaqItem/MainFaqItem.tsx index 103bcab7e..df82f6891 100644 --- a/apps/user/src/components/main/Faq/MainFaqList/MainFaqItem/MainFaqItem.tsx +++ b/apps/user/src/components/main/Faq/MainFaqList/MainFaqItem/MainFaqItem.tsx @@ -5,11 +5,11 @@ import { flex } from '@maru/utils'; import { useRouter } from 'next/navigation'; import { styled } from 'styled-components'; -interface PropsType { +interface Props { title: string; } -const MainFaqItem = ({ title }: PropsType) => { +const MainFaqItem = ({ title }: Props) => { const router = useRouter(); return ( diff --git a/apps/user/src/components/main/Notice/MainNoticeList/MainNoticeItem/MainNoticeItem.tsx b/apps/user/src/components/main/Notice/MainNoticeList/MainNoticeItem/MainNoticeItem.tsx index bdcc2b502..8d71c5f6e 100644 --- a/apps/user/src/components/main/Notice/MainNoticeList/MainNoticeItem/MainNoticeItem.tsx +++ b/apps/user/src/components/main/Notice/MainNoticeList/MainNoticeItem/MainNoticeItem.tsx @@ -1,15 +1,15 @@ -import { useRouter } from 'next/navigation'; -import { styled } from 'styled-components'; import { ROUTES } from '@/constants/common/constant'; -import { font, color } from '@maru/theme'; +import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; +import { useRouter } from 'next/navigation'; +import { styled } from 'styled-components'; -interface PropsType { +interface Props { id: number; title: string; } -const MainNoticeItem = ({ id, title }: PropsType) => { +const MainNoticeItem = ({ id, title }: Props) => { const router = useRouter(); return ( diff --git a/apps/user/src/components/main/Schedule/Schedule.tsx b/apps/user/src/components/main/Schedule/Schedule.tsx index 1e97b61df..788cfb968 100644 --- a/apps/user/src/components/main/Schedule/Schedule.tsx +++ b/apps/user/src/components/main/Schedule/Schedule.tsx @@ -31,7 +31,7 @@ const Schedule = () => { return ( - 입학일정 + 2024학년도 부산소마고 입학 일정 {SCHEDULE_DATA.map((item) => ( diff --git a/apps/user/src/components/main/Schedule/ScheduleItem/ScheduleItem.tsx b/apps/user/src/components/main/Schedule/ScheduleItem/ScheduleItem.tsx index debbc9f19..119c08d1a 100644 --- a/apps/user/src/components/main/Schedule/ScheduleItem/ScheduleItem.tsx +++ b/apps/user/src/components/main/Schedule/ScheduleItem/ScheduleItem.tsx @@ -3,12 +3,12 @@ import { Row, Text } from '@maru/ui'; import { flex } from '@maru/utils'; import styled from 'styled-components'; -interface PropsType { +interface Props { date: string; plan: string; } -const ScheduleItem = ({ date, plan }: PropsType) => { +const ScheduleItem = ({ date, plan }: Props) => { return ( {date} diff --git a/apps/user/src/components/notice/NoticeDetailContent/NoticeDetailContent.tsx b/apps/user/src/components/notice/NoticeDetailContent/NoticeDetailContent.tsx index 21e189546..e0bc33686 100644 --- a/apps/user/src/components/notice/NoticeDetailContent/NoticeDetailContent.tsx +++ b/apps/user/src/components/notice/NoticeDetailContent/NoticeDetailContent.tsx @@ -4,11 +4,11 @@ import { Column, Text } from '@maru/ui'; import { flex, formatCreatedAt } from '@maru/utils'; import styled from 'styled-components'; -interface PropsType { +interface Props { id: number; } -const NoticeDetailContent = ({ id }: PropsType) => { +const NoticeDetailContent = ({ id }: Props) => { const { data: noticeDetailData } = useNoticeDetailQuery(id); return noticeDetailData ? ( diff --git a/apps/user/src/components/notice/NoticeList/NoticeItem/NoticeItem.tsx b/apps/user/src/components/notice/NoticeList/NoticeItem/NoticeItem.tsx index c993b08ed..8918fd165 100644 --- a/apps/user/src/components/notice/NoticeList/NoticeItem/NoticeItem.tsx +++ b/apps/user/src/components/notice/NoticeList/NoticeItem/NoticeItem.tsx @@ -6,13 +6,13 @@ import { flex, formatCreatedAt } from '@maru/utils'; import { useRouter } from 'next/navigation'; import styled from 'styled-components'; -interface PropsType { +interface Props { id: number; title: string; createdAt: string; } -const NoticeItem = ({ id, title, createdAt }: PropsType) => { +const NoticeItem = ({ id, title, createdAt }: Props) => { const router = useRouter(); return ( diff --git a/apps/user/src/components/result/ResultMain/ResultMain.tsx b/apps/user/src/components/result/ResultMain/ResultMain.tsx index be8dc308e..d02292a57 100644 --- a/apps/user/src/components/result/ResultMain/ResultMain.tsx +++ b/apps/user/src/components/result/ResultMain/ResultMain.tsx @@ -1,16 +1,16 @@ +import { ResultOption, ResultStep } from '@/types/result/client'; import { color } from '@maru/theme'; import { Button, Column, Text } from '@maru/ui'; import { flex } from '@maru/utils'; -import { ResultOption, ResultStep } from '@/types/result/client'; import { Dispatch, SetStateAction } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { setResultStep: Dispatch>; option: ResultOption; } -const ResultMain = ({ setResultStep, option }: PropsType) => { +const ResultMain = ({ setResultStep, option }: Props) => { const handleGoResultPageButtonClick = () => { setResultStep('RESULT'); }; diff --git a/apps/user/src/components/result/ResultTableFooter/ResultTableFooter.tsx b/apps/user/src/components/result/ResultTableFooter/ResultTableFooter.tsx index 206f26762..d00c4aed4 100644 --- a/apps/user/src/components/result/ResultTableFooter/ResultTableFooter.tsx +++ b/apps/user/src/components/result/ResultTableFooter/ResultTableFooter.tsx @@ -4,12 +4,12 @@ import { color } from '@maru/theme'; import { Button, Column, Row, Text } from '@maru/ui'; import { useRouter } from 'next/navigation'; -interface PropsType { +interface Props { option: ResultOption; is합격: boolean; } -const ResultTableFooter = ({ option, is합격 }: PropsType) => { +const ResultTableFooter = ({ option, is합격 }: Props) => { const router = useRouter(); const handleGoMainPageButtonClick = () => { diff --git a/apps/user/src/components/result/ResultTableItem/ResultTableItem.tsx b/apps/user/src/components/result/ResultTableItem/ResultTableItem.tsx index 4329a22e5..92cfebdf9 100644 --- a/apps/user/src/components/result/ResultTableItem/ResultTableItem.tsx +++ b/apps/user/src/components/result/ResultTableItem/ResultTableItem.tsx @@ -1,16 +1,16 @@ -import { Row, Text } from '@maru/ui'; import { color } from '@maru/theme'; +import { Row, Text } from '@maru/ui'; import { flex } from '@maru/utils'; import styled from 'styled-components'; -interface PropsType { +interface Props { id: number; name: string; type: string; is합격: boolean; } -const ResultTableItem = ({ id, name, type, is합격 }: PropsType) => { +const ResultTableItem = ({ id, name, type, is합격 }: Props) => { return ( diff --git a/apps/user/src/components/signup/Terms/Terms.tsx b/apps/user/src/components/signup/Terms/Terms.tsx index 41e447fd2..91a6028dc 100644 --- a/apps/user/src/components/signup/Terms/Terms.tsx +++ b/apps/user/src/components/signup/Terms/Terms.tsx @@ -1,14 +1,14 @@ import { IconArrowRight } from '@maru/icon'; -import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; +import { Dispatch, SetStateAction, useEffect, useState } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { setTermsAgree: Dispatch>; } -const Terms = ({ setTermsAgree }: PropsType) => { +const Terms = ({ setTermsAgree }: Props) => { const [allCheck, setAllCheck] = useState(false); const [checkOne, setChecktOne] = useState(false); const [checkTwo, setChecktTwo] = useState(false); diff --git a/apps/user/src/constants/common/constant.ts b/apps/user/src/constants/common/constant.ts index 1b31d7168..3d50a9060 100644 --- a/apps/user/src/constants/common/constant.ts +++ b/apps/user/src/constants/common/constant.ts @@ -19,6 +19,8 @@ export const ROUTES = { LOGIN: '/login', NOTICE: '/notice', SIGNUP: '/signup', + FIRST_RESULT: '/result/first', + FINAL_RESULT: '/result/first', } as const; export const TOKEN = { diff --git a/apps/user/src/hooks/useApiError.ts b/apps/user/src/hooks/useApiError.ts index 6c2531da9..b5331a5b5 100644 --- a/apps/user/src/hooks/useApiError.ts +++ b/apps/user/src/hooks/useApiError.ts @@ -1,8 +1,8 @@ import { AxiosError, isAxiosError } from 'axios'; -type ErrorStatus = 400 | 401 | 402 | 403 | 404 | 407 | 408 | 409 | 429 | 500; +type ErrorStatus = 403 | 429 | 500; -const errorMessages: { [key in ErrorStatus]?: string } = { +const ERROR: Record = { 403: '유저의 권한이 없습니다.', 429: '너무 많이 요청하였습니다. 조금 뒤 다시 이용해주세요.', 500: '서버에 알 수 없는 오류가 발생하였습니다.', @@ -14,7 +14,10 @@ const useApiError = () => { if (isAxiosError(error)) { const status = error.status as ErrorStatus; const message = error.message; - errorMessage = message ?? errorMessages[status]; + errorMessage = message ?? ERROR[status]; + if (status === 500) { + throw new Error('500'); + } } else { errorMessage = '알 수 없는 오류가 발생하였습니다.'; } diff --git a/apps/user/src/layouts/AppLayout.tsx b/apps/user/src/layouts/AppLayout.tsx index d93b830b6..29f846c6f 100644 --- a/apps/user/src/layouts/AppLayout.tsx +++ b/apps/user/src/layouts/AppLayout.tsx @@ -4,7 +4,7 @@ import { color } from '@maru/theme'; import { CSSProperties, ReactNode } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { header?: boolean; footer?: boolean; children: ReactNode; @@ -18,7 +18,7 @@ const AppLayout = ({ style, header = false, footer = false, -}: PropsType) => { +}: Props) => { return ( <> {header &&
} @@ -31,6 +31,6 @@ const AppLayout = ({ export default AppLayout; const StyledAppLayout = styled.section` - width: 100vw; + width: 100%; min-height: 100vh; `; diff --git a/apps/user/src/layouts/FormLayout.tsx b/apps/user/src/layouts/FormLayout.tsx index 49d789d8c..64cd11517 100644 --- a/apps/user/src/layouts/FormLayout.tsx +++ b/apps/user/src/layouts/FormLayout.tsx @@ -5,12 +5,12 @@ import { Text } from '@maru/ui'; import { ReactNode } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; title: String; } -const FormLayout = ({ children, title }: PropsType) => { +const FormLayout = ({ children, title }: Props) => { return ( <>
@@ -30,7 +30,7 @@ const FormLayout = ({ children, title }: PropsType) => { export default FormLayout; const StyledFormLayout = styled.section` - width: 100vw; + width: 100%; height: 100vh; background-color: ${color.white}; `; diff --git a/apps/user/src/services/QueryClientProvider.tsx b/apps/user/src/services/QueryClientProvider.tsx index 0a39cdbe2..00223d592 100644 --- a/apps/user/src/services/QueryClientProvider.tsx +++ b/apps/user/src/services/QueryClientProvider.tsx @@ -4,11 +4,11 @@ import { QueryClient, QueryClientProvider as MaruQueryClientProvider } from '@ta import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; import { ReactNode, useState } from 'react'; -interface PropsType { +interface Props { children: ReactNode; } -const QueryClientProvider = ({ children }: PropsType) => { +const QueryClientProvider = ({ children }: Props) => { const [queryClient] = useState( () => new QueryClient({ diff --git a/apps/user/src/services/auth/mutations.ts b/apps/user/src/services/auth/mutations.ts index 749ffc200..c573010d8 100644 --- a/apps/user/src/services/auth/mutations.ts +++ b/apps/user/src/services/auth/mutations.ts @@ -53,15 +53,13 @@ export const useRequestEmailMutation = (email: string) => { }; export const useLogoutUserMutation = () => { - const { handleError } = useApiError(); - const { mutate: logoutUserMutate, ...restMutation } = useMutation({ mutationFn: deleteLogoutUser, onSuccess: () => { localStorage.clear(); window.location.href = ROUTES.MAIN; }, - onError: handleError, + onError: localStorage.clear, }); return { logoutUserMutate, ...restMutation }; diff --git a/packages/maru-hooks/index.ts b/packages/maru-hooks/index.ts index ffccb9021..af2162596 100644 --- a/packages/maru-hooks/index.ts +++ b/packages/maru-hooks/index.ts @@ -1,4 +1,4 @@ -export { default as useInterval } from './src/useInterval'; +export { default as useBooleanState } from './src/useBooleanState'; export { default as useDebounceInput } from './src/useDebounceInput'; +export { default as useInterval } from './src/useInterval'; export { default as useOutsideClick } from './src/useOutsideClick'; -export { default as useBoolean } from './src/useBoolean'; diff --git a/packages/maru-hooks/src/useBoolean.ts b/packages/maru-hooks/src/useBooleanState.ts similarity index 80% rename from packages/maru-hooks/src/useBoolean.ts rename to packages/maru-hooks/src/useBooleanState.ts index 1e23ce445..d84836052 100644 --- a/packages/maru-hooks/src/useBoolean.ts +++ b/packages/maru-hooks/src/useBooleanState.ts @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react'; -const useBoolean = (initialValue?: boolean) => { +const useBooleanState = (initialValue?: boolean) => { const [value, setValue] = useState(!!initialValue); const setTrue = useCallback(() => setValue(true), []); @@ -10,4 +10,4 @@ const useBoolean = (initialValue?: boolean) => { return { value, setValue, setTrue, setFalse, toggle }; }; -export default useBoolean; +export default useBooleanState; diff --git a/packages/maru-hooks/src/useDebounceInput.ts b/packages/maru-hooks/src/useDebounceInput.ts index a198aae33..783af0748 100644 --- a/packages/maru-hooks/src/useDebounceInput.ts +++ b/packages/maru-hooks/src/useDebounceInput.ts @@ -1,12 +1,12 @@ -import { useState, useCallback, useMemo, ChangeEventHandler } from 'react'; import debounce from 'lodash/debounce'; +import { ChangeEventHandler, useCallback, useMemo, useState } from 'react'; -interface PropsType { +interface Props { initialValue?: string; debounceTimeout?: number; } -const useDebounceInput = ({ initialValue = '', debounceTimeout = 150 }: PropsType) => { +const useDebounceInput = ({ initialValue = '', debounceTimeout = 150 }: Props) => { const [value, setValue] = useState(initialValue); const [debouncedValue, setDebouncedValue] = useState(initialValue); diff --git a/packages/maru-ui/src/Button/Button.style.ts b/packages/maru-ui/src/Button/Button.style.ts index 9b21ea941..77d83d81d 100644 --- a/packages/maru-ui/src/Button/Button.style.ts +++ b/packages/maru-ui/src/Button/Button.style.ts @@ -43,7 +43,7 @@ export const getButtonStyle = { `, DISABLED: css` background-color: ${color.gray700}; - color: ${color.white}; + color: ${color.gray400}; cursor: auto; `, }; diff --git a/packages/maru-ui/src/Button/Button.tsx b/packages/maru-ui/src/Button/Button.tsx index ecc306c19..ca09299df 100644 --- a/packages/maru-ui/src/Button/Button.tsx +++ b/packages/maru-ui/src/Button/Button.tsx @@ -6,7 +6,7 @@ import styled from 'styled-components'; import { getButtonPadding, getButtonSize, getButtonStyle } from './Button.style'; import { ButtonIcon, ButtonOption, ButtonSize } from './Button.type'; -interface PropsType extends ButtonHTMLAttributes { +interface Props extends ButtonHTMLAttributes { children: ReactNode; option?: ButtonOption; icon?: ButtonIcon; @@ -22,7 +22,7 @@ const Button = ({ size = 'MEDIUM', width, style, -}: PropsType) => { +}: Props) => { return ( icon && getButtonPadding[icon]}; - ${({ option }) => option && getButtonStyle[option]}; - ${({ size }) => size && getButtonSize[size]}; + ${(props) => props.icon && getButtonPadding[props.icon]}; + ${(props) => props && getButtonStyle[props.option]}; + ${(props) => props && getButtonSize[props.size]}; `; diff --git a/packages/maru-ui/src/Button/UnderLineButton.tsx b/packages/maru-ui/src/Button/UnderLineButton.tsx index d8c8b34df..a17b7b86d 100644 --- a/packages/maru-ui/src/Button/UnderLineButton.tsx +++ b/packages/maru-ui/src/Button/UnderLineButton.tsx @@ -2,12 +2,12 @@ import { color, font } from '@maru/theme'; import { ButtonHTMLAttributes, ReactNode } from 'react'; import styled, { css } from 'styled-components'; -interface PropsType extends ButtonHTMLAttributes { +interface Props extends ButtonHTMLAttributes { children: ReactNode; active: boolean; } -const UnderLineButton = ({ children, onClick, active }: PropsType) => { +const UnderLineButton = ({ children, onClick, active }: Props) => { return ( {children} diff --git a/packages/maru-ui/src/Confirm/Confirm.tsx b/packages/maru-ui/src/Confirm/Confirm.tsx index 5eb1628e5..f727495ab 100644 --- a/packages/maru-ui/src/Confirm/Confirm.tsx +++ b/packages/maru-ui/src/Confirm/Confirm.tsx @@ -8,7 +8,7 @@ import Column from '../Flex/Column'; import Row from '../Flex/Row'; import Text from '../Text/Text'; -interface PropsType { +interface Props { title: string; desc?: string; content: ReactNode; @@ -28,7 +28,7 @@ const Confirm = ({ onConfirm, confirmButtonText = '확인', closeButtonText = '취소', -}: PropsType) => { +}: Props) => { return ( @@ -79,7 +79,7 @@ const BlurBackground = styled.div<{ $isOpen: boolean }>` display: ${(props) => (props.$isOpen ? 'flex' : 'none')}; align-items: center; justify-content: center; - width: 100vw; + width: 100%; height: 100vh; background: rgba(0, 0, 0, 0.4); z-index: 1; diff --git a/packages/maru-ui/src/Dropdown/Dropdown.tsx b/packages/maru-ui/src/Dropdown/Dropdown.tsx index c876e154f..b552cc869 100644 --- a/packages/maru-ui/src/Dropdown/Dropdown.tsx +++ b/packages/maru-ui/src/Dropdown/Dropdown.tsx @@ -1,4 +1,4 @@ -import { useBoolean, useOutsideClick } from '@maru/hooks'; +import { useBooleanState, useOutsideClick } from '@maru/hooks'; import { IconArrowBottom, IconArrowTop } from '@maru/icon'; import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; @@ -8,7 +8,7 @@ import Text from '../Text/Text'; type DropdownSizeOption = 'MEDIUM' | 'SMALL'; -interface PropsType { +interface Props { label?: string; data: string[]; width?: CSSProperties['width']; @@ -28,12 +28,12 @@ const Dropdown = ({ onChange, name, placeholder, -}: PropsType) => { +}: Props) => { const { value: isOpen, setFalse: closeDropdown, toggle: handleToggleButtonClick, - } = useBoolean(); + } = useBooleanState(); const dropdownRef = useOutsideClick(closeDropdown); const handleDropdownItemButtonClick = (data: string) => { @@ -108,7 +108,7 @@ const StyledDropdown = styled.div<{ $isOpen: boolean; size: DropdownSizeOption } const DropdownListBox = styled.div<{ $isOpen: boolean }>` position: relative; - display: ${({ $isOpen: isOpen }) => (isOpen ? 'block' : 'none')}; + display: ${(props) => (props.$isOpen ? 'block' : 'none')}; `; const DropdownList = styled.div` diff --git a/packages/maru-ui/src/Flex/Column.tsx b/packages/maru-ui/src/Flex/Column.tsx index 30ef83a72..906e7d623 100644 --- a/packages/maru-ui/src/Flex/Column.tsx +++ b/packages/maru-ui/src/Flex/Column.tsx @@ -1,16 +1,8 @@ -import styled from 'styled-components'; -import { FlexPropsType } from './Flex.type'; import { flex } from '@maru/utils'; +import styled from 'styled-components'; +import { FlexProps } from './Flex.type'; -const Column = ({ - children, - gap, - justifyContent, - alignItems, - width, - height, - style, -}: FlexPropsType) => { +const Column = ({ children, gap, justifyContent, alignItems, width, height, style }: FlexProps) => { return ( {children} diff --git a/packages/maru-ui/src/Flex/Flex.type.ts b/packages/maru-ui/src/Flex/Flex.type.ts index 7662679a2..f243f04fa 100644 --- a/packages/maru-ui/src/Flex/Flex.type.ts +++ b/packages/maru-ui/src/Flex/Flex.type.ts @@ -1,6 +1,6 @@ -import { ReactNode, CSSProperties } from 'react'; +import { CSSProperties, ReactNode } from 'react'; -export interface FlexPropsType { +export interface FlexProps { children: ReactNode; gap?: CSSProperties['gap']; justifyContent?: CSSProperties['justifyContent']; diff --git a/packages/maru-ui/src/Flex/Row.tsx b/packages/maru-ui/src/Flex/Row.tsx index b10e5effc..1cd9b1f0a 100644 --- a/packages/maru-ui/src/Flex/Row.tsx +++ b/packages/maru-ui/src/Flex/Row.tsx @@ -1,15 +1,7 @@ import { styled } from 'styled-components'; -import { FlexPropsType } from './Flex.type'; +import { FlexProps } from './Flex.type'; -const Row = ({ - children, - gap, - justifyContent, - alignItems, - width, - height, - style, -}: FlexPropsType) => { +const Row = ({ children, gap, justifyContent, alignItems, width, height, style }: FlexProps) => { return ( {children} diff --git a/packages/maru-ui/src/Input/ButtonInput.tsx b/packages/maru-ui/src/Input/ButtonInput.tsx index d2fed43df..22125e365 100644 --- a/packages/maru-ui/src/Input/ButtonInput.tsx +++ b/packages/maru-ui/src/Input/ButtonInput.tsx @@ -2,9 +2,9 @@ import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; import styled from 'styled-components'; import Input from './Input'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; -interface ButtonInputPropsType extends InputPropsType { +interface ButtonInputProps extends InputProps { buttonText: string; enabled?: boolean; buttonWidth?: string; @@ -25,7 +25,7 @@ const ButtonInput = ({ readOnly, isError = false, errorMessage, -}: ButtonInputPropsType) => { +}: ButtonInputProps) => { return (
{label && } diff --git a/packages/maru-ui/src/Input/ConditionalMessage.tsx b/packages/maru-ui/src/Input/ConditionalMessage.tsx index 522be8076..c4b089fb7 100644 --- a/packages/maru-ui/src/Input/ConditionalMessage.tsx +++ b/packages/maru-ui/src/Input/ConditionalMessage.tsx @@ -1,29 +1,29 @@ import { color, font } from '@maru/theme'; import styled, { css } from 'styled-components'; -interface PropsType { +interface Props { message?: string; errorMessage?: string; isError?: boolean; } -const ConditionalMessage = ({ message, errorMessage, isError = false }: PropsType) => { +const ConditionalMessage = ({ message, errorMessage, isError = false }: Props) => { return isError ? ( errorMessage ? (
- {errorMessage} + {errorMessage}
) : null ) : message ? ( - {message} + {message} ) : null; }; export default ConditionalMessage; -const StyledConditionalMessage = styled.p<{ isError: boolean }>` - ${({ isError }) => - isError +const StyledConditionalMessage = styled.p<{ $isError: boolean }>` + ${(props) => + props.$isError ? css` position: absolute; top: 0; diff --git a/packages/maru-ui/src/Input/Input.tsx b/packages/maru-ui/src/Input/Input.tsx index 289cc801f..c8aca2586 100644 --- a/packages/maru-ui/src/Input/Input.tsx +++ b/packages/maru-ui/src/Input/Input.tsx @@ -2,7 +2,7 @@ import { IconError } from '@maru/icon'; import { color, font } from '@maru/theme'; import styled, { css } from 'styled-components'; import ConditionalMessage from './ConditionalMessage'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; const Input = ({ width = '320px', @@ -17,7 +17,7 @@ const Input = ({ readOnly, textAlign, isError = false, -}: InputPropsType) => { +}: InputProps) => { return (
{label && } @@ -30,7 +30,7 @@ const Input = ({ value={value} readOnly={readOnly} style={{ textAlign }} - isError={isError} + $isError={isError} /> {isError && ( ` +const StyledInput = styled.input<{ $isError: boolean }>` ${font.p2} color: ${color.gray800}; height: 48px; @@ -70,8 +70,8 @@ const StyledInput = styled.input<{ isError?: boolean }>` outline: 2px solid rgba(20, 112, 255, 0.25); } - ${({ isError }) => - isError && + ${(props) => + props.$isError && css` border: 1px solid ${color.red}; outline: 2px solid rgba(244, 67, 54, 0.25); diff --git a/packages/maru-ui/src/Input/Input.type.ts b/packages/maru-ui/src/Input/Input.type.ts index 47d07b212..ae418d9c9 100644 --- a/packages/maru-ui/src/Input/Input.type.ts +++ b/packages/maru-ui/src/Input/Input.type.ts @@ -1,6 +1,6 @@ import { CSSProperties, InputHTMLAttributes } from 'react'; -export interface InputPropsType extends InputHTMLAttributes { +export interface InputProps extends InputHTMLAttributes { width?: string; label?: string; errorMessage?: string; diff --git a/packages/maru-ui/src/Input/NumberInput.tsx b/packages/maru-ui/src/Input/NumberInput.tsx index 443ddaa8b..2dac61250 100644 --- a/packages/maru-ui/src/Input/NumberInput.tsx +++ b/packages/maru-ui/src/Input/NumberInput.tsx @@ -1,6 +1,6 @@ import { color, font } from '@maru/theme'; import { css, styled } from 'styled-components'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; const NumberInput = ({ name, @@ -9,8 +9,8 @@ const NumberInput = ({ onChange, placeholder, value = 0, - isError, -}: InputPropsType) => { + isError = false, +}: InputProps) => { return ( ); @@ -27,7 +27,7 @@ const NumberInput = ({ export default NumberInput; -const StyledNumberInput = styled.input<{ isError?: boolean }>` +const StyledNumberInput = styled.input<{ $isError: boolean }>` ${font.p2} height: 40px; border-radius: 6px; @@ -50,9 +50,8 @@ const StyledNumberInput = styled.input<{ isError?: boolean }>` margin: 0; } - ${({ isError }) => - typeof isError === 'boolean' && - isError && + ${(props) => + props.$isError && css` border: 1px solid ${color.red}; outline: 2px solid rgba(244, 67, 54, 0.25); diff --git a/packages/maru-ui/src/Input/PreviewInput.tsx b/packages/maru-ui/src/Input/PreviewInput.tsx index b2f0b4b7d..c6bd63b37 100644 --- a/packages/maru-ui/src/Input/PreviewInput.tsx +++ b/packages/maru-ui/src/Input/PreviewInput.tsx @@ -1,10 +1,10 @@ -import { useBoolean } from '@maru/hooks'; +import { useBooleanState } from '@maru/hooks'; import { IconInvisibleEye, IconVisibleEye } from '@maru/icon'; import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; import styled, { css } from 'styled-components'; import ConditionalMessage from './ConditionalMessage'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; const PreviewInput = ({ width = '320px', @@ -16,14 +16,14 @@ const PreviewInput = ({ message, isError = false, onChange, -}: InputPropsType) => { - const { value: isPreview, toggle: toggleIsPreview } = useBoolean(); +}: InputProps) => { + const { value: isPreview, toggle: toggleIsPreview } = useBooleanState(); return (
{label && }
- + ` +const StyledPreviewInput = styled.div<{ $isError: boolean }>` ${flex({ alignItems: 'center', justifyContent: 'space-between' })} gap: 10px; height: 48px; @@ -67,16 +67,16 @@ const StyledPreviewInput = styled.div<{ isError?: boolean }>` border-radius: 6px; &:focus-within { - border: 1px solid ${({ isError }) => (isError ? color.red : color.maruDefault)}; - ${({ isError }) => - !isError && + border: 1px solid ${(props) => (props.$isError ? color.red : color.maruDefault)}; + ${(props) => + !props.$isError && css` outline: 2px solid rgba(20, 112, 255, 0.25); `} } - ${({ isError }) => - isError && + ${(props) => + props.$isError && css` border: 1px solid ${color.red}; outline: 2px solid rgba(244, 67, 54, 0.25); diff --git a/packages/maru-ui/src/Input/SearchInput.tsx b/packages/maru-ui/src/Input/SearchInput.tsx index 2b2284a50..d80880053 100644 --- a/packages/maru-ui/src/Input/SearchInput.tsx +++ b/packages/maru-ui/src/Input/SearchInput.tsx @@ -2,7 +2,7 @@ import { IconSearch } from '@maru/icon'; import { color } from '@maru/theme'; import { flex } from '@maru/utils'; import styled from 'styled-components'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; const SearchInput = ({ width = '320px', @@ -11,7 +11,7 @@ const SearchInput = ({ name, value, onChange, -}: InputPropsType) => { +}: InputProps) => { return ( diff --git a/packages/maru-ui/src/Input/TimeLimitInput.tsx b/packages/maru-ui/src/Input/TimeLimitInput.tsx index 8d70dd565..34c60465e 100644 --- a/packages/maru-ui/src/Input/TimeLimitInput.tsx +++ b/packages/maru-ui/src/Input/TimeLimitInput.tsx @@ -5,9 +5,9 @@ import { Dispatch, SetStateAction } from 'react'; import styled, { css } from 'styled-components'; import Text from '../Text/Text'; import ConditionalMessage from './ConditionalMessage'; -import { InputPropsType } from './Input.type'; +import { InputProps } from './Input.type'; -interface TimeLimitInputPropsType extends InputPropsType { +interface TimeLimitInputProps extends InputProps { timerTime: number; setTimerTime: Dispatch>; } @@ -23,7 +23,7 @@ const TimeLimitInput = ({ setTimerTime, isError = false, errorMessage, -}: TimeLimitInputPropsType) => { +}: TimeLimitInputProps) => { useInterval(() => { setTimerTime((prev) => prev - 1); if (timerTime <= 0) { @@ -35,7 +35,7 @@ const TimeLimitInput = ({
{label && }
- + {formatTime(timerTime)} @@ -49,7 +49,7 @@ const TimeLimitInput = ({ export default TimeLimitInput; -const StyledTimeLimitInput = styled.div<{ isError: boolean }>` +const StyledTimeLimitInput = styled.div<{ $isError: boolean }>` ${flex({ alignItems: 'center', justifyContent: 'center' })} gap: 10px; height: 48px; @@ -59,16 +59,16 @@ const StyledTimeLimitInput = styled.div<{ isError: boolean }>` border-radius: 6px; &:focus-within { - border: 1px solid ${({ isError }) => (isError ? color.red : color.maruDefault)}; - ${({ isError }) => - !isError && + border: 1px solid ${(props) => (props.$isError ? color.red : color.maruDefault)}; + ${(props) => + !props.$isError && css` outline: 2px solid rgba(20, 112, 255, 0.25); `} } - ${({ isError }) => - isError && + ${(props) => + props.$isError && css` border: 1px solid ${color.red}; outline: 2px solid rgba(244, 67, 54, 0.25); @@ -76,7 +76,7 @@ const StyledTimeLimitInput = styled.div<{ isError: boolean }>` &:focus { border: 1px solid ${color.red}; } - `} + `}; `; const Input = styled.input` diff --git a/packages/maru-ui/src/Link/Link.tsx b/packages/maru-ui/src/Link/Link.tsx index 6b0da4ac0..24a6d5db5 100644 --- a/packages/maru-ui/src/Link/Link.tsx +++ b/packages/maru-ui/src/Link/Link.tsx @@ -1,14 +1,14 @@ import { flex } from '@maru/utils'; -import { ReactNode, CSSProperties } from 'react'; +import { CSSProperties, ReactNode } from 'react'; import styled from 'styled-components'; -interface PropsType { +interface Props { children: ReactNode; onClick: () => void; gap?: CSSProperties['gap']; } -const Link = ({ children, gap, onClick }: PropsType) => { +const Link = ({ children, gap, onClick }: Props) => { return ( {children} diff --git a/packages/maru-ui/src/Modal/Modal.tsx b/packages/maru-ui/src/Modal/Modal.tsx index 7054c0e7a..1f7acb39e 100644 --- a/packages/maru-ui/src/Modal/Modal.tsx +++ b/packages/maru-ui/src/Modal/Modal.tsx @@ -8,7 +8,7 @@ import Column from '../Flex/Column'; import Row from '../Flex/Row'; import Text from '../Text/Text'; -interface PropsType { +interface Props { title: string; children: ReactNode; isOpen: boolean; @@ -19,18 +19,9 @@ interface PropsType { width?: CSSProperties['width']; } -const Modal = ({ - title, - children, - isOpen, - onClose, - onConfirm, - style, - height, - width, -}: PropsType) => { +const Modal = ({ title, children, isOpen, onClose, onConfirm, style, height, width }: Props) => { return ( - + ` - display: ${(props) => (props.isOpen ? 'flex' : 'none')}; +const BlurBackground = styled.div<{ $isOpen: boolean }>` + display: ${(props) => (props.$isOpen ? 'flex' : 'none')}; align-items: center; justify-content: center; position: fixed; top: 0; left: 0; - width: 100vw; + width: 100%; height: 100vh; background: rgba(0, 0, 0, 0.4); z-index: 1; diff --git a/packages/maru-ui/src/Radio/Radio.tsx b/packages/maru-ui/src/Radio/Radio.tsx index 8b6a205c7..bfdd00d6d 100644 --- a/packages/maru-ui/src/Radio/Radio.tsx +++ b/packages/maru-ui/src/Radio/Radio.tsx @@ -2,9 +2,9 @@ import { flex } from '@maru/utils'; import { InputHTMLAttributes } from 'react'; import { styled } from 'styled-components'; -interface PropsType extends InputHTMLAttributes {} +interface Props extends InputHTMLAttributes {} -const Radio = ({ value, name, checked, onChange }: PropsType) => { +const Radio = ({ value, name, checked, onChange }: Props) => { return ( diff --git a/packages/maru-ui/src/RadioGroup/RadioGroup.tsx b/packages/maru-ui/src/RadioGroup/RadioGroup.tsx index 4004c448e..52080e68a 100644 --- a/packages/maru-ui/src/RadioGroup/RadioGroup.tsx +++ b/packages/maru-ui/src/RadioGroup/RadioGroup.tsx @@ -4,7 +4,7 @@ import styled from 'styled-components'; import Row from '../Flex/Row'; import Radio from '../Radio/Radio'; -interface PropsType { +interface Props { label: string; list: { value?: string; label: string; checked?: boolean }[] | string[]; name: string; @@ -12,7 +12,7 @@ interface PropsType { onChange: ChangeEventHandler; } -const RadioGroup = ({ label, list, name, value, onChange }: PropsType) => { +const RadioGroup = ({ label, list, name, value, onChange }: Props) => { return (
diff --git a/packages/maru-ui/src/Table/Table.type.ts b/packages/maru-ui/src/Table/Table.type.ts index 85f8087b7..3569f4995 100644 --- a/packages/maru-ui/src/Table/Table.type.ts +++ b/packages/maru-ui/src/Table/Table.type.ts @@ -1,6 +1,6 @@ import { CSSProperties, ReactNode } from 'react'; -export interface TablePropsType { +export interface TableProps { children: ReactNode; width: CSSProperties['width']; height: CSSProperties['height']; diff --git a/packages/maru-ui/src/Table/Td.tsx b/packages/maru-ui/src/Table/Td.tsx index 137ca9aac..09188b883 100644 --- a/packages/maru-ui/src/Table/Td.tsx +++ b/packages/maru-ui/src/Table/Td.tsx @@ -1,8 +1,7 @@ +import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; -import { font, color } from '@maru/theme'; -import { CSSProperties, ReactNode } from 'react'; -import { TableOptionType, TablePropsType } from './Table.type'; import styled, { css } from 'styled-components'; +import { TableOptionType, TableProps } from './Table.type'; const Td = ({ children, @@ -13,7 +12,7 @@ const Td = ({ borderTopRightRadius, borderBottomLeftRadius, borderBottomRightRadius, -}: TablePropsType) => { +}: TableProps) => { return ( ` +const StyledTd = styled.div<{ option: TableOptionType }>` ${flex({ alignItems: 'center', justifyContent: 'center' })} color: ${color.gray900}; diff --git a/packages/maru-ui/src/Table/Th.tsx b/packages/maru-ui/src/Table/Th.tsx index dfe6a714e..68ea87e2c 100644 --- a/packages/maru-ui/src/Table/Th.tsx +++ b/packages/maru-ui/src/Table/Th.tsx @@ -1,7 +1,7 @@ +import { color, font } from '@maru/theme'; import { flex } from '@maru/utils'; -import { font, color } from '@maru/theme'; -import { TableOptionType, TablePropsType } from './Table.type'; import styled, { css } from 'styled-components'; +import { TableOptionType, TableProps } from './Table.type'; const Th = ({ children, @@ -12,7 +12,7 @@ const Th = ({ borderTopRightRadius, borderBottomLeftRadius, borderBottomRightRadius, -}: TablePropsType) => { +}: TableProps) => { return ( { +interface Props extends HTMLAttributes { children: ReactNode; color?: string; fontType: Font; @@ -12,7 +12,7 @@ interface PropsType extends HTMLAttributes { textAlign?: CSSProperties['textAlign']; } -const Text = ({ children, color, fontType, textAlign, width }: PropsType) => { +const Text = ({ children, color, fontType, textAlign, width }: Props) => { return ( {children} @@ -23,5 +23,5 @@ const Text = ({ children, color, fontType, textAlign, width }: PropsType) => { export default Text; const StyledText = styled.p<{ fontType: Font }>` - ${({ fontType }) => font[fontType]} + ${(props) => props.fontType && font[props.fontType]} `; diff --git a/packages/maru-ui/src/Textarea/Textarea.tsx b/packages/maru-ui/src/Textarea/Textarea.tsx index e66b374fe..84a6765b4 100644 --- a/packages/maru-ui/src/Textarea/Textarea.tsx +++ b/packages/maru-ui/src/Textarea/Textarea.tsx @@ -2,12 +2,12 @@ import { color, font } from '@maru/theme'; import { TextareaHTMLAttributes } from 'react'; import styled from 'styled-components'; -interface PropsType extends TextareaHTMLAttributes { +interface Props extends TextareaHTMLAttributes { limit: number; label: string; } -const Textarea = ({ limit, label, name, value, onChange }: PropsType) => { +const Textarea = ({ limit, label, name, value, onChange }: Props) => { const textValue = value as string; return ( diff --git a/packages/maru-utils/styles/flex.ts b/packages/maru-utils/styles/flex.ts index ae790722d..81654448a 100644 --- a/packages/maru-utils/styles/flex.ts +++ b/packages/maru-utils/styles/flex.ts @@ -1,13 +1,13 @@ -import { css } from 'styled-components'; import type { CSSProperties } from 'react'; +import { css } from 'styled-components'; -interface PropsType { +interface Props { flexDirection?: CSSProperties['flexDirection']; justifyContent?: CSSProperties['justifyContent']; alignItems?: CSSProperties['alignItems']; } -const flex = ({ flexDirection, justifyContent, alignItems }: PropsType) => { +const flex = ({ flexDirection, justifyContent, alignItems }: Props) => { return css` display: flex; flex-direction: ${flexDirection};