diff --git a/public/images/bg-start.png b/public/images/bg-start.png
new file mode 100644
index 0000000..a912077
Binary files /dev/null and b/public/images/bg-start.png differ
diff --git a/public/images/bg-start2.png b/public/images/bg-start2.png
new file mode 100644
index 0000000..b4df401
Binary files /dev/null and b/public/images/bg-start2.png differ
diff --git a/public/images/blue-check.png b/public/images/blue-check.png
new file mode 100644
index 0000000..1e19e38
Binary files /dev/null and b/public/images/blue-check.png differ
diff --git a/public/images/image.png b/public/images/image.png
new file mode 100644
index 0000000..7e9703d
Binary files /dev/null and b/public/images/image.png differ
diff --git a/public/images/profile-1-red.png b/public/images/profile-1-red.png
new file mode 100644
index 0000000..96615b0
Binary files /dev/null and b/public/images/profile-1-red.png differ
diff --git a/public/images/profile-1.png b/public/images/profile-1.png
new file mode 100644
index 0000000..1e15711
Binary files /dev/null and b/public/images/profile-1.png differ
diff --git a/public/images/profile-2.png b/public/images/profile-2.png
new file mode 100644
index 0000000..f2b0342
Binary files /dev/null and b/public/images/profile-2.png differ
diff --git a/src/app/globals.css b/src/app/globals.css
index 8e6519d..759ed29 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -2,14 +2,26 @@
@tailwind components;
@tailwind utilities;
-:root {
- --background: #ffffff;
- --foreground: #171717;
+html,
+body {
+ height: 100vh;
}
body {
color: var(--foreground);
background: var(--background);
- min-height: 100vh;
max-width: 600px;
+ min-height: 600px;
+ color: #1a1a25;
+ overflow: hidden;
+}
+
+input[type='number'] {
+ -moz-appearance: textfield;
+ appearance: textfield;
+}
+
+input[type='number']::-webkit-outer-spin-button,
+input[type='number']::-webkit-inner-spin-button {
+ -webkit-appearance: none;
}
diff --git a/src/app/start/components/StartHeader.tsx b/src/app/start/components/StartHeader.tsx
new file mode 100644
index 0000000..1487cfa
--- /dev/null
+++ b/src/app/start/components/StartHeader.tsx
@@ -0,0 +1,18 @@
+import { Left } from '@/components/Icons'
+import { StrictPropsWithChildren } from '@/types'
+
+interface StartHeaderProps extends StrictPropsWithChildren {
+ onBack: () => void
+}
+
+export default function StartHeader({ children, onBack }: StartHeaderProps) {
+ return (
+
+
+ {children}
+
+ )
+}
diff --git a/src/app/start/components/Step1.tsx b/src/app/start/components/Step1.tsx
new file mode 100644
index 0000000..ad90565
--- /dev/null
+++ b/src/app/start/components/Step1.tsx
@@ -0,0 +1,60 @@
+'use client'
+
+import { Input } from '@/components/common'
+import useUserInfo from '@/hooks/store/useUserInfo'
+import Image from 'next/image'
+import { useState } from 'react'
+
+interface Step1Props {
+ setError: (error: boolean) => void
+}
+
+export default function Step1({ setError }: Step1Props) {
+ const { userInfo, setUserInfo } = useUserInfo()
+ const [username, setUsername] = useState(userInfo.name)
+ const [errorMessage, setErrorMessage] = useState()
+
+ const validateName = (name: string) => {
+ const regex = /^[가-힣a-zA-Z0-9]{0,6}$/
+ return regex.test(name)
+ }
+
+ const handleChangeName = (e: React.ChangeEvent) => {
+ const newName = e.target.value
+ setUsername(newName)
+
+ if (!validateName(newName)) {
+ setErrorMessage('닉네임은 한글/영문/숫자를 포함한 6자 이내만 가능해요.')
+ } else {
+ setError(false)
+ setErrorMessage('')
+ setUserInfo({ ...userInfo, name: newName })
+ }
+ }
+ return (
+
+
+ 안녕하세요, 조각조각이에요 :)
+
+ 어떻게 불러드릴까요?
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/start/components/Step2.tsx b/src/app/start/components/Step2.tsx
new file mode 100644
index 0000000..948c9fc
--- /dev/null
+++ b/src/app/start/components/Step2.tsx
@@ -0,0 +1,94 @@
+'use client'
+
+import { Input } from '@/components/common'
+import CheckboxWithLabel from '@/components/common/CheckBox'
+import useUserInfo from '@/hooks/store/useUserInfo'
+import Image from 'next/image'
+import { ChangeEvent, useState } from 'react'
+
+interface Step2Props {
+ setError: (error: boolean) => void
+}
+
+export default function Step2({ setError }: Step2Props) {
+ const [errorMessage, setErrorMessage] = useState()
+ const { userInfo, setUserInfo } = useUserInfo()
+ const { name, age, gender } = userInfo
+
+ const [userAge, setUserAge] = useState(age ? String(age) : '')
+
+ const handleGenderChange = (data: string) => {
+ setUserInfo({ ...userInfo, gender: data })
+
+ if (!errorMessage) {
+ setError(false)
+ }
+ }
+ const handleAgeChange = (e: ChangeEvent) => {
+ const { value } = e.target
+ if (/^\d+$/.test(value) || value === '') {
+ setUserAge(value)
+
+ const regex = /^[0-9]{4}$/
+
+ if (regex.test(value)) {
+ setUserInfo({ ...userInfo, age: value ? Number(value) : undefined })
+ setErrorMessage('')
+ if (!gender) {
+ setError(false)
+ }
+ } else {
+ setError(true)
+ setErrorMessage('4자리 숫자로 입력해주세요.')
+ }
+ }
+ }
+
+ return (
+
+
+ {name} 님의 나이와 성별을
+ 알려주세요.
+
+
+
출생년도
+
+
+
성별
+
+ handleGenderChange('female')}
+ />
+
+ handleGenderChange('male')}
+ />
+ handleGenderChange('no')}
+ />
+
+
+
+
+ )
+}
diff --git a/src/app/start/components/Step3.tsx b/src/app/start/components/Step3.tsx
new file mode 100644
index 0000000..d58a769
--- /dev/null
+++ b/src/app/start/components/Step3.tsx
@@ -0,0 +1,77 @@
+'use client'
+
+import {
+ Profile1,
+ Profile2,
+ Profile3,
+ Profile4,
+ Profile5,
+ Profile6,
+ Profile7,
+ SelectProfile,
+} from '@/components'
+import useUserInfo from '@/hooks/store/useUserInfo'
+import { cn } from '@/util'
+import { useState } from 'react'
+
+const profiles = [
+ { id: '1', Component: Profile1 },
+ { id: '2', Component: Profile2 },
+ { id: '3', Component: Profile3 },
+ { id: '4', Component: Profile4 },
+ { id: '5', Component: Profile5 },
+ { id: '6', Component: Profile6 },
+ { id: '7', Component: Profile7 },
+]
+
+export default function Step3() {
+ const { userInfo, setUserInfo } = useUserInfo()
+ const [selectedProfile, setSelectedProfile] = useState(userInfo.profileIcon)
+
+ const handleProfileSelect = (profile: string) => {
+ setSelectedProfile(profile)
+ setUserInfo({ ...userInfo, profileIcon: profile })
+ }
+
+ return (
+
+
어떤 프로필로 함께 하시겠어요?
+
+ 프로필은 나중에 바꿀 수 있어요
+
+
+
+ {profiles.map(({ id, Component }) => (
+
+
+
+ ))}
+
+
+
+ {profiles.map(({ id, Component }) => (
+
+ ))}
+
+
+ )
+}
diff --git a/src/app/start/components/Step4.tsx b/src/app/start/components/Step4.tsx
new file mode 100644
index 0000000..601994b
--- /dev/null
+++ b/src/app/start/components/Step4.tsx
@@ -0,0 +1,207 @@
+'use client'
+
+import useUserInfo from '@/hooks/store/useUserInfo'
+import { useState, useEffect } from 'react'
+import { motion } from 'framer-motion'
+
+const boxes = [
+ {
+ id: 1,
+ text: '문화
예술',
+ width: '100px',
+ fontSize: '18px',
+ startX: '5%',
+ startY: '-100px',
+ endX: '100px',
+ endY: '400px',
+ },
+ {
+ id: 2,
+ text: '자기
개발',
+ width: '70px',
+ fontSize: '16px',
+ startX: '30px',
+ startY: '-100px',
+ endX: '50px',
+ endY: '250px',
+ },
+ {
+ id: 3,
+ text: '자연',
+ width: '80px',
+ fontSize: '16px',
+ startX: '150px',
+ startY: '-100px',
+ endX: '150px',
+ endY: '300px',
+ },
+ {
+ id: 4,
+ text: '휴식',
+ width: '100px',
+ fontSize: '18px',
+ startX: '300px',
+ startY: '-100px',
+ endX: '250px',
+ endY: '350px',
+ },
+ {
+ id: 5,
+ text: '소셜',
+ width: '66px',
+ fontSize: '14px',
+ startX: '200px',
+ startY: '-100px',
+ endX: '170px',
+ endY: '180px',
+ },
+ {
+ id: 6,
+ text: '건강',
+ width: '52px',
+ fontSize: '12px',
+ startX: '300px',
+ startY: '-100px',
+ endX: '300px',
+ endY: '120px',
+ },
+ {
+ id: 7,
+ text: '엔터테인먼트',
+ width: '57px',
+ fontSize: '10px',
+ startX: '20px',
+ startY: '-100px',
+ endX: '20px',
+ endY: '150px',
+ },
+]
+
+const backgroundShapes = [
+ {
+ id: 1,
+ width: '20px',
+ startX: '350px',
+ startY: '50px',
+ endX: '80px',
+ endY: '350px',
+ },
+ {
+ id: 2,
+ width: '15px',
+ startX: '20px',
+ startY: '30px',
+ endX: '20px',
+ endY: '250px',
+ },
+ {
+ id: 3,
+ width: '10px',
+ startX: '300px',
+ startY: '100px',
+ endX: '300px',
+ endY: '250px',
+ },
+ {
+ id: 4,
+ width: '25px',
+ startX: '400px',
+ startY: '0px',
+ endX: '100px',
+ endY: '400px',
+ },
+ {
+ id: 5,
+ width: '30px',
+ startX: '200px',
+ startY: '60px',
+ endX: '200px',
+ endY: '300px',
+ },
+ {
+ id: 6,
+ width: '12px',
+ startX: '350px',
+ startY: '10px',
+ endX: '350px',
+ endY: '200px',
+ },
+ {
+ id: 7,
+ width: '30px',
+ startX: '350px',
+ startY: '10px',
+ endX: '350px',
+ endY: '70px',
+ },
+]
+
+export default function Step4() {
+ const { userInfo } = useUserInfo()
+ const [isAnimating, setIsAnimating] = useState(false)
+
+ useEffect(() => {
+ setTimeout(() => {
+ setIsAnimating(true)
+ }, 200)
+ }, [])
+
+ return (
+
+
+
+ 환영해요, {userInfo.name}님!
+
+
+ 조각조각이 고망님의 흩어진
+ 시간 조각들을 찾아줄게요.
+
+
+
+ {backgroundShapes.map((shape, index) => (
+
+ ))}
+
+ {boxes.map((box, index) => (
+
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/src/app/start/components/index.tsx b/src/app/start/components/index.tsx
new file mode 100644
index 0000000..a49d8d9
--- /dev/null
+++ b/src/app/start/components/index.tsx
@@ -0,0 +1,3 @@
+export { default as Step1 } from './Step1'
+export { default as Step2 } from './Step2'
+export { default as StartHeader } from './StartHeader'
diff --git a/src/app/start/layout.tsx b/src/app/start/layout.tsx
new file mode 100644
index 0000000..62bc662
--- /dev/null
+++ b/src/app/start/layout.tsx
@@ -0,0 +1,11 @@
+import type { Metadata } from 'next'
+import { StrictPropsWithChildren } from '@/types'
+import './start.css'
+
+export const metadata: Metadata = {
+ title: '조각조각 - 회원가입',
+ description: '조각조각 - 회원가입 : 사용자 정보 입력',
+}
+export default function StartLayout({ children }: StrictPropsWithChildren) {
+ return {children}
+}
diff --git a/src/app/start/page.tsx b/src/app/start/page.tsx
new file mode 100644
index 0000000..f57e8d9
--- /dev/null
+++ b/src/app/start/page.tsx
@@ -0,0 +1,74 @@
+'use client'
+
+import { Button, If } from '@/components/common'
+import { useState } from 'react'
+import { cn } from '@/util'
+import Step1 from './components/Step1'
+import Step2 from './components/Step2'
+import StartHeader from './components/StartHeader'
+import Step3 from './components/Step3'
+import Step4 from './components/Step4'
+
+export default function Start() {
+ const [step, setStep] = useState(1)
+ const [text, setText] = useState('다음')
+ const [error, setError] = useState(true)
+
+ const handleBack = () => {
+ setStep((prevStep) => Math.max(prevStep - 1, 1))
+ }
+
+ const handleNext = () => {
+ setStep((prevStep) => Math.min(prevStep + 1, 4))
+ if (step === 2) {
+ setError(false)
+ } else setError(true)
+
+ if (step === 3) {
+ setError(false)
+ setText('시작하기')
+ }
+ }
+
+ const progressBarWidth = `${(step / 3) * 100}%`
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/start/start.css b/src/app/start/start.css
new file mode 100644
index 0000000..0d66314
--- /dev/null
+++ b/src/app/start/start.css
@@ -0,0 +1,7 @@
+.title {
+ @apply text-2xl font-semibold leading-34 mt-24 mb-40;
+}
+
+.subtitle {
+ @apply text-lg font-semibold leading-relaxed mt-44;
+}
diff --git a/src/components/Icons/Caution.tsx b/src/components/Icons/Caution.tsx
new file mode 100644
index 0000000..9d60e15
--- /dev/null
+++ b/src/components/Icons/Caution.tsx
@@ -0,0 +1,39 @@
+import { SVGProps } from 'react'
+
+export default function Caution({ ...props }: SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Check.tsx b/src/components/Icons/Check.tsx
new file mode 100644
index 0000000..cb09357
--- /dev/null
+++ b/src/components/Icons/Check.tsx
@@ -0,0 +1,33 @@
+import { SVGProps } from 'react'
+
+export default function Check({
+ color,
+ ...props
+}: { color?: string } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Left.tsx b/src/components/Icons/Left.tsx
new file mode 100644
index 0000000..14abe15
--- /dev/null
+++ b/src/components/Icons/Left.tsx
@@ -0,0 +1,24 @@
+import { SVGProps } from 'react'
+
+export default function Left({ ...props }: SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile1.tsx b/src/components/Icons/Profile1.tsx
new file mode 100644
index 0000000..ce71a01
--- /dev/null
+++ b/src/components/Icons/Profile1.tsx
@@ -0,0 +1,431 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile2.tsx b/src/components/Icons/Profile2.tsx
new file mode 100644
index 0000000..355b23c
--- /dev/null
+++ b/src/components/Icons/Profile2.tsx
@@ -0,0 +1,278 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile3.tsx b/src/components/Icons/Profile3.tsx
new file mode 100644
index 0000000..7fa7454
--- /dev/null
+++ b/src/components/Icons/Profile3.tsx
@@ -0,0 +1,243 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile4.tsx b/src/components/Icons/Profile4.tsx
new file mode 100644
index 0000000..4a0cb20
--- /dev/null
+++ b/src/components/Icons/Profile4.tsx
@@ -0,0 +1,393 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile5.tsx b/src/components/Icons/Profile5.tsx
new file mode 100644
index 0000000..a19ca4a
--- /dev/null
+++ b/src/components/Icons/Profile5.tsx
@@ -0,0 +1,179 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile6.tsx b/src/components/Icons/Profile6.tsx
new file mode 100644
index 0000000..8bd142e
--- /dev/null
+++ b/src/components/Icons/Profile6.tsx
@@ -0,0 +1,403 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/Profile7.tsx b/src/components/Icons/Profile7.tsx
new file mode 100644
index 0000000..d63dbf7
--- /dev/null
+++ b/src/components/Icons/Profile7.tsx
@@ -0,0 +1,333 @@
+import { SVGProps } from 'react'
+
+export default function Profile1({
+ active,
+ ...props
+}: { active?: boolean } & SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/SelectProfile.tsx b/src/components/Icons/SelectProfile.tsx
new file mode 100644
index 0000000..baf690e
--- /dev/null
+++ b/src/components/Icons/SelectProfile.tsx
@@ -0,0 +1,19 @@
+import { SVGProps } from 'react'
+
+export default function Left({ ...props }: SVGProps) {
+ return (
+
+ )
+}
diff --git a/src/components/Icons/index.tsx b/src/components/Icons/index.tsx
new file mode 100644
index 0000000..04ac249
--- /dev/null
+++ b/src/components/Icons/index.tsx
@@ -0,0 +1,11 @@
+export { default as Left } from './Left'
+export { default as Check } from './Check'
+export { default as Caution } from './Caution'
+export { default as Profile1 } from './Profile1'
+export { default as Profile2 } from './Profile2'
+export { default as Profile3 } from './Profile3'
+export { default as Profile4 } from './Profile4'
+export { default as Profile5 } from './Profile5'
+export { default as Profile6 } from './Profile6'
+export { default as Profile7 } from './Profile7'
+export { default as SelectProfile } from './SelectProfile'
diff --git a/src/components/common/Button/index.tsx b/src/components/common/Button/index.tsx
index 43c607b..7b9635e 100644
--- a/src/components/common/Button/index.tsx
+++ b/src/components/common/Button/index.tsx
@@ -18,6 +18,6 @@ const Button = forwardRef(
},
)
-Button.displayName = 'Crayon-Button'
+Button.displayName = 'q-Button'
export default Button
diff --git a/src/components/common/Button/useButton.ts b/src/components/common/Button/useButton.ts
index 7f281ed..d537d37 100644
--- a/src/components/common/Button/useButton.ts
+++ b/src/components/common/Button/useButton.ts
@@ -32,8 +32,9 @@ export function useButton(props: UseButtonProp) {
ref: domRef,
onClick: handleClick,
className: cn(
- `py-10 px-40 rounded-button h-51 text-[22px] text-[#fff] flex items-center gap-10 justify-center focus:outline-none whitespace-nowrap`,
- disabled && 'cursor-not-allowed opacity-70',
+ `py-10 px-40 rounded-12 h-51 text-22 text-[#fff] bg-black flex items-center gap-10 justify-center focus:outline-none whitespace-nowrap`,
+ disabled &&
+ 'cursor-not-allowed bg-primary_foundation_10 text-primary_foundation_40',
className,
),
}),
diff --git a/src/components/common/CheckBox/index.tsx b/src/components/common/CheckBox/index.tsx
new file mode 100644
index 0000000..0ed2434
--- /dev/null
+++ b/src/components/common/CheckBox/index.tsx
@@ -0,0 +1,44 @@
+import { Check } from '@/components/Icons'
+import { cn } from '@/util'
+import Button from '../Button'
+
+interface CheckboxWithLabelProps {
+ id: string
+ label: string
+ isChecked: boolean
+ onChange: (id: string) => void
+ isRequired?: boolean
+}
+
+export default function CheckboxWithLabel({
+ id,
+ label,
+ isChecked,
+ onChange,
+ isRequired = false,
+}: CheckboxWithLabelProps) {
+ return (
+
+
+
+ {label}
+ {isRequired && *}
+
+
+ )
+}
diff --git a/src/components/common/Input/index.tsx b/src/components/common/Input/index.tsx
new file mode 100644
index 0000000..8a8d5ae
--- /dev/null
+++ b/src/components/common/Input/index.tsx
@@ -0,0 +1,49 @@
+'use client'
+
+import { forwardRef } from 'react'
+import { Caution } from '@/components/Icons'
+import Image from 'next/image'
+import { useInput, UseInputProps } from './useInput'
+import If from '../If'
+
+const Input = forwardRef((props, ref) => {
+ const { endContent, startContent, error, label, success, value } = props
+ const { getBaseProps, getInputProps, isClearable, getClearButtonProps } =
+ useInput({ ...props, ref })
+
+ return (
+ <>
+
+ {startContent}
+
+ {/* eslint-disable-next-line */}
+ {isClearable && }
+ {endContent}
+
+
+ {label}
+
+
+
+
+ {error}
+
+
+
+
+
+ >
+ )
+})
+
+Input.displayName = 'fe-Input'
+
+export default Input
diff --git a/src/components/common/Input/useInput.ts b/src/components/common/Input/useInput.ts
new file mode 100644
index 0000000..54a0b25
--- /dev/null
+++ b/src/components/common/Input/useInput.ts
@@ -0,0 +1,92 @@
+'use client'
+
+import { InputHTMLAttributes, ChangeEvent, useCallback } from 'react'
+import { cn } from '@/util'
+import { useDOMRef } from '@/hooks'
+import { ReactRef } from '@/types/react'
+
+export interface UseInputProps extends InputHTMLAttributes {
+ ref?: ReactRef
+ wrapperClassName?: string
+ error?: string
+ label?: string
+ success?: string
+ startContent?: React.ReactNode
+ endContent?: React.ReactNode
+ isClearable?: boolean
+ onValueChange?: (value: string) => void
+ onClear?: () => void
+}
+
+export function useInput(props: UseInputProps) {
+ const {
+ ref,
+ error,
+ value,
+ wrapperClassName,
+ startContent,
+ endContent,
+ isClearable,
+ onValueChange,
+ onClear,
+ ...otherProps
+ } = props
+
+ const domRef = useDOMRef(ref)
+
+ const handleClear = useCallback(() => {
+ onValueChange?.('')
+ onClear?.()
+ }, [onValueChange, onClear])
+
+ const handleChangeValue = useCallback(
+ (e: ChangeEvent) => {
+ if (!otherProps.disabled) {
+ otherProps.onChange?.(e)
+ onValueChange?.(e.target.value)
+ }
+ },
+ [otherProps, onValueChange],
+ )
+
+ const getBaseProps = useCallback(
+ () => ({
+ className: cn(
+ 'flex items-center bg-white px-5 border-b border-[#D1D5DB]',
+ wrapperClassName,
+ !!error && 'border-system_red',
+ !error && !!value && 'border-black',
+ ),
+ }),
+ [wrapperClassName, error],
+ )
+
+ const getInputProps = useCallback(
+ () => ({
+ ...otherProps,
+ value: value ?? '',
+ ref: domRef,
+ className: cn(
+ 'bg-white my-15 h-full w-full focus:outline-none placeholder-primary_foundation_40',
+ otherProps.className,
+ ),
+ onChange: handleChangeValue,
+ }),
+ [domRef, handleChangeValue, otherProps, error],
+ )
+
+ const getClearButtonProps = useCallback(
+ () => ({
+ onClick: handleClear,
+ }),
+ [handleClear],
+ )
+
+ return {
+ handleClear,
+ getBaseProps,
+ getInputProps,
+ getClearButtonProps,
+ isClearable,
+ }
+}
diff --git a/src/components/common/index.tsx b/src/components/common/index.tsx
new file mode 100644
index 0000000..cd7ddde
--- /dev/null
+++ b/src/components/common/index.tsx
@@ -0,0 +1,3 @@
+export { default as Input } from './Input'
+export { default as Button } from './Button'
+export { default as If } from './If'
diff --git a/src/components/index.tsx b/src/components/index.tsx
new file mode 100644
index 0000000..7c4d588
--- /dev/null
+++ b/src/components/index.tsx
@@ -0,0 +1,2 @@
+export * from './Icons'
+export * from './common'
diff --git a/src/hooks/store/useUserInfo.ts b/src/hooks/store/useUserInfo.ts
new file mode 100644
index 0000000..23586cc
--- /dev/null
+++ b/src/hooks/store/useUserInfo.ts
@@ -0,0 +1,31 @@
+import { create } from 'zustand'
+
+interface UserInfoType {
+ name: string
+ gender: string
+ age: number | undefined
+ profileIcon?: string
+}
+
+interface UserInfoState {
+ userInfo: UserInfoType
+}
+
+interface UserInfoActions {
+ setUserInfo: (userinfo: UserInfoType) => void
+ deleteUserInfo: () => void
+}
+
+const defaultState = { name: '', gender: '', age: undefined, profileIcon: '1' }
+
+const useUserInfo = create((set) => ({
+ userInfo: defaultState,
+ setUserInfo: (userInfo: UserInfoType) => {
+ set({ userInfo })
+ },
+ deleteUserInfo: () => {
+ set({ userInfo: defaultState })
+ },
+}))
+
+export default useUserInfo
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 9f24d61..da01dba 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -27,8 +27,17 @@ const config: Config = {
theme: {
extend: {
colors: {
- background: 'var(--background)',
- foreground: 'var(--foreground)',
+ black: '#000',
+ white: '#fff',
+ system_red: '#FF5D5E',
+ system_blue: '#528DFF',
+ accent_100: '#FF4F38',
+ primary_foundation_40: '#A3A3A8',
+ primary_foundation_10: '#E9E9EA',
+ primary_foundation_50: '#8D8D92',
+ primary_foundation_60: '#76767C',
+ primary_foundation_30: '#BBBBBE',
+ primary_foundation_5: '#F3F3F4',
},
width: px0To500,
height: px0To500,