Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] 구글 로그인 회원가입 및 온보딩 페이지 구현 #20

Merged
merged 35 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4da2f7a
feat: 더미 사이드바 UI 구현
cobocho Jun 10, 2024
2f2cda3
feat: `Input` 컴포넌트 구현
cobocho Jun 10, 2024
52b7129
feat: `Checkbox` 구현
cobocho Jun 10, 2024
c71632d
feat: 회원가입 Form UI 구현
cobocho Jun 10, 2024
4baf1b3
feat: 로그인 Form 구현
cobocho Jun 10, 2024
4080d49
feat: 로그인 페이지 및 리다이렉트 구현
cobocho Jun 11, 2024
0315137
docs: 이용 약관 작성
cobocho Jun 11, 2024
31cb04b
feat: 회원가입 폼 UI 디자인 구현
cobocho Jun 11, 2024
33c106b
feat: 회원가입 서버 통신 로직 구현
cobocho Jun 11, 2024
b0f04ad
feat: 폼 제출간 로딩 구현
cobocho Jun 11, 2024
a662d68
feat: 온보딩 페이지 기초 레이아웃 구성
cobocho Jun 11, 2024
098b9f2
feat: 온보딩 페이지 UI 구현
cobocho Jun 11, 2024
7117efb
feat: 온보딩 네트워크 통신 로직 구현
cobocho Jun 11, 2024
dd0e1c3
feat: 유효성 검사 로직 일부 구현
cobocho Jun 11, 2024
69461cc
feat: 로그인 페이지 권한 검사 미들웨어 구현
cobocho Jun 11, 2024
45777ec
refactor: 미들웨어 추상화
cobocho Jun 11, 2024
f973b81
feat: 토큰 만료에 따른 refresh 로직 추가
cobocho Jun 11, 2024
3a8339a
docs: 개인정보 처리방침 작성
cobocho Jun 11, 2024
7d220b0
fix: 이용약관 및 개인정보 처리 방침 수정
cobocho Jun 11, 2024
592616f
refactor: 메인 페이지 기본 딜레이 시간을 공용 함수에서 제거
cobocho Jun 12, 2024
96afdb4
refactor: 권한 관리 미들웨어 리팩토링
cobocho Jun 12, 2024
6ea7301
chore: 미사용 빌드 타임 스탬프 제거
cobocho Jun 12, 2024
c3fffe9
fix: 스토리북 패키지 의존성 수정
cobocho Jun 12, 2024
cfc5553
fix: chromatic 워크플로우 수정
cobocho Jun 12, 2024
03d2134
chore: `SignUpForm` 스토리 제거
cobocho Jun 12, 2024
c3886d2
feat: 스토리북에 msw 추가
cobocho Jun 12, 2024
43e2859
refactor: 테스트 환경 분리
cobocho Jun 12, 2024
3ea86a5
test: 유효성 검사 테스트 작성
cobocho Jun 12, 2024
6dceab0
test: 퍼널 페이지 테스트 및 스토리 작성
cobocho Jun 12, 2024
ce2d017
design: 스토리북 커스터마이징
cobocho Jun 12, 2024
d32e452
fix: 스토리북 데코레이터를 워크샵에서 관리하도록 수정
cobocho Jun 12, 2024
b32c5a0
fix: 에러 발생하는 스토리 빌드 제외
cobocho Jun 12, 2024
2ecec55
fix: 스토리북 환경에서의 `prefetch` 비활성화
cobocho Jun 13, 2024
19beb0b
refactor: `Storybook` 에러 해결을 위한 `Link` 래퍼 구현
cobocho Jun 13, 2024
6019afd
fix: 온보딩 뒤로 가기 제거
cobocho Jun 13, 2024
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
4 changes: 4 additions & 0 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ jobs:
run: pnpm install -no-frozen-lockfile
working-directory: apps/workshop

- name: Build Design System Package
run: pnpm run build
working-directory: packages/design-system

- name: Publish Chromatic
id: chromatic
uses: chromaui/action@latest
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"liveServer.settings.port": 5501
}
25 changes: 17 additions & 8 deletions apps/extension/components/TermItem/TermItem.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,27 @@ const meta = {
'<strong>서버</strong>는 네트워크에 연결된 컴퓨터로 클라이언트의 요청을 받아 처리하고 결과를 응답으로 보냅니다. 웹 <strong>서버</strong>, 데이터 베이스 <strong>서버</strong>, 메일 <strong>서버</strong> 등이 <strong>서버</strong>에 속합니다.',
},
},
decorators: [
(Story) => (
<div style={{ width: '600px' }}>
<Story />
</div>
),
],
argTypes: {
term: {
control: {
type: 'object',
},
},
},
tags: ['autodocs'],
} satisfies Meta<typeof TermItem>

