Skip to content

Commit

Permalink
feat: invite (#298)
Browse files Browse the repository at this point in the history
  • Loading branch information
rabyeoljji authored Dec 5, 2024
1 parent b6c8181 commit 260a562
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 2 deletions.
Binary file added public/images/invite-letter.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 public/images/no-invite-letter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions src/app/(routes)/invite/[code]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { FunctionComponent, PropsWithChildren } from 'react'
import type { Metadata } from 'next'
import Icon from '@/shared/components/custom/icon'

export const metadata: Metadata = {}

interface LayoutProps extends PropsWithChildren {}

const Layout: FunctionComponent<LayoutProps> = ({ children }) => {
return (
<>
<header className="flex h-[54px] w-full max-w-mobile items-center justify-between bg-background-base-02 px-[18px]">
<Icon name="logo" className="h-[36px]" />
</header>
{children}
</>
)
}

export default Layout
24 changes: 24 additions & 0 deletions src/app/(routes)/invite/[code]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import AvailableInviteView from '@/features/invite/screen/available-invite'
import UnavailableInviteView from '@/features/invite/screen/unavailable-invite'

interface Props {
params: {
code: string
}
}

const InvitePage = ({ params }: Props) => {
const code = params.code
// 링크 유효기간 체크
// 유효성에 따라 다른 page view 보여주기
const isValid = false

return (
<main className="flex h-[calc(100dvh-54px)] w-full flex-col items-center overflow-y-auto overflow-x-hidden bg-background-base-02 px-[43px] scrollbar-hide">
{isValid ? <AvailableInviteView code={code} /> : <UnavailableInviteView />}
</main>
)
}

export default InvitePage
20 changes: 20 additions & 0 deletions src/app/(routes)/invite/sign-up/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { FunctionComponent, PropsWithChildren } from 'react'
import type { Metadata } from 'next'
import Icon from '@/shared/components/custom/icon'

export const metadata: Metadata = {}

interface LayoutProps extends PropsWithChildren {}

const Layout: FunctionComponent<LayoutProps> = ({ children }) => {
return (
<>
<header className="flex h-[54px] w-full max-w-mobile items-center justify-between bg-background-base-02 px-[18px]">
<Icon name="logo" className="h-[36px]" />
</header>
{children}
</>
)
}

export default Layout
25 changes: 25 additions & 0 deletions src/app/(routes)/invite/sign-up/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import SocialLogin from '@/features/auth/social-login'
import Text from '@/shared/components/ui/text'

interface Props {
searchParams?: {
code: string
}
}

const InviteSignUpPage = ({ searchParams }: Props) => {
// 유효한 코드일 경우 전달됨

return (
<main className="flex-center h-[calc(100dvh-54px)] w-full flex-col overflow-y-auto overflow-x-hidden bg-background-base-02 px-[16px] scrollbar-hide">
<Text as={'h2'} typography="title1">
3초만에 픽토스 시작하기
</Text>

<SocialLogin />
</main>
)
}

export default InviteSignUpPage
2 changes: 1 addition & 1 deletion src/app/(routes)/profile/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const AccountPage = async () => {
<Text typography="subtitle2-medium">카카오 로그인</Text>

{/* 구글 로그인 */}
{/* <Icon name="google" className="size-[20px]" />
{/* <Icon name="google-with-background" className="size-[20px]" />
<Text typography="subtitle2-medium">구글 로그인</Text>
<Text typography="text2-medium" className="font-suit text-text-caption">
[email protected]
Expand Down
31 changes: 31 additions & 0 deletions src/features/auth/social-login/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client'

import Icon from '@/shared/components/custom/icon'
import { Button } from '@/shared/components/ui/button'
import Text from '@/shared/components/ui/text'
import { signIn } from 'next-auth/react'

const SocialLogin = () => {
return (
<div className="my-[64px] flex w-full flex-col items-center">
<Button
className="w-full gap-[12px] rounded-full bg-white py-[13.5px] hover:bg-white"
onClick={() => signIn('google')}
>
<Icon name="google" />
<Text typography="text1-bold" color="primary">
Google로 로그인
</Text>
</Button>
<Button
className="mt-[14px] w-full gap-[16px] rounded-full bg-[#FBE44D] py-[13.5px] text-[#3C1E1E] hover:bg-[#FBE44D]/80"
onClick={() => signIn('kakao')}
>
<Icon name="kakao" />
<Text typography="text1-bold">카카오로 로그인</Text>
</Button>
</div>
)
}

export default SocialLogin
42 changes: 42 additions & 0 deletions src/features/invite/screen/available-invite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Button } from '@/shared/components/ui/button'
import Text from '@/shared/components/ui/text'
import Image from 'next/image'
import Link from 'next/link'

const AvailableInviteView = ({ code }: { code: string }) => {
return (
<>
<Image
src={'/images/invite-letter.png'}
alt=""
width={198}
height={210}
className="my-[29px]"
/>

<Text typography="title1" className="mb-[8px]">
{'픽토스'}님이 보내신
</Text>

<Text typography="title1" className="mb-[16px]">
{'픽토스'}{' '}
<Text as="span" color="special">
PRO
</Text>{' '}
무료 이용권
</Text>

<Text typography="text1-medium" color="sub" className="text-center">
하루 5분으로 내가 배운 것을 기억하세요 <br />
노트필기, 수업 기록, 저장한 자료 등 <br />
픽토스 PRO에서는 마음껏 퀴즈로 만들 수 있어요
</Text>

<Link href={'/invite/sign-up' + '?code=' + code} className="w-full max-w-[280px]">
<Button className="mx-[5px] my-[56px] w-full max-w-[280px]">바로 받기</Button>
</Link>
</>
)
}

export default AvailableInviteView
38 changes: 38 additions & 0 deletions src/features/invite/screen/unavailable-invite.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Button } from '@/shared/components/ui/button'
import Text from '@/shared/components/ui/text'
import Image from 'next/image'
import Link from 'next/link'

const UnavailableInviteView = () => {
return (
<>
<Image
src={'/images/no-invite-letter.png'}
alt=""
width={133}
height={92}
className="my-[84px]"
/>

<Text typography="title1" className="mb-[8px]">
이런!
</Text>

<Text typography="title1" className="mb-[16px]">
초대장이 사라졌어요
</Text>

<Text typography="text1-medium" color="sub" className="text-center">
링크 유효기간이 만료되어, 새로운 초대 링크가 필요해요 <br />
픽토스 PRO 무료 이용권을 받고 싶다면 <br />
친구에게 링크를 다시 요청해보세요
</Text>

<Link href={'/invite/sign-up'} className="w-full max-w-[280px]">
<Button className="mx-[5px] my-[56px] w-full max-w-[280px]">그냥 바로 가입하기</Button>
</Link>
</>
)
}

export default UnavailableInviteView
30 changes: 30 additions & 0 deletions src/shared/components/custom/icon/svg-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,36 @@ export const KakaoWithBackground = ({ ...props }) => {
}

export const Google = ({ ...props }) => {
return (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M18.6706 8.36775H17.9993V8.33317H10.4993V11.6665H15.2089C14.5219 13.6069 12.6756 14.9998 10.4993 14.9998C7.7381 14.9998 5.49935 12.7611 5.49935 9.99984C5.49935 7.23859 7.7381 4.99984 10.4993 4.99984C11.7739 4.99984 12.9335 5.48067 13.8164 6.26609L16.1735 3.909C14.6852 2.52192 12.6943 1.6665 10.4993 1.6665C5.89727 1.6665 2.16602 5.39775 2.16602 9.99984C2.16602 14.6019 5.89727 18.3332 10.4993 18.3332C15.1014 18.3332 18.8327 14.6019 18.8327 9.99984C18.8327 9.44109 18.7752 8.89567 18.6706 8.36775Z"
fill="#FFC107"
/>
<path
d="M3.12695 6.12109L5.86487 8.129C6.6057 6.29484 8.39987 4.99984 10.4995 4.99984C11.774 4.99984 12.9336 5.48067 13.8165 6.26609L16.1736 3.909C14.6853 2.52192 12.6945 1.6665 10.4995 1.6665C7.29862 1.6665 4.52279 3.47359 3.12695 6.12109Z"
fill="#FF3D00"
/>
<path
d="M10.5008 18.3331C12.6533 18.3331 14.6091 17.5094 16.0879 16.1698L13.5087 13.9873C12.6439 14.645 11.5872 15.0007 10.5008 14.9998C8.33328 14.9998 6.49286 13.6177 5.79953 11.689L3.08203 13.7827C4.4612 16.4815 7.26203 18.3331 10.5008 18.3331Z"
fill="#4CAF50"
/>
<path
d="M18.6713 8.36808H18V8.3335H10.5V11.6668H15.2096C14.8809 12.5903 14.2889 13.3973 13.5067 13.9881L13.5079 13.9872L16.0871 16.1697C15.9046 16.3356 18.8333 14.1668 18.8333 10.0002C18.8333 9.44141 18.7758 8.896 18.6713 8.36808Z"
fill="#1976D2"
/>
</svg>
)
}

export const GoogleWithBackground = ({ ...props }) => {
return (
<svg
width="20"
Expand Down
2 changes: 1 addition & 1 deletion src/shared/components/ui/text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const TextColorStyles: Record<TextColor, string> = {
disabled: 'text-text-disabled',
right: 'text-text-right',
wrong: 'text-text-wrong',
special: 'bg-gradient-to-r from-blue-400 to-orange-500 bg-clip-text text-transparent',
special: 'bg-gradient-to-r from-orange-500 to-blue-400 bg-clip-text text-transparent',
}

const Text = forwardRef(
Expand Down

0 comments on commit 260a562

Please sign in to comment.