Skip to content

Commit

Permalink
Merge pull request #50 from sangmaaaaan/Feat/onboarding
Browse files Browse the repository at this point in the history
[User] Feat: onboarding modal 구현
  • Loading branch information
sangmaaaaan authored Sep 10, 2024
2 parents a9ce818 + 2e3cd71 commit 210cc8e
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 6 deletions.
3 changes: 1 addition & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@vercel/analytics": "^1.3.1",
"antd": "^5.19.0",
"axios": "^1.7.2",
"chromatic": "^11.5.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"eslint": "^8.57.0",
Expand Down Expand Up @@ -76,7 +77,6 @@
"@storybook/react-webpack5": "^8.1.10",
"@storybook/test": "^8.1.10",
"@typescript-eslint/parser": "^5.62.0",
"chromatic": "^11.5.4",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.34.3",
Expand Down
160 changes: 160 additions & 0 deletions src/assets/maru-egg.svg
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/onboarding_0.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/onboarding_1.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/onboarding_2.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/onboarding_3.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/onboarding_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
113 changes: 113 additions & 0 deletions src/ui/components/molecule/onboarding/onboarding.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, { useState } from 'react';
import onboarding_0 from '../../../../assets/onboarding_0.png';
import onboarding_1 from '../../../../assets/onboarding_1.png';
import onboarding_2 from '../../../../assets/onboarding_2.png';
import onboarding_3 from '../../../../assets/onboarding_3.png';
import onboarding_4 from '../../../../assets/onboarding_4.png';

interface OnboardingProps {
onClose: () => void;
}

const Onboarding = ({ onClose }: OnboardingProps) => {
const [step, setStep] = useState(0);

const steps = [
{
image: onboarding_0,
title: '명지대학교 AI 입학문의 챗봇,',
subtitle: '마루에그에 오신 것을 환영합니다!',
description: '1분만에 마루에그의 모든 기능을 알려드려요',
button1Text: '건너뛰기',
button2Text: '시작하기',
},
{
image: onboarding_1,
title: '수시/정시/편입 타입 지정',
subtitle: '',
description: '클릭 1번으로 필요한 입력 정보를 알려드려요',
button1Text: '건너뛰기',
button2Text: '다음',
},
{
image: onboarding_2,
title: 'FAQ · 입시결과 · 모집요강 바로가기',
subtitle: '',
description: '자주 가는 페이지는 빠르게 접근할 수 있도록 만들었어요',
button1Text: '건너뛰기',
button2Text: '다음',
},
{
image: onboarding_3,
title: '모집요강에 있는 정보들을 한번에',
subtitle: '',
description: '질문을 하며 참고할 수 있는 정보를 한곳에 모아놨어요',
button1Text: '건너뛰기',
button2Text: '다음',
},
{
image: onboarding_4,
title: '질문내용에 적합한 참고자료도 함께',
subtitle: '',
description: '질문을 하며 참고할 수 있는 자료들을 함께 알려드려요',
button1Text: '건너뛰기',
button2Text: '다음',
},
{
image: onboarding_0,
title: '마루에그와 함께 입학문의로 보다 쉽게',
subtitle: '',
description: '마루에그에 대한 정보가 더 궁금하다면?',
button1Text: '다시보기',
button2Text: '문의하러 가기',
},
];

const handleNext = () => {
if (step < steps.length - 1) {
setStep(step + 1);
} else {
onClose();
}
};

const handleRestart = () => {
setStep(0);
};

return (
<div className="absolute z-30 flex h-full w-full items-center justify-center bg-black bg-opacity-40 mobile:rounded-none desktop:rounded-3xl">
<div className="relative h-[411px] w-[324px] items-center justify-center rounded-2xl bg-white">
<div className="flex flex-col">
{/* Image */}
<div className="flex h-[232px] w-full items-center justify-center rounded-b-none rounded-t-2xl bg-[#DFE5EE]">
<img src={steps[step].image} alt="onboarding-step" className="object-contain" />
</div>
{/* Text */}
<div className="space-y-1 py-8">
<p className="text-center font-pretendard text-sm font-medium">
{steps[step].title}
<br />
{steps[step].subtitle}
</p>
<p className="text-center font-pretendard text-xs font-normal text-[#8B8B8B]">{steps[step].description}</p>
</div>
{/* CTA */}
<div className="absolute bottom-0 flex w-full items-center justify-between rounded-b-2xl bg-white">
<button
onClick={step === steps.length - 1 ? handleRestart : onClose}
className="w-2/5 rounded-bl-2xl bg-[#ECECEC] p-5"
>
<p className="font-pretendard text-sm font-medium text-[#747474]">{steps[step].button1Text}</p>
</button>
<button onClick={handleNext} className="w-3/5 rounded-br-2xl bg-primary-blue p-5">
<p className="font-pretendard text-sm font-medium text-white">{steps[step].button2Text}</p>
</button>
</div>
</div>
</div>
</div>
);
};

export default Onboarding;
20 changes: 18 additions & 2 deletions src/ui/pages/maru-egg.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
// src/ui/pages/maru-egg.tsx
import React from 'react';
import React, { useEffect, useState } from 'react';
import Header from '../components/molecule/header/header';
import useTypeStore from '../../store/type-category-store';
import ChatForm from '../components/molecule/chat-form/chat-form';
import ChatSection from '../components/molecule/chat-section/chat-section';
import Onboarding from '../components/molecule/onboarding/onboarding';

const MaruEgg: React.FC = () => {
const { type, category } = useTypeStore();
const [showOnboarding, setShowOnboarding] = useState(false);

useEffect(() => {
const isFirstVisit = localStorage.getItem('isFirstVisit') === null;
if (isFirstVisit) {
setShowOnboarding(true);
localStorage.setItem('isFirstVisit', 'false');
} else {
setShowOnboarding(false);
}
}, []);

const handleCloseOnboarding = () => {
setShowOnboarding(false);
};

return (
<div className="flex h-svh items-center justify-center bg-gray-100">
<div className="relative flex h-full w-full bg-background-default mobile:h-full mobile:min-h-[480px] mobile:min-w-[320px] mobile:rounded-none desktop:h-[780px] desktop:max-w-[390px] desktop:rounded-3xl desktop:border desktop:border-gray-200 desktop:shadow-2xl">
{showOnboarding && <Onboarding onClose={handleCloseOnboarding} />}
<Header type={type} />

<ChatSection />
{type !== undefined && category !== undefined && (
<div className="absolute bottom-0 w-full bg-white px-3 py-3 mobile:rounded-none desktop:rounded-bl-3xl desktop:rounded-br-3xl">
Expand Down
1 change: 0 additions & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ module.exports = {
'background-default': '#F2F2F3',
},
screens: {
'mobile_sm' : '320px',
'mobile' : '360px',
'desktop' : '769px',
},
Expand Down

0 comments on commit 210cc8e

Please sign in to comment.