Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added src/assets/Archive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/Exclamation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/LayerLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions src/components/auth/AlertBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export default function AlertBox(props: {isVisible : boolean}){
if(props.isVisible){
return (
<div className="fixed top-0 z-10 block w-[100%] h-[100%] bg-[#140B0A73]">
<div className="flex flex-col justify-around items-stretch h-[100%]">
<center>
<div className="w-[260px] h-[123px] rounded-[16px] p-[24px] bg-[#FFFFFF]">
<h2 className="text-left text-[15px] text-[#201E1D] font-[600] mb-[14px]">모든 항목을 입력해주세요.</h2>
<button className="text-[14px] text-[#E1F5FE] font-[800] w-[210px] h-[39px] rounded-[9px] bg-[#3E2723]">확인</button>
</div>
</center>
</div>
</div>
);
}
}
2 changes: 1 addition & 1 deletion src/components/common/input/TextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function TextArea({
/>

<span className="self-end text-[11px] text-[#2A1F1C]/55">
{value.length} / {maxLength}
{value?.length} / {maxLength}
</span>
</div>
)
Expand Down
24 changes: 24 additions & 0 deletions src/components/onboarding/OnboardingComponentChange.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { onboardingComponentProps } from '@/pages/Onboarding'
import OnboardingPage1Component from '@/components/onboarding/OnboardingPage1Component'
import OnboardingPage2Component from '@/components/onboarding/OnboardingPage2Component'
import OnboardingPage3Component from '@/components/onboarding/OnboardingPage3Component'

export default function OnboardingComponentChange ({pageNumber, topic, setTopic, decision, setDecision, reason, setReason, selectedValue, setSelectedValue, selectedCategory, setSelectedCategory} : onboardingComponentProps) {
switch(pageNumber){
case 1: return <OnboardingPage1Component />
case 2: return <OnboardingPage2Component />
case 3: return <OnboardingPage3Component
pageNumber={pageNumber}
topic = {topic}
setTopic = {setTopic}
decision = {decision}
setDecision = {setDecision}
reason = {reason}
setReason = {setReason}
selectedValue = {selectedValue}
setSelectedValue = {setSelectedValue}
selectedCategory = {selectedCategory}
setSelectedCategory = {setSelectedCategory}
/>
}
}
14 changes: 14 additions & 0 deletions src/components/onboarding/OnboardingHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default function OnboardingHeader(props: { pageNumber:number; }) {
return (
<header className="h-[31px] px-7 flex items-end gap-2">
{[1, 2, 3].map((step) => (
<div
key={step}
className={`h-[3px] w-8 ${
step <= props.pageNumber ? 'bg-[#3E2723]' : 'bg-[#DDF0FA]'
}`}
/>
))}
</header>
)
}
30 changes: 30 additions & 0 deletions src/components/onboarding/OnboardingPage1Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export default function OnboardingPage1Component() {

return (
<div>
{/* nine blocks */}
<section className="mb-[23px]">
<div className="h-[34px]">
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-growth)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-stability)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-autonomy)]"></div>
</div>
<div className="h-[34px]">
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-connection)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-recognition)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-fun)]"></div>
</div>
<div className="h-[34px]">
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-efficiency)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-meaning)]"></div>
<div className="inline-block h-[28px] w-[28px] mr-[6px] mb-[6px] bg-[var(--color-responsibility)]"></div>
</div>
</section>
<section>
{/* content */}
<div className="text-[32px] font-[800] mb-[12px]">가치관을 묻지 않아요</div>
<div className="text-[15px] font-[400]">대신 지금 고민 중인 선택 하나만 물어볼게요.<br/>'당신의 가치'는 무엇인가는 묻지 않지만,<br/>구체적인 갈림길 앞에서는 누구나 이유를 둘 수 있으니까요.</div>
</section>
</div>
);
}
50 changes: 50 additions & 0 deletions src/components/onboarding/OnboardingPage2Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
export default function OnboardingPage2Component() {
return (
<div>
<h1 className="text-[32px] font-[800] text-[#201E1D] mb-[38px] ">고르고, 이유를 남기면</h1>
<section>
<div className="h-[64px]">
<div className="w-[10px] h-[64px] inline-block mr-[14px]">
<div className="w-[10px] h-[10px] bg-[#3E2723]"></div>
<div className="w-[2px] h-[54px] bg-[#3e2723] opacity-[22%] ml-[4px]"></div>
</div>
<div className="inline-block align-top">
<h3 className="text-[15px] font-[600] text-[#201E1D]">고민</h3>
<p className="text-[13px] font-[400] text-[#2A1F1C8C]">지금 하는 갈림길 하나를 이름 붙인다</p>
</div>
</div>
<div className="h-[64px]">
<div className="w-[10px] h-[64px] inline-block mr-[14px]">
<div className="w-[10px] h-[10px] bg-[#3E2723]"></div>
<div className="w-[2px] h-[54px] bg-[#3e2723] opacity-[22%] ml-[4px]"></div>
</div>
<div className="inline-block align-top">
<h3 className="text-[15px] font-[600] text-[#201E1D]">오늘의 판단</h3>
<p className="text-[13px] font-[400] text-[#2A1F1C8C]">오늘, 어느 쪽으로 마음이 갔는지</p>
</div>
</div>
<div className="h-[64px]">
<div className="w-[10px] h-[64px] inline-block mr-[14px]">
<div className="w-[10px] h-[10px] bg-[#3E2723]"></div>
<div className="w-[2px] h-[54px] bg-[#3e2723] opacity-[22%] ml-[4px]"></div>
</div>
<div className="inline-block align-top">
<h3 className="text-[15px] font-[600] text-[#201E1D]">이유</h3>
<p className="text-[13px] font-[400] text-[#2A1F1C8C]">한 줄이면 충분하다</p>
</div>
</div>
<div className="h-[64px]">
<div className="w-[10px] h-[64px] inline-block mr-[14px]">
<div className="w-[10px] h-[10px] bg-[#3E2723]"></div>
<div className="w-[2px] h-[54px] bg-[#3e2723] opacity-[22%] ml-[4px]"></div>
</div>
<div className="inline-block align-top">
<h3 className="text-[15px] font-[600] text-[#201E1D]">가치</h3>
<p className="text-[13px] font-[400] text-[#2A1F1C8C]">가장 가까운 것 하나만 고른다</p>
</div>
</div>
</section>
<p className="text-[13px] font-[400] text-[#2A1F1C8C] mt-[15px]">쌓일수록, 당신의 선택이 보여요.</p>
</div>
);
}
101 changes: 101 additions & 0 deletions src/components/onboarding/OnboardingPage3Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { useState, type ChangeEvent } from 'react'