export default meta

type Story = StoryObj<typeof meta>

export const Preview: Story = {}
export const Preview: Story = {
args: {
term: {
term: '<strong>서버</strong>',
synonyms: 'Server',
meaning:
'<strong>서버</strong>는 네트워크에 연결된 컴퓨터로 클라이언트의 요청을 받아 처리하고 결과를 응답으로 보냅니다. 웹 <strong>서버</strong>, 데이터 베이스 <strong>서버</strong>, 메일 <strong>서버</strong> 등이 <strong>서버</strong>에 속합니다.',
},
},
}
1 change: 1 addition & 0 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@types/node": "^20.11.24",
"@types/react": "^18.2.61",
"@types/react-dom": "^18.2.19",
"@vitejs/plugin-react": "^4.3.1",
"@vitest/ui": "^1.6.0",
"@vook-client/eslint-config": "*",
"eslint": "^8.57.0",
Expand Down
3 changes: 3 additions & 0 deletions apps/web/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
NEXT_PUBLIC_DOMAIN=http://localhost:3000
NEXT_PUBLIC_API_URL=https://dev.vook-api.seungyeop-lee.com
NEXT_PUBLIC_GOOGLE_LOGIN_URL=https://dev.vook-api.seungyeop-lee.com/oauth2/authorization/google
2 changes: 2 additions & 0 deletions apps/web/.env.staging
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
NEXT_PUBLIC_DOMAIN=https://stag.vook.seungyeop-lee.com
NEXT_PUBLIC_API_URL=https://stag.vook-api.seungyeop-lee.com
NEXT_PUBLIC_GOOGLE_LOGIN_URL=https://stag.vook-api.seungyeop-lee.com/oauth2/authorization/google
20 changes: 18 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,52 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint . --max-warnings 0"
"lint": "eslint . --max-warnings 0",
"test": "vitest"
},
"dependencies": {
"@hookform/resolvers": "^3.6.0",
"@tanstack/react-query": "^5.32.0",
"@types/js-cookie": "^3.0.6",
"@vanilla-extract/css": "^1.14.2",
"@vanilla-extract/css-utils": "^0.1.3",
"@vanilla-extract/dynamic": "^2.1.0",
"@vanilla-extract/recipes": "^0.5.2",
"@vanilla-extract/sprinkles": "^1.6.1",
"@vook-client/api": "*",
"@vook-client/design-system": "*",
"js-cookie": "^3.0.5",
"next": "^14.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.5",
"vite-tsconfig-paths": "^4.3.2",
"zod": "^3.23.8",
"zustand": "^4.5.2"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.1.1",
"@storybook/react": "^8.0.10",
"@storybook/test": "^8.0.10",
"@tanstack/react-query-devtools": "^5.32.0",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.5",
"@testing-library/user-event": "^14.5.2",
"@types/eslint": "^8.56.5",
"@types/node": "^20.11.24",
"@types/react": "^18.2.61",
"@types/react-dom": "^18.2.19",
"@vanilla-extract/next-plugin": "^2.4.0",
"@vanilla-extract/vite-plugin": "^4.0.9",
"@vanilla-extract/webpack-plugin": "^2.3.7",
"@vitejs/plugin-react": "^4.3.1",
"@vook-client/eslint-config": "*",
"@vook-client/typescript-config": "*",
"clsx": "^2.1.1",
"eslint": "^8.57.0"
"dotenv": "^16.4.5",
"eslint": "^8.57.0",
"jsdom": "^24.0.0",
"msw": "^2.3.1",
"vitest": "^1.5.2"
}
}
29 changes: 29 additions & 0 deletions apps/web/setupTests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import '@testing-library/jest-dom'
import { handlers } from '@vook-client/api'
import { setupServer } from 'msw/node'
import { cleanup } from '@testing-library/react'
import { afterEach } from 'vitest'

const mswServer = setupServer(...handlers)

vi.mock('next/font/local', () => {
return {
default: () => {},
}
})

vi.mock('next/navigation', () => ({
useRouter() {
return {
prefetch: () => null,
}
},
}))

afterEach(() => {
cleanup()
})

beforeAll(() => mswServer.listen())

afterAll(() => mswServer.close())
7 changes: 7 additions & 0 deletions apps/web/src/app/(afterLogin)/layout.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { style } from '@vanilla-extract/css'

import { SIDE_BAR_WIDTH } from '@/styles/layout'

export const mainArea = style({
marginLeft: SIDE_BAR_WIDTH,
})
16 changes: 16 additions & 0 deletions apps/web/src/app/(afterLogin)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { PropsWithChildren } from 'react'

import { Sidebar } from '@/components/Sidebar'

import { mainArea } from './layout.css'

const Layout = ({ children }: PropsWithChildren) => {
return (
<div className={mainArea}>
<Sidebar />
{children}
</div>
)
}

export default Layout
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ import { Term } from '@/components/Term/Term'

const Home = () => {
return (
<main className={main}>
<div className={main}>
<Header />

<div style={{ flex: 1 }}>
<Search />
<Term />
</div>

<Footer />
</main>
</div>
)
}

Expand Down
48 changes: 48 additions & 0 deletions apps/web/src/app/(beforeLogin)/auth/token/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client'

import { userInfoService, UserStatus } from '@vook-client/api'
import Cookies from 'js-cookie'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

interface AuthCallbackQueryParams {
searchParams: {
access: string
refresh: string
}
}

const AuthCallbackPage = ({
searchParams: { access, refresh },
}: AuthCallbackQueryParams) => {
const router = useRouter()

useEffect(() => {
Cookies.set('access', access, {
secure: true,
})
Cookies.set('refresh', refresh, {
secure: true,
})

const checkUserRegistered = async () => {
const userInfo = await userInfoService.getUserInfo({
access,
refresh,
})
const isRegistered = userInfo.result.status === UserStatus.Registered

if (isRegistered) {
router.push('/')
return
}
router.push('/signup')
}

checkUserRegistered()
}, [access, refresh, router])

return null
}

export default AuthCallbackPage
10 changes: 10 additions & 0 deletions apps/web/src/app/(beforeLogin)/login/layout.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { style } from '@vanilla-extract/css'

export const loginLayout = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',

width: '100dvw',
height: '100dvh',
})
9 changes: 9 additions & 0 deletions apps/web/src/app/(beforeLogin)/login/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { PropsWithChildren } from 'react'

import { loginLayout } from './layout.css'

const Layout = ({ children }: PropsWithChildren) => {
return <div className={loginLayout}>{children}</div>
}

export default Layout
5 changes: 5 additions & 0 deletions apps/web/src/app/(beforeLogin)/login/page.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { style } from '@vanilla-extract/css'

export const loginFormArea = style({
width: 380,
})
15 changes: 15 additions & 0 deletions apps/web/src/app/(beforeLogin)/login/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'

import { LoginForm } from '@/components/LoginForm'

import { loginFormArea } from './page.css'

const LoginPage = () => {
return (
<div className={loginFormArea}>
<LoginForm />
</div>
)
}

export default LoginPage
10 changes: 10 additions & 0 deletions apps/web/src/app/(beforeLogin)/signup/layout.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { style } from '@vanilla-extract/css'

export const loginLayout = style({
display: 'flex',
justifyContent: 'center',
alignItems: 'center',

width: '100dvw',
height: '100dvh',
})
9 changes: 9 additions & 0 deletions apps/web/src/app/(beforeLogin)/signup/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { PropsWithChildren } from 'react'

import { loginLayout } from './layout.css'

const Layout = ({ children }: PropsWithChildren) => {
return <div className={loginLayout}>{children}</div>
}

export default Layout
5 changes: 5 additions & 0 deletions apps/web/src/app/(beforeLogin)/signup/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Loading = () => {
return <div />
}

export default Loading
5 changes: 5 additions & 0 deletions apps/web/src/app/(beforeLogin)/signup/page.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { style } from '@vanilla-extract/css'

export const signupForm = style({
width: 380,
})
13 changes: 13 additions & 0 deletions apps/web/src/app/(beforeLogin)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SignUpForm } from '@/components/SignUpForm'

import { signupForm } from './page.css'

const SignUpPage = () => {
return (
<div className={signupForm}>
<SignUpForm />
</div>
)
}

export default SignUpPage
6 changes: 6 additions & 0 deletions apps/web/src/app/(beforeLogin)/terms/layout.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { style } from '@vanilla-extract/css'

export const termsLayout = style({
width: 780,
margin: '30px auto',
})
9 changes: 9 additions & 0 deletions apps/web/src/app/(beforeLogin)/terms/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { PropsWithChildren } from 'react'

import { termsLayout } from './layout.css'

const Layout = ({ children }: PropsWithChildren) => {
return <div className={termsLayout}>{children}</div>
}

export default Layout
Loading
Loading