-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[FEAT] 온보딩 퍼블리싱 및 동작 구현
- Loading branch information
Showing
30 changed files
with
576 additions
and
49 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
const FinishScreen = () => { | ||
return <div>FinishScreen</div>; | ||
}; | ||
|
||
export default FinishScreen; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import styled from "styled-components"; | ||
|
||
export const ProgressBarWrapper = styled.div` | ||
display: flex; | ||
align-items: center; | ||
width: 100%; | ||
height: 14px; | ||
border-radius: 20px; | ||
background: #ededed; | ||
margin-top: 2rem; | ||
position: relative; | ||
`; | ||
|
||
export const Progress = styled.div<{ $percentage: number }>` | ||
background-color: #ffd600; | ||
border-top-left-radius: 20px; | ||
border-bottom-left-radius: 20px; | ||
border-top-right-radius: ${(props) => (props.$percentage >= 99 ? 20 : 0)}px; | ||
border-bottom-right-radius: ${(props) => | ||
props.$percentage >= 99 ? 20 : 0}px; | ||
height: 100%; | ||
width: ${(props) => props.$percentage}%; | ||
transition: width 0.5s ease-in-out; | ||
position: relative; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import * as S from "./ProgressBar.styeld"; | ||
|
||
interface ProgressBarProps { | ||
percentage: number; | ||
} | ||
|
||
const ProgressBar = (props: ProgressBarProps) => { | ||
return ( | ||
<S.ProgressBarWrapper> | ||
<S.Progress $percentage={props.percentage} /> | ||
</S.ProgressBarWrapper> | ||
); | ||
}; | ||
|
||
export default ProgressBar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { SelectBtnProps } from "@type/selectList"; | ||
import * as S from "./SelectOptionList.styled"; | ||
import { colorSets } from "@utils/defaultData"; | ||
|
||
const SelectBtn = (props: SelectBtnProps) => { | ||
const colorSet = colorSets[props.colorName]; | ||
|
||
return ( | ||
<S.SelectBtnWrapper $colorSet={colorSet} onClick={props.onClick}> | ||
{props.text} | ||
{props.imgURL && <S.SelectIcon src={props.imgURL} alt="선택지" />} | ||
</S.SelectBtnWrapper> | ||
); | ||
}; | ||
|
||
export default SelectBtn; |
35 changes: 35 additions & 0 deletions
35
src/components/common/selectOption/SelectOptionList.styled.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { ColorSet } from "@type/selectList"; | ||
import styled from "styled-components"; | ||
|
||
export const SelectOptionContainer = styled.div<{ width?: string }>` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
position: relative; | ||
gap: 1rem; | ||
width: ${({ width }) => (width ? width : "100%")}; | ||
`; | ||
|
||
export const SelectBtnWrapper = styled.div<{ $colorSet: ColorSet }>` | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
padding: 0 1.5rem; | ||
box-sizing: border-box; | ||
width: 100%; | ||
height: 5rem; | ||
font-size: 2rem; | ||
font-weight: 700; | ||
background-color: ${({ $colorSet }) => $colorSet.background}; | ||
color: ${({ $colorSet }) => $colorSet.color}; | ||
border: 1px solid ${({ $colorSet }) => $colorSet.border}; | ||
border-radius: 6px; | ||
`; | ||
|
||
export const SelectIcon = styled.img` | ||
width: 2.3rem; | ||
height: 2.3rem; | ||
margin-right: 10px; | ||
vertical-align: middle; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { SelectListProps } from "@type/selectList"; | ||
import SelectBtn from "./SelectBtn"; | ||
import * as S from "./SelectOptionList.styled"; | ||
|
||
const SelectOptionList = (props: SelectListProps) => { | ||
const getColorName = (state: string) => { | ||
switch (state) { | ||
case "correct": | ||
return "green"; | ||
case "wrong": | ||
return "red"; | ||
case "selected": | ||
return "yellow"; | ||
case "default": | ||
default: | ||
return "gray"; | ||
} | ||
}; | ||
|
||
const getImgURL = (state: string) => { | ||
switch (state) { | ||
case "correct": | ||
return "/correct.png"; | ||
case "wrong": | ||
return "/wrong.png"; | ||
case "selected": | ||
return ""; | ||
default: | ||
return ""; | ||
} | ||
}; | ||
|
||
const handleSelect = (value: string | number | null) => { | ||
props.setter(value); | ||
}; | ||
|
||
return ( | ||
<S.SelectOptionContainer width={props.width}> | ||
{props.selectList.map((element) => ( | ||
<SelectBtn | ||
key={element.text} | ||
text={element.text} | ||
colorName={getColorName(element.state)} | ||
imgURL={getImgURL(element.state)} | ||
onClick={() => handleSelect(element.value)} | ||
/> | ||
))} | ||
</S.SelectOptionContainer> | ||
); | ||
}; | ||
|
||
export default SelectOptionList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { colorSets } from "@utils/defaultData"; | ||
import React, { ChangeEvent, KeyboardEvent } from "react"; | ||
import styled from "styled-components"; | ||
|
||
interface AgeInputProps { | ||
age: string | number | null; | ||
setter: (value: number | null) => void; | ||
} | ||
|
||
const AgeInput = ({ age, setter }: AgeInputProps) => { | ||
const [isEditing, setIsEditing] = React.useState<boolean>(false); | ||
|
||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => { | ||
const value = event.target.value; | ||
const newValue = value === "" ? null : Number(value); | ||
setter(newValue); | ||
}; | ||
|
||
const handleBlur = () => { | ||
setIsEditing(false); | ||
}; | ||
|
||
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => { | ||
if (event.key === "Enter") { | ||
setIsEditing(false); | ||
} | ||
}; | ||
|
||
return ( | ||
<Container $age={age}> | ||
{isEditing ? ( | ||
<Input | ||
type="number" | ||
value={age ?? ""} | ||
onChange={handleChange} | ||
onBlur={handleBlur} | ||
onKeyDown={handleKeyDown} | ||
autoFocus | ||
/> | ||
) : ( | ||
<Text onClick={() => setIsEditing(true)}> | ||
{age !== null ? `만 ${age}세` : "만"} | ||
</Text> | ||
)} | ||
</Container> | ||
); | ||
}; | ||
|
||
export default AgeInput; | ||
|
||
const Container = styled.div<{ $age?: any }>` | ||
display: flex; | ||
align-items: center; | ||
padding: 0 1rem; | ||
box-sizing: border-box; | ||
width: 50%; | ||
height: 4.5rem; | ||
font-size: 2rem; | ||
font-weight: 700; | ||
border: 1px solid | ||
${({ $age }) => | ||
$age ? colorSets["yellow"].border : colorSets["gray"].border}; | ||
background-color: ${({ $age }) => | ||
$age ? colorSets["yellow"].background : "none"}; | ||
border-radius: 6px; | ||
position: relative; | ||
`; | ||
|
||
const Text = styled.div` | ||
cursor: pointer; | ||
width: 100%; | ||
line-height: 4.5rem; | ||
padding: 0 1rem; | ||
`; | ||
|
||
const Input = styled.input` | ||
font-size: 2rem; | ||
width: 100%; | ||
box-sizing: border-box; | ||
padding: 0 1.5rem; | ||
border: none; | ||
border-radius: 6px; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
height: 100%; | ||
background-color: transparent; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import AgeInput from "./AgeInput"; | ||
import * as S from "./onboarding.styled"; | ||
|
||
interface SelectAgeProps { | ||
age: string | number | null; | ||
setter: (value: string | number | null) => void; | ||
} | ||
|
||
const SelectAge = ({ age, setter }: SelectAgeProps) => { | ||
return ( | ||
<S.Container> | ||
<S.Title>학습자의 나이는 몇살인가요?</S.Title> | ||
<S.SubContainer> | ||
<S.SubTitle>만 나이</S.SubTitle> | ||
<AgeInput age={age} setter={setter} /> | ||
</S.SubContainer> | ||
</S.Container> | ||
); | ||
}; | ||
|
||
export default SelectAge; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Dropdown from "@components/common/dropDown/Dropdown"; | ||
import * as S from "./onboarding.styled"; | ||
import { nationElements } from "@utils/defaultData"; | ||
|
||
interface SelectLanguageProps { | ||
setter: (value: string | number | null) => void; | ||
} | ||
|
||
const SelectLanguage = ({ setter }: SelectLanguageProps) => { | ||
return ( | ||
<S.Container> | ||
<S.Title>어떤 언어를 배우시나요?</S.Title> | ||
<S.SubContainer> | ||
<S.SubTitle>언어</S.SubTitle> | ||
<Dropdown selectList={nationElements} setter={setter} /> | ||
</S.SubContainer> | ||
</S.Container> | ||
); | ||
}; | ||
|
||
export default SelectLanguage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import * as S from "./onboarding.styled"; | ||
import useSelectLevel from "@hooks/useSelectLevel"; | ||
import { nationElements } from "@utils/defaultData"; | ||
import SelectOptionList from "@common/selectOption/SelectOptionList"; | ||
|
||
interface SelectLevelProps { | ||
languageId: number | string; | ||
setter: (value: string | number | null) => void; | ||
} | ||
|
||
const SelectLevel = ({ languageId, setter }: SelectLevelProps) => { | ||
const { selectedLevel, setSelectedLevel, levelOptions } = useSelectLevel(); | ||
const language = nationElements.find( | ||
(element) => element.value === languageId | ||
); | ||
|
||
const handleOptionChange = (value: string | number | null) => { | ||
setSelectedLevel(value); | ||
setter(value); | ||
}; | ||
|
||
return ( | ||
<S.Container> | ||
<S.Title>{language?.text}를 얼마나 알고 계신가요?</S.Title> | ||
<S.SubContainer> | ||
<SelectOptionList | ||
selectList={levelOptions.map((option) => ({ | ||
text: option.text, | ||
value: option.value, | ||
state: selectedLevel === option.value ? "selected" : "default", | ||
}))} | ||
setter={handleOptionChange} | ||
/> | ||
</S.SubContainer> | ||
</S.Container> | ||
); | ||
}; | ||
|
||
export default SelectLevel; |
Oops, something went wrong.