import { onboardingComponentProps } from '@/pages/Onboarding'
import RecordValueButton from '@/components/common/button/RecordValueButton'
import TextArea from '@/components/common/input/TextArea'
import CategoryButton from '@/components/common/button/CategoryButton'

import { VALUE_LABELS, type ValueKey } from '@/constants/insights'
import { VALUE_DESCRIPTIONS } from '@/constants/values'



const VALUE_KEYS = Object.keys(VALUE_LABELS) as ValueKey[]

const CATEGORY_OPTIONS = [
{ value: 'work', title: '일·진로', description: '취업, 이직, 업무 판단' },
{
value: 'relationship',
title: '관계',
description: '친구, 연인, 가족, 동료',
},
{ value: 'money', title: '돈', description: '소비, 저축, 투자' },
{ value: 'health', title: '건강·몸', description: '운동, 수면, 컨디션' },
{ value: 'self', title: '나 자신', description: '성격, 원칙, 새로운 시도' },
{ value: 'etc', title: '기타', description: '위 어디에도 해당 없음' },
] as const

type CategoryValue = (typeof CATEGORY_OPTIONS)[number]['value']

export default function OnboardingPage3Component({pageNumber, topic, setTopic, decision, setDecision, reason, setReason, selectedValue, setSelectedValue, selectedCategory, setSelectedCategory} : onboardingComponentProps) {


return (
<>
<div>
<h1 className="text-[32px] font-[800] text-[#201E1D] mb-[13px] ">지금 고민,<br/>하나씩 적어볼까요?</h1>
<p className="text-[13px] font-[400] text-[#2A1F1C8C] mb-[20px]">아직 연습이예요. 편하게 가볍게 한 번 써볼까요?</p>
<div className="w-[344px] h-[64px] px-[16px] py-[14px] bg-[#DDF0FA] text-[12px] font-[400] text-[#201E1D] mb-[20px]">고민은 취업, 관계, 돈, 건강처럼 <b>영역</b>으로 나눠서 적어볼 수 있어요. 아래에서 골라보세요.</div>
</div>
<section className="flex w-[352px] flex-col gap-5 mb-[20px]">
<TextArea
label="무슨 고민인가요?"
placeholder="예: A사 vs B사"
value={topic}
onChange={(e) => setTopic(e.target.value)}
maxLength={50}
/>
</section>
Comment on lines +40 to +48

@seohyeon0219 seohyeon0219 Aug 14, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 고민, 오늘의 판단, 이유 입력창 모두 동일한 topic state를 value로 사용하고 있어, 한 입력창에 내용을 입력하면 세 입력창의 값이 동시에 변경됩니다.

각 입력 필드는 서로 다른 값을 관리해야 하므로 각각 별도의 state(또는 prop)로 분리해주세요.

// 현재 (잘못됨)
<TextArea value={topic} onChange={(e) => setTopic(e.target.value)} ... />
<TextArea value={topic} onChange={(e) => setTopic(e.target.value)} ... />
<TextArea value={topic} onChange={(e) => setTopic(e.target.value)} ... />


// 수정
<TextArea value={concern} onChange={(e) => setConcern(e.target.value)} ... />
<TextArea value={decision} onChange={(e) => setDecision(e.target.value)} ... />
<TextArea value={reason} onChange={(e) => setReason(e.target.value)} ... />

concern, decision, reason을 각각 독립적으로 관리하도록 수정 부탁드립니다!

<section className="flex w-[352px] flex-col gap-3 mb-[20px]">
<h2 className="text-[13px] text-[#2A1F1C]/70">이 고민은 어떤 영역인가요?</h2>
<div className="flex flex-col gap-2">
{CATEGORY_OPTIONS.map((option) => (
<CategoryButton
key={option.value}
title={option.title}
description={option.description}
isSelected={selectedCategory === option.value}
onClick={() => setSelectedCategory(option.value)}
/>
))}
</div>
</section>
<section className="flex w-[352px] flex-col gap-5 mb-[20px]">
<TextArea
label="오늘, 어떤 판단을 내렸나요?"
placeholder="예: 아직 못 정함/ A로 마음이 기움"
value={decision}
onChange={(e) => setDecision(e.target.value)}
maxLength={50}
/>
</section>
<div className="w-[344px] h-[64px] px-[16px] py-[14px] bg-[#DDF0FA] text-[12px] font-[400] text-[#201E1D] mb-[20px]">이유는 '성장', '안정', '재미'처럼 9가지 <b>가치</b> 중 가장 가까운 하나로 정리돼요.</div>

<section className="flex w-[352px] flex-col gap-5 mb-[20px]">
<TextArea
label="그건 왜인가요? "
placeholder="한 줄이면 충분해요"
value={reason}
onChange={(e) => setReason(e.target.value)}
maxLength={100}
rows={3}
/>
</section>
<section className="flex w-[352px] flex-col gap-3 mb-[20px]">
<h2 className="text-[13px] text-[#2A1F1C]/70">방금 그 이유, 가장 가까운 하나는?</h2>
<div className="flex flex-col gap-2">
{VALUE_KEYS.map((key) => (
<RecordValueButton
key={key}
valueKey={key}
title={VALUE_LABELS[key]}
description={VALUE_DESCRIPTIONS[key]}
isSelected={selectedValue === key}
onClick={() => setSelectedValue(key)}
/>
))}
</div>
</section>
</>
);
}
51 changes: 51 additions & 0 deletions src/components/settings/DeleteAccount.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Dispatch, SetStateAction } from 'react';

export default function DeleteAccount(props: {
isVisible : boolean;
deleteAccountShow: boolean,
setDeleteAccountShow:Dispatch<SetStateAction<boolean>>,
deleteAccountAlertShow : boolean,
setDeleteAccountAlertShow : Dispatch<SetStateAction<boolean>>,
}){

const DeleteAccountShow = () =>{
if(props.deleteAccountShow == false){
props.setDeleteAccountShow(true);
}
else{
props.setDeleteAccountShow(false);
}
}

const DeleteAccountAlertShow = () =>{
if(props.deleteAccountAlertShow == false){
props.setDeleteAccountShow(false);
props.setDeleteAccountAlertShow(true);
}
else{
props.setDeleteAccountShow(true);
props.setDeleteAccountAlertShow(false);
}
}

if(props.isVisible){
return (
<div className="fixed top-0 z-10 block w-[100%] h-[100%] bg-[#140B0A73]">
<div className="flex flex-col justify-around items-stretch h-[100%]">
<center>
<div className="w-[280px] h-[300px] rounded-[16px] p-[24px] bg-[#FFFFFF]">
<h2 className="text-left text-[16px] text-[#201E1D] font-[700] mb-[14px]">정말 탈퇴하시겠어요?</h2>
<p className="text-left text-[13px] text-[#2A1F1CCC] font-[400] mb-[14px]" >회원 탈퇴 시 아래 데이터가 모두 삭제됩니다.</p>
<p className="text-left text-[13px] text-[#201E1D] font-[400] mb-[14px]">&bull;&nbsp; 고민 및 기록 <br />&bull;&nbsp; 가치 분포 및 인사이트 <br />&bull;&nbsp; 계정 정보</p>
<p className="text-left text-[13px] text-[#2A1F1C99] font-[400] mb-[14px]">삭제된 데이터는 복구할 수 없습니다.</p>
<div>
<button onClick={DeleteAccountShow} className="border-[1px] border-[#201E1D66] font-[14px] text-[#2A1F1C] font-[800] w-[112px] h-[39px] rounded-[9px] bg-[#FFF] mr-[8px]">취소</button>
<button onClick={DeleteAccountAlertShow} className="font-[14px] text-[#FFF] font-[800] w-[112px] h-[39px] rounded-[9px] bg-[#E5342A]">탈퇴하기</button>
</div>
</div>
</center>
</div>
</div>
);
}
}
21 changes: 21 additions & 0 deletions src/components/settings/DeleteAccountAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Dispatch, SetStateAction } from 'react';

export default function DeleteAccountAlert(props: {
isVisible : boolean,
}){
if(props.isVisible){
return (
<div className="fixed top-0 z-10 block w-[100%] h-[100%] bg-[#140B0A73]">
<div className="flex flex-col justify-around items-stretch h-[100%]">
<center>
<div className="w-[280px] h-[180px] rounded-[16px] p-[24px] bg-[#FFFFFF]">
<h2 className="text-[15px] text-[#201E1D] font-[600] mb-[17px]">회원 탈퇴가 완료되었습니다.</h2>
<p className="text-[13px] text-[#2A1F1CCC] font-[400] mb-[30px]">그동안 Layer를 이용해주셔서 감사합니다.</p>
<button className="text-[14px] text-[#FFF] font-[800] w-[210px] h-[39px] rounded-[9px] bg-[#3E2723]">확인</button>
</div>
</center>
</div>
</div>
);
}
}
Loading