diff --git a/apps/admin/src/assets/images/create-show.png b/apps/admin/src/assets/images/create-show.png deleted file mode 100644 index 6ee8b0c0..00000000 Binary files a/apps/admin/src/assets/images/create-show.png and /dev/null differ diff --git a/apps/admin/src/assets/images/entrance-notification.png b/apps/admin/src/assets/images/entrance-notification.png deleted file mode 100644 index 1ec063d3..00000000 Binary files a/apps/admin/src/assets/images/entrance-notification.png and /dev/null differ diff --git a/apps/admin/src/assets/images/key-visual.png b/apps/admin/src/assets/images/key-visual.png deleted file mode 100644 index e8a2dc88..00000000 Binary files a/apps/admin/src/assets/images/key-visual.png and /dev/null differ diff --git a/apps/admin/src/assets/images/light.png b/apps/admin/src/assets/images/light.png deleted file mode 100644 index 54299407..00000000 Binary files a/apps/admin/src/assets/images/light.png and /dev/null differ diff --git a/apps/admin/src/assets/images/manage-entrance.png b/apps/admin/src/assets/images/manage-entrance.png deleted file mode 100644 index 64a87316..00000000 Binary files a/apps/admin/src/assets/images/manage-entrance.png and /dev/null differ diff --git a/apps/admin/src/assets/images/mobile-admin-preview.png b/apps/admin/src/assets/images/mobile-admin-preview.png deleted file mode 100644 index 80aa5f15..00000000 Binary files a/apps/admin/src/assets/images/mobile-admin-preview.png and /dev/null differ diff --git a/apps/admin/src/assets/images/mobile-ticket-preview.png b/apps/admin/src/assets/images/mobile-ticket-preview.png deleted file mode 100644 index 4f2f5938..00000000 Binary files a/apps/admin/src/assets/images/mobile-ticket-preview.png and /dev/null differ diff --git a/apps/admin/src/assets/images/more-information-light.png b/apps/admin/src/assets/images/more-information-light.png deleted file mode 100644 index 56059edd..00000000 Binary files a/apps/admin/src/assets/images/more-information-light.png and /dev/null differ diff --git a/apps/admin/src/assets/images/pc-admin-preview.png b/apps/admin/src/assets/images/pc-admin-preview.png deleted file mode 100644 index de28f62f..00000000 Binary files a/apps/admin/src/assets/images/pc-admin-preview.png and /dev/null differ diff --git a/apps/admin/src/assets/images/pc-ticket-preview.png b/apps/admin/src/assets/images/pc-ticket-preview.png deleted file mode 100644 index 93bc0a51..00000000 Binary files a/apps/admin/src/assets/images/pc-ticket-preview.png and /dev/null differ diff --git a/apps/admin/src/assets/images/show-info.png b/apps/admin/src/assets/images/show-info.png deleted file mode 100644 index 64504205..00000000 Binary files a/apps/admin/src/assets/images/show-info.png and /dev/null differ diff --git a/apps/admin/src/assets/images/ticket-purchase.png b/apps/admin/src/assets/images/ticket-purchase.png deleted file mode 100644 index e9218329..00000000 Binary files a/apps/admin/src/assets/images/ticket-purchase.png and /dev/null differ diff --git a/apps/admin/src/assets/landing-v2/arrow.svg b/apps/admin/src/assets/landing-v2/arrow.svg new file mode 100644 index 00000000..82ecc5e2 --- /dev/null +++ b/apps/admin/src/assets/landing-v2/arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/admin/src/assets/landing-v2/entry-asis.png b/apps/admin/src/assets/landing-v2/entry-asis.png new file mode 100644 index 00000000..ee26fbad Binary files /dev/null and b/apps/admin/src/assets/landing-v2/entry-asis.png differ diff --git a/apps/admin/src/assets/landing-v2/entry-tobe.png b/apps/admin/src/assets/landing-v2/entry-tobe.png new file mode 100644 index 00000000..d169f523 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/entry-tobe.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-1.png b/apps/admin/src/assets/landing-v2/hero-1.png new file mode 100644 index 00000000..bf5c3035 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-1.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-2.png b/apps/admin/src/assets/landing-v2/hero-2.png new file mode 100644 index 00000000..e3c3d5a1 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-2.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-3.png b/apps/admin/src/assets/landing-v2/hero-3.png new file mode 100644 index 00000000..052f281d Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-3.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-4.png b/apps/admin/src/assets/landing-v2/hero-4.png new file mode 100644 index 00000000..208ba721 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-4.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-5.png b/apps/admin/src/assets/landing-v2/hero-5.png new file mode 100644 index 00000000..e69cf512 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/hero-5.png differ diff --git a/apps/admin/src/assets/landing-v2/hero-logo.svg b/apps/admin/src/assets/landing-v2/hero-logo.svg new file mode 100644 index 00000000..3fb23394 --- /dev/null +++ b/apps/admin/src/assets/landing-v2/hero-logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/apps/admin/src/assets/landing-v2/light.svg b/apps/admin/src/assets/landing-v2/light.svg new file mode 100644 index 00000000..d1685fb3 --- /dev/null +++ b/apps/admin/src/assets/landing-v2/light.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/admin/src/assets/landing-v2/notify-asis.png b/apps/admin/src/assets/landing-v2/notify-asis.png new file mode 100644 index 00000000..cbe61780 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/notify-asis.png differ diff --git a/apps/admin/src/assets/landing-v2/notify-tobe.png b/apps/admin/src/assets/landing-v2/notify-tobe.png new file mode 100644 index 00000000..773aa492 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/notify-tobe.png differ diff --git a/apps/admin/src/assets/landing-v2/payment.png b/apps/admin/src/assets/landing-v2/payment.png new file mode 100644 index 00000000..b9022f48 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/payment.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-1.png b/apps/admin/src/assets/landing-v2/problem-1.png new file mode 100644 index 00000000..7a153fa4 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-1.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-2.png b/apps/admin/src/assets/landing-v2/problem-2.png new file mode 100644 index 00000000..06b91c95 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-2.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-3.png b/apps/admin/src/assets/landing-v2/problem-3.png new file mode 100644 index 00000000..bfa678f4 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-3.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-4.png b/apps/admin/src/assets/landing-v2/problem-4.png new file mode 100644 index 00000000..2d610e9e Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-4.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-5.png b/apps/admin/src/assets/landing-v2/problem-5.png new file mode 100644 index 00000000..80b53ccb Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-5.png differ diff --git a/apps/admin/src/assets/landing-v2/problem-6.png b/apps/admin/src/assets/landing-v2/problem-6.png new file mode 100644 index 00000000..8df3af66 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/problem-6.png differ diff --git a/apps/admin/src/assets/landing-v2/promo-1.png b/apps/admin/src/assets/landing-v2/promo-1.png new file mode 100644 index 00000000..364a5665 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/promo-1.png differ diff --git a/apps/admin/src/assets/landing-v2/promo-2.png b/apps/admin/src/assets/landing-v2/promo-2.png new file mode 100644 index 00000000..6668fade Binary files /dev/null and b/apps/admin/src/assets/landing-v2/promo-2.png differ diff --git a/apps/admin/src/assets/landing-v2/sales-asis.png b/apps/admin/src/assets/landing-v2/sales-asis.png new file mode 100644 index 00000000..db85cca9 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/sales-asis.png differ diff --git a/apps/admin/src/assets/landing-v2/sales-tobe.png b/apps/admin/src/assets/landing-v2/sales-tobe.png new file mode 100644 index 00000000..1bc3282d Binary files /dev/null and b/apps/admin/src/assets/landing-v2/sales-tobe.png differ diff --git a/apps/admin/src/assets/landing-v2/stats-asis.png b/apps/admin/src/assets/landing-v2/stats-asis.png new file mode 100644 index 00000000..55106205 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/stats-asis.png differ diff --git a/apps/admin/src/assets/landing-v2/stats-tobe.png b/apps/admin/src/assets/landing-v2/stats-tobe.png new file mode 100644 index 00000000..beaf49f2 Binary files /dev/null and b/apps/admin/src/assets/landing-v2/stats-tobe.png differ diff --git a/apps/admin/src/pages/Landing/LandingPage.styles.ts b/apps/admin/src/pages/Landing/LandingPage.styles.ts index 65d1bb7b..1d9b02be 100644 --- a/apps/admin/src/pages/Landing/LandingPage.styles.ts +++ b/apps/admin/src/pages/Landing/LandingPage.styles.ts @@ -1,17 +1,13 @@ -import { mq_lg } from '@boolti/ui'; import styled from '@emotion/styled'; import { m } from 'framer-motion'; const Container = styled(m.div)` overflow: hidden; min-height: 100vh; - padding-top: 48px; + &::-webkit-scrollbar { display: none; } - ${mq_lg} { - padding-top: 68px; - } `; const FooterContainer = styled.div` diff --git a/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts b/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts index de8b8fd8..0789a2e0 100644 --- a/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts +++ b/apps/admin/src/pages/Landing/atoms/visibleSectionAtom.ts @@ -2,9 +2,14 @@ import { atom, useSetAtom } from 'jotai'; import { useEffect } from 'react'; import { useInView } from 'react-intersection-observer'; -type VisibleSection = 'key-visal' | 'organizer' | 'user'; +type VisibleSection = + | 'hero' + | 'problem' + | 'solution-features' + | 'solution-highlight' + | 'how-to-use'; -export const visibleSectionAtom = atom('key-visal'); +export const visibleSectionAtom = atom('hero'); export const useVisibleSectionAtom = (section: VisibleSection) => { const { ref, inView, entry } = useInView({ threshold: 0.2 }); diff --git a/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts b/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts new file mode 100644 index 00000000..e0d2fd2a --- /dev/null +++ b/apps/admin/src/pages/Landing/components/FeatureCard/FeatureCard.styles.ts @@ -0,0 +1,157 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; + +import { LANDING_COLORS, mq_desktop } from '../../constants'; + +const Card = styled.article` + display: flex; + flex-direction: column; + align-items: stretch; + width: 100%; +`; + +const TextArea = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 16px; + padding: 0 24px 24px; + + ${mq_lg} { + gap: 20px; + padding: 0 0 32px; + } + + ${mq_desktop} { + gap: 24px; + padding: 0 0 40px; + } +`; + +const Chip = styled.div` + display: inline-flex; + align-items: center; + padding: 8px 14px; + border-radius: 200px; + background-color: ${LANDING_COLORS.chipBg}; + color: ${LANDING_COLORS.chipText}; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 16px; + line-height: 1.3; + letter-spacing: -0.02em; + + ${mq_lg} { + font-size: 18px; + } + + ${mq_desktop} { + padding: 10px 16px; + font-size: 24px; + } +`; + +const TitleBlock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + text-align: center; +`; + +const Title = styled.h3` + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 20px; + line-height: 1.35; + letter-spacing: -0.02em; + white-space: pre-line; + color: #000000; + margin: 0; + + ${mq_lg} { + font-size: 24px; + } + + ${mq_desktop} { + font-size: 32px; + } +`; + +const Description = styled.p` + font-family: Pretendard, sans-serif; + font-weight: 400; + font-size: 14px; + line-height: 1.5; + letter-spacing: -0.02em; + white-space: pre-line; + color: #a2a5b4; + margin: 0; + + ${mq_lg} { + font-size: 18px; + } + + ${mq_desktop} { + font-size: 24px; + } +`; + +const Media = styled.div` + position: relative; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + width: 100%; + padding: 16px; + border: 1px solid ${LANDING_COLORS.cardBorder}; + border-radius: 16px; + background-color: #ffffff; + + ${mq_desktop} { + padding: 32px; + gap: 24px; + } +`; + +const MediaImage = styled.img` + width: 100%; + height: auto; + object-fit: cover; + border-radius: 8px; +`; + +const MediaArrow = styled.div` + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 32px; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + + svg, + img { + width: 100%; + height: 100%; + } + + ${mq_desktop} { + width: 48px; + height: 48px; + } +`; + +export default { + Card, + TextArea, + Chip, + TitleBlock, + Title, + Description, + Media, + MediaImage, + MediaArrow, +}; diff --git a/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx b/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx new file mode 100644 index 00000000..3044dacf --- /dev/null +++ b/apps/admin/src/pages/Landing/components/FeatureCard/index.tsx @@ -0,0 +1,49 @@ +import { ReactNode } from 'react'; + +import arrowSvg from '~/assets/landing-v2/arrow.svg'; + +import Styled from './FeatureCard.styles'; + +interface FeatureCardProps { + chip: string; + title: string; + description: string; + asisSrc?: string; + tobeSrc?: string; + media?: ReactNode; + className?: string; +} + +const FeatureCard = ({ + chip, + title, + description, + asisSrc, + tobeSrc, + media, + className, +}: FeatureCardProps) => { + return ( + + + {chip} + + {title} + {description} + + + {media ?? + (asisSrc && tobeSrc ? ( + + + + + + + + ) : null)} + + ); +}; + +export default FeatureCard; diff --git a/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts b/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts deleted file mode 100644 index 0bd6ca0d..00000000 --- a/apps/admin/src/pages/Landing/components/FeatureItem/FeatureItem.styles.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { mq_lg, mq_md } from '@boolti/ui'; -import styled from '@emotion/styled'; - -const Container = styled.div<{ position: 'left' | 'right' }>` - display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: center; - padding: 80px 0 40px; - flex-direction: column; - - ${mq_lg} { - max-width: ${({ theme }) => theme.breakpoint.desktop}; - margin: 0 auto; - padding: 110px 20px 0; - justify-content: space-between; - flex-direction: ${({ position }) => (position === 'left' ? 'row' : 'row-reverse')}; - } - ${mq_md} { - flex-direction: column; - align-items: ${({ position }) => (position === 'left' ? 'flex-start' : 'flex-end')}; - max-width: ${({ theme }) => theme.breakpoint.tablet}; - } -`; - -const Circle = styled.div` - z-index: 0; - width: 70px; - height: 70px; - border-radius: 100%; - background-color: ${({ theme }) => theme.palette.primary.o1}; - opacity: 0.15; - filter: blur(10px); - position: absolute; - top: -125%; - left: -75%; - - ${mq_lg} { - width: 120px; - height: 120px; - top: -150%; - } -`; - -const TextContainer = styled.div` - text-align: center; - - ${mq_lg} { - flex: 0 0 auto; - text-align: left; - } -`; - -const CategoryText = styled.span` - z-index: 1; - display: inline-block; - position: relative; - ${({ theme }) => theme.typo.b1}; - font-weight: bold; - color: ${({ theme }) => theme.palette.primary.o1}; - - ${mq_lg} { - ${({ theme }) => theme.typo.h2}; - font-size: 20px; - line-height: 24px; - } -`; - -const Title = styled.h3` - position: relative; - z-index: 1; - ${({ theme }) => theme.typo.point.p4}; - color: ${({ theme }) => theme.palette.grey.g90}; - margin: 6px 0; - white-space: pre-wrap; - - ${mq_lg} { - font-size: 32px; - margin: 12px 0 20px; - line-height: 52px; - } - - ${mq_md} { - margin: 12px 0 6px; - } -`; - -const Description = styled.p` - ${({ theme }) => theme.typo.b1}; - color: ${({ theme }) => theme.palette.grey.g60}; - white-space: pre-wrap; - - ${mq_lg} { - font-size: 20px; - line-height: 32px; - } -`; - -const Image = styled.img<{ - maxWidth: [number, number, number]; - padding: [number, number]; - position: 'left' | 'right'; -}>` - width: calc(100% - 40px); - max-width: ${({ maxWidth }) => maxWidth[0]}px; - margin-top: 40px; - padding: ${({ padding }) => padding[0]}px ${({ padding }) => padding[1]}px; - - ${mq_md} { - margin-top: 40px !important; - margin-${({ position }) => position}: auto; - max-width: ${({ maxWidth }) => maxWidth[1]}px !important; - } - - ${mq_lg} { - min-width: 0; - min-height: 0; - overflow: hidden; - flex: 1 1 auto; - width: auto; - max-width: ${({ maxWidth }) => maxWidth[2]}px; - margin-top: 0; - } -`; - -export default { - Container, - Circle, - CategoryText, - TextContainer, - Title, - Description, - Image, -}; diff --git a/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx b/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx deleted file mode 100644 index 157f02aa..00000000 --- a/apps/admin/src/pages/Landing/components/FeatureItem/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import Styled from './FeatureItem.styles'; - -interface Props { - category: string; - title: string; - description: string; - position: 'left' | 'right'; - imageSrc: string; - maxWidth: [number, number, number]; - imagePadding?: [number, number]; -} - -const FeatureItem = ({ - category, - title, - description, - position, - imageSrc, - maxWidth, - imagePadding = [0, 0], -}: Props) => { - return ( - - - - {category} - - - {title} - {description} - - - - ); -}; - -export default FeatureItem; diff --git a/apps/admin/src/pages/Landing/components/Header/Header.styles.ts b/apps/admin/src/pages/Landing/components/Header/Header.styles.ts index 57492b8b..4eec972e 100644 --- a/apps/admin/src/pages/Landing/components/Header/Header.styles.ts +++ b/apps/admin/src/pages/Landing/components/Header/Header.styles.ts @@ -1,22 +1,21 @@ -import { Button as _Button, mq_lg } from '@boolti/ui'; +import { mq_lg } from '@boolti/ui'; import styled from '@emotion/styled'; import { m } from 'framer-motion'; import { Link } from 'react-router-dom'; +import { LANDING_COLORS } from '../../constants'; + const Header = styled.header` position: fixed; - z-index: 2; + z-index: 10; top: 0; left: 0; width: 100%; - border-bottom: 1px solid; - border-color: ${({ theme }) => `${theme.palette.grey.g50}${theme.palette.opacity[30]}`}; - background: ${({ theme }) => `${theme.palette.grey.g60}${theme.palette.opacity[40]}`}; - backdrop-filter: blur(40px); + border-bottom: 1px solid ${LANDING_COLORS.headerBorder}; + background: ${LANDING_COLORS.headerGlass}; + backdrop-filter: blur(80px); + -webkit-backdrop-filter: blur(80px); padding: 0 20px; - ${mq_lg} { - padding: 0 20px; - } `; const HeaderContaienr = styled(m.div)` @@ -26,10 +25,10 @@ const HeaderContaienr = styled(m.div)` align-items: center; justify-content: space-between; max-width: ${({ theme }) => theme.breakpoint.desktop}; - height: 48px; + height: 56px; + ${mq_lg} { - padding: 0 20px; - height: 68px; + height: 72px; } `; @@ -37,7 +36,8 @@ const BooltiIcon = styled.button` width: 55.5px; height: 21px; cursor: pointer; - z-index: 1; + display: flex; + align-items: center; ${mq_lg} { width: 74px; @@ -49,95 +49,79 @@ const BooltiIcon = styled.button` } `; -const MobileButton = styled.button` - width: 40px; - height: 40px; +const Nav = styled.div` display: flex; align-items: center; - justify-content: flex-end; - cursor: pointer; - - & > svg { - color: white; - width: 24px; - height: 24px; - } + gap: 12px; ${mq_lg} { - display: none; + gap: 24px; } `; -const MobileMenu = styled(m.div)` - display: flex; - flex-direction: column; - overflow: hidden; - margin-top: auto; - width: 100%; +const TextButton = styled.button` + display: none; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 16px; + line-height: 1.3; + color: #ffffff; + padding: 8px 12px; + cursor: pointer; ${mq_lg} { - display: none; + display: inline-flex; } `; -const DesktopMenu = styled.div` - display: none; +const PrimaryButton = styled(Link)` + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px 14px; + border-radius: 12px; + background-color: ${LANDING_COLORS.primaryCta}; + color: #ffffff; + font-family: Pretendard, sans-serif; + font-weight: 500; + font-size: 14px; + line-height: 1.3; + text-decoration: none; + cursor: pointer; + ${mq_lg} { - flex: 1; - padding-left: 48px; - display: flex; + padding: 10px 18px; + font-size: 16px; } `; -const InternalLink = styled(Link)` - display: flex; - align-items: center; - ${({ theme }) => theme.typo.b1}; - color: ${({ theme }) => theme.palette.grey.w}; +const AuthTextButton = styled.button` + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 14px; + line-height: 1.3; + color: #ffffff; + padding: 8px 12px; cursor: pointer; - padding: 12px 0; ${mq_lg} { - ${({ theme }) => theme.typo.sh1}; - padding: 0 18px; + font-size: 16px; } `; const DropDownContainer = styled.div` - margin-left: auto; - .icon-wrapper > svg { - color: ${({ theme }) => theme.palette.grey.w}; + color: #ffffff; } `; -const AuthButton = styled.button` - ${({ theme }) => theme.typo.sh1}; - cursor: pointer; - - padding: 0 18px; - color: ${({ theme }) => theme.palette.grey.w}; - &:last-child { - margin-left: auto; - } -`; - -const MobileAuthButton = styled(_Button)` - display: flex; - cursor: pointer; - width: 100%; - margin: 12px 0 20px; -`; - export default { Header, - DesktopMenu, HeaderContaienr, BooltiIcon, - MobileButton, - MobileMenu, - InternalLink, - MobileAuthButton, + Nav, + TextButton, + PrimaryButton, + AuthTextButton, DropDownContainer, - AuthButton, }; diff --git a/apps/admin/src/pages/Landing/components/Header/index.tsx b/apps/admin/src/pages/Landing/components/Header/index.tsx index 0ca540a3..69dea86b 100644 --- a/apps/admin/src/pages/Landing/components/Header/index.tsx +++ b/apps/admin/src/pages/Landing/components/Header/index.tsx @@ -1,143 +1,68 @@ import { queryKeys, useLogout, useQueryClient, useUserProfile } from '@boolti/api'; -import { BooltiDark, CloseIcon, MenuIcon } from '@boolti/icon'; +import { BooltiDark } from '@boolti/icon'; import { useTheme } from '@emotion/react'; -import { useAtomValue } from 'jotai'; -import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import ProfileDropdown from '~/components/ProfileDropdown'; import { PATH } from '~/constants/routes'; import { useDeviceWidth } from '~/hooks/useDeviceWidth'; -import { useScrollDirection } from '~/hooks/useScrollDirection'; - import { useAuthAtom } from '~/atoms/useAuthAtom'; import { openStoreLink } from '~/utils/link'; -import { Tab } from '..'; -import { visibleSectionAtom } from '../../atoms/visibleSectionAtom'; + import Styled from './Header.styles'; const Header = () => { const { isLogin, removeToken } = useAuthAtom(); - const currentVisibleSection = useAtomValue(visibleSectionAtom); - const scrollDirection = useScrollDirection(); - const visible = currentVisibleSection === 'key-visal' || scrollDirection === 'up'; - - const deviceWidth = useDeviceWidth(); const theme = useTheme(); + const deviceWidth = useDeviceWidth(); const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10); - const logoutMutation = useLogout(); const navigate = useNavigate(); const queryClient = useQueryClient(); - - const [isExpanded, setIsExpanded] = useState(false); + const logoutMutation = useLogout(); const { data } = useUserProfile({ enabled: isLogin() }); const { imgPath } = data ?? {}; - const onClickAuthButton = async () => { + const handleAppExplore = () => { + if (isMobile) { + openStoreLink(); + return; + } + navigate(PATH.QR); + }; + + const handleAuth = async () => { if (isLogin()) { await logoutMutation.mutateAsync(); - removeToken(); queryClient.removeQueries({ ...queryKeys.user.summary }); - return; } - navigate(PATH.LOGIN); }; return ( - + scrollTo({ top: 0, behavior: 'smooth' })}> - - - { - if (isMobile) { - openStoreLink(); - return; - } - navigate(PATH.QR); - }} - > - 앱 바로가기 - - 공연 준비하기 + + + 앱 둘러보기 + {isLogin() ? ( ) : ( - 로그인 + + 로그인 + )} - - - {/** 모바일용 */} - { - setIsExpanded((prev) => !prev); - }} - > - {isExpanded ? : } - + 시작하기 + - - { - if (isMobile) { - openStoreLink(); - return; - } - navigate(PATH.QR); - }} - > - 앱 바로가기 - - 공연 준비하기 - - {isLogin() ? '로그아웃' : '로그인'} - - - - {!isMobile && } ); }; diff --git a/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts b/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts new file mode 100644 index 00000000..a827f0e3 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/Hero/Hero.styles.ts @@ -0,0 +1,152 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; + +import { LANDING_COLORS, mq_desktop } from '../../constants'; + +const Section = styled.section` + display: flex; + flex-direction: column; + align-self: stretch; + padding: 104px 20px 32px; + background: ${LANDING_COLORS.heroGradient}; + + ${mq_lg} { + padding: 140px 24px 24px; + } + + ${mq_desktop} { + padding: 140px 32px 48px; + } +`; + +const Container = styled.div` + display: flex; + flex-direction: column; + align-items: stretch; + gap: 32px; + width: 100%; + max-width: 1200px; + margin: 0 auto; + + ${mq_desktop} { + gap: 43px; + } +`; + +const TextBlock = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + text-align: center; +`; + +const Eyebrow = styled.span` + font-family: Pretendard, sans-serif; + font-weight: 400; + font-size: 18px; + line-height: 1.3; + letter-spacing: -0.04em; + color: #a2a5b4; + + ${mq_lg} { + font-size: 22px; + } + + ${mq_desktop} { + font-size: 26px; + } +`; + +const Title = styled.h1` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 28px; + line-height: 1.45; + letter-spacing: -0.02em; + color: #ffffff; + margin: 0; + + ${mq_lg} { + font-size: 34px; + } + + ${mq_desktop} { + font-size: 42px; + } +`; + +const TitleRow = styled.span` + display: inline-flex; + align-items: center; + gap: 10px; +`; + +const LogoMark = styled.span` + display: inline-flex; + align-items: center; + height: 1em; + + svg, + img { + height: 1em; + width: auto; + } +`; + +const ImageRow = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; + gap: 12px; + padding: 16px 4px; + overflow-x: auto; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + ${mq_desktop} { + gap: 16px; + padding: 24px 8px; + justify-content: center; + } +`; + +const ImageCard = styled.img` + flex-shrink: 0; + width: 200px; + height: 268px; + border-radius: 16px; + object-fit: cover; + background-color: #2a2a3d; + user-select: none; + + ${mq_lg} { + width: 240px; + height: 322px; + } + + ${mq_desktop} { + width: 280px; + height: 376px; + } +`; + +export default { + Section, + Container, + TextBlock, + Eyebrow, + Title, + TitleRow, + LogoMark, + ImageRow, + ImageCard, +}; diff --git a/apps/admin/src/pages/Landing/components/Hero/index.tsx b/apps/admin/src/pages/Landing/components/Hero/index.tsx new file mode 100644 index 00000000..0a2cd782 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/Hero/index.tsx @@ -0,0 +1,42 @@ +import heroLogo from '~/assets/landing-v2/hero-logo.svg'; +import hero1 from '~/assets/landing-v2/hero-1.png'; +import hero2 from '~/assets/landing-v2/hero-2.png'; +import hero3 from '~/assets/landing-v2/hero-3.png'; +import hero4 from '~/assets/landing-v2/hero-4.png'; +import hero5 from '~/assets/landing-v2/hero-5.png'; + +import { LANDING_COPY } from '../../constants'; +import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; +import Styled from './Hero.styles'; + +const HERO_IMAGES = [hero1, hero2, hero3, hero4, hero5]; + +const Hero = () => { + const { ref } = useVisibleSectionAtom('hero'); + + return ( + + + + {LANDING_COPY.hero.eyebrow} + + {LANDING_COPY.hero.titleLead} + + {LANDING_COPY.hero.titleTrail} + + 불티 + + + + + + {HERO_IMAGES.map((src, index) => ( + + ))} + + + + ); +}; + +export default Hero; diff --git a/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts b/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts new file mode 100644 index 00000000..512d8c1f --- /dev/null +++ b/apps/admin/src/pages/Landing/components/HowToUse/HowToUse.styles.ts @@ -0,0 +1,138 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; +import { Link } from 'react-router-dom'; + +import { LANDING_COLORS, mq_desktop } from '../../constants'; + +const Section = styled.section` + position: relative; + display: flex; + flex-direction: column; + align-items: center; + align-self: stretch; + gap: 40px; + padding: 80px 20px; + background-color: #000000; + overflow: hidden; + + ${mq_lg} { + gap: 48px; + padding: 96px 32px; + } + + ${mq_desktop} { + gap: 56px; + padding: 120px 32px; + } +`; + +const Light = styled.img` + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 100%; + max-width: 1200px; + height: auto; + pointer-events: none; + opacity: 0.6; + z-index: 1; +`; + +const Title = styled.h2` + position: relative; + z-index: 2; + text-align: center; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 24px; + line-height: 1.45; + letter-spacing: -0.02em; + color: #ffffff; + white-space: pre-line; + margin: 0; + + ${mq_lg} { + font-size: 32px; + } + + ${mq_desktop} { + font-size: 40px; + } +`; + +const BtnWrap = styled.div` + position: relative; + z-index: 2; + display: flex; + flex-direction: column; + gap: 12px; + width: 100%; + max-width: 360px; + + ${mq_lg} { + flex-direction: row; + width: auto; + max-width: none; + gap: 16px; + } +`; + +const baseButton = ` + display: inline-flex; + justify-content: center; + align-items: center; + padding: 16px 24px; + border-radius: 12px; + font-family: Pretendard, sans-serif; + font-size: 16px; + line-height: 1.3; + letter-spacing: -0.02em; + cursor: pointer; + text-decoration: none; + border: 0; +`; + +const PrimaryButton = styled(Link)` + ${baseButton} + background-color: ${LANDING_COLORS.primaryCta}; + color: #ffffff; + font-weight: 500; + box-shadow: 0 8px 24px rgba(255, 104, 39, 0.3); + + ${mq_lg} { + padding: 18px 28px; + font-size: 18px; + } + + ${mq_desktop} { + padding: 20px 32px; + font-size: 24px; + } +`; + +const SecondaryButton = styled.button` + ${baseButton} + background-color: ${LANDING_COLORS.darkButton}; + color: ${LANDING_COLORS.darkButtonText}; + font-weight: 400; + + ${mq_lg} { + padding: 18px 28px; + font-size: 18px; + } + + ${mq_desktop} { + padding: 20px 32px; + font-size: 24px; + } +`; + +export default { + Section, + Light, + Title, + BtnWrap, + PrimaryButton, + SecondaryButton, +}; diff --git a/apps/admin/src/pages/Landing/components/HowToUse/index.tsx b/apps/admin/src/pages/Landing/components/HowToUse/index.tsx new file mode 100644 index 00000000..8b0bacdc --- /dev/null +++ b/apps/admin/src/pages/Landing/components/HowToUse/index.tsx @@ -0,0 +1,44 @@ +import { useTheme } from '@emotion/react'; +import { useNavigate } from 'react-router-dom'; + +import lightSvg from '~/assets/landing-v2/light.svg'; +import { PATH } from '~/constants/routes'; +import { useDeviceWidth } from '~/hooks/useDeviceWidth'; +import { openStoreLink } from '~/utils/link'; + +import { LANDING_COPY } from '../../constants'; +import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; +import Styled from './HowToUse.styles'; + +const HowToUse = () => { + const { ref } = useVisibleSectionAtom('how-to-use'); + const theme = useTheme(); + const deviceWidth = useDeviceWidth(); + const navigate = useNavigate(); + const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10); + + const handleSecondary = () => { + if (isMobile) { + openStoreLink(); + return; + } + navigate(PATH.QR); + }; + + return ( + + + {LANDING_COPY.howToUse.title} + + + {LANDING_COPY.howToUse.secondaryCta} + + + {LANDING_COPY.howToUse.primaryCta} + + + + ); +}; + +export default HowToUse; diff --git a/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx b/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx deleted file mode 100644 index fd176679..00000000 --- a/apps/admin/src/pages/Landing/components/KeyVisual/KeyVisual.styles.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import { mq_lg } from '@boolti/ui'; -import styled from '@emotion/styled'; -import { m } from 'framer-motion'; - -import keyVisualImg from '~/assets/images/key-visual.png'; - -const Container = styled.section` - position: relative; - text-align: center; - width: 100%; - margin-top: -49px; - padding-top: 49px; - height: 740px; - background: #070708 url('${keyVisualImg}'); - background-position: bottom center; - background-repeat: no-repeat; - background-size: cover; - ${mq_lg} { - margin-top: -69px; - padding-top: 69px; - height: 1200px; - } - &::before, - &::after { - z-index: 0; - content: ''; - position: absolute; - top: 0; - width: 20%; - height: 100%; - background: linear-gradient( - 90deg, - #020205 45.03%, - rgba(2, 2, 5, 0.81) 81.17%, - rgba(2, 2, 5, 0) 100% - ); - filter: blur(27.700000762939453px); - } - &::before { - left: 0; - margin-left: -5%; - } - &::after { - right: 0; - margin-right: -5%; - transform: rotate(180deg); - } -`; - -const Title = styled.h1` - z-index: 1; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - ${({ theme }) => theme.typo.h2}; - color: ${({ theme }) => theme.palette.grey.g00}; - margin-top: 100px; - - & svg { - margin-top: 16px; - width: 104px; - height: 37px; - display: inline-block; - color: ${({ theme }) => theme.palette.grey.g00}; - - path { - fill: ${({ theme }) => theme.palette.grey.g00}; - } - } - - ${mq_lg} { - font-size: 48px; - line-height: normal; - margin-top: 246px; - - & svg { - margin-top: 40px; - width: 259px; - height: 98px; - } - } -`; - -const Description = styled(m.span)` - z-index: 1; - display: inline-block; - position: relative; - white-space: pre-wrap; - word-break: keep-all; - ${({ theme }) => theme.typo.b4}; - color: ${({ theme }) => theme.palette.grey.g00}; - margin-top: 170px; - padding: 0 60px; - - & > b { - font-weight: bold; - } - - &::before, - &::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: calc(100% - 60px); - max-width: 456px; - height: 48px; - border-radius: 100%; - border: 0.2px solid rgba(255, 255, 255, 0.4); - } - &::before { - transform: translate3d(-50%, -50%, 0) rotate(1.6deg); - } - &::after { - transform: translate3d(-50%, -50%, 0) rotate(6.4deg); - } - - ${mq_lg} { - width: calc(100% - 80px); - max-width: 1010px; - margin-top: 400px; - ${({ theme }) => theme.typo.b4}; - font-size: 28px; - line-height: 48px; - letter-spacing: -0.64px; - - &::before, - &::after { - height: 128px; - max-width: 1010px; - border-width: 1px; - } - } -`; - -const FloatingUnion = styled.div<{ position: 'left' | 'right' }>` - position: absolute; - ${({ position }) => { - switch (position) { - case 'left': { - return ` - top: -30px; - left: 10px; - width: 40px; - height: 40px; - transform: roate(24deg); - - ${mq_lg} { - top: -30%; - left: -36px; - width: 96px; - height: 96px; - } - `; - } - case 'right': { - return ` - top: 20%; - right: 10px; - width: 42px; - height: 42px; - transform: rotate(-50deg); - - ${mq_lg} { - top: 30%; - right: -46px; - width: 114px; - height: 114px; - } - `; - } - } - }} -`; - -export const MobileBreak = styled.br` - ${mq_lg} { - display: none; - } -`; - -export const Hidden = styled.div` - height: 0; - opacity: 0; -`; - -export default { - Container, - Title, - Description, - MobileBreak, - Hidden, - FloatingUnion, -}; diff --git a/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx b/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx deleted file mode 100644 index 558a94f4..00000000 --- a/apps/admin/src/pages/Landing/components/KeyVisual/index.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { BooltiDark } from '@boolti/icon'; -import { useAnimation, useInView } from 'framer-motion'; -import { useEffect, useRef } from 'react'; - -import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; -import Styled from './KeyVisual.styles'; - -const Union = () => { - return ( - - - - ); -}; - -const KeyVisual = () => { - const { ref: sectionRef } = useVisibleSectionAtom('key-visal'); - const hiddenElementRef = useRef(null); - const isInView = useInView(hiddenElementRef, { amount: 'all' }); - const animation = useAnimation(); - - useEffect(() => { - if (isInView) { - animation.start('visible'); - } - }, [isInView, animation]); - - return ( - - - 핫한 공연 예매의 시작 - - - - <>음악을 사랑하는 모두가, 공연을 즐기고 싶은 모두가{'\n'} - <>더 쉽게 공연을 주최하고 관람할 수 있도록!{'\n'} - <> - - 지금 불티에서 당신의 공연을 시작해 보세요 - - - - - - - - - - - ); -}; - -export default KeyVisual; diff --git a/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts b/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts deleted file mode 100644 index 2c1492f9..00000000 --- a/apps/admin/src/pages/Landing/components/MoreInformation/MoreInformation.styles.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { mq_lg } from '@boolti/ui'; -import styled from '@emotion/styled'; -import { Link } from 'react-router-dom'; - -import lightImg from '~/assets/images/more-information-light.png'; - -export const Container = styled.section` - position: relative; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - width: 100%; - padding: 80px 0; - background-color: ${({ theme }) => theme.palette.grey.b}; - ${mq_lg} { - height: 400px; - } -`; - -const BackgroundLight = styled.div` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: url('${lightImg}'); - background-position: top center; - background-repeat: no-repeat; - background-size: cover; -`; - -const Text = styled.p` - z-index: 1; - - white-space: pre-wrap; - text-align: center; - ${({ theme }) => theme.typo.sh2}; - color: ${({ theme }) => theme.palette.grey.w}; - - ${mq_lg} { - font-size: 32px; - font-weight: bold; - line-height: 60px; - } -`; - -const Button = styled(Link)` - z-index: 1; - cursor: pointer; - border-radius: 4px; - margin-top: 16px; - padding: 9px 16px; - ${({ theme }) => theme.typo.sh1}; - color: ${({ theme }) => theme.palette.grey.w}; - background-color: ${({ theme }) => theme.palette.primary.o1}; - ${mq_lg} { - padding: 13px 20px; - margin-top: 28px; - } -`; - -export default { - Container, - BackgroundLight, - Text, - Button, -}; diff --git a/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx b/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx deleted file mode 100644 index 23244b62..00000000 --- a/apps/admin/src/pages/Landing/components/MoreInformation/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import Styled from './MoreInformation.styles'; - -const MoerInformation = () => { - const moreInfoPageLink = 'https://www.notion.so/boolti/Boolti-6de303e8cc0242ea8b3930ce33032aa2'; - - return ( - - - 더욱 자세한 불티 이용 방법이{'\n'}궁금하시다면? - 이용 방법 보러 가기 - - ); -}; - -export default MoerInformation; diff --git a/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts b/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts deleted file mode 100644 index 189fb534..00000000 --- a/apps/admin/src/pages/Landing/components/OrganizerSection/OrganizerSection.styles.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { mq_lg } from '@boolti/ui'; -import styled from '@emotion/styled'; -import { Link } from 'react-router-dom'; - -import lightImg from '~/assets/images/light.png'; - -const Section = styled.section` - width: 100%; -`; - -const Container = styled.div` - position: relative; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - background-color: #ff5b15; - padding-top: 80px; - - &::after { - position: absolute; - bottom: 0; - width: calc(100% - 80px); - height: 40px; - content: ''; - opacity: 0.25; - background: linear-gradient(180deg, rgba(255, 92, 22, 0) 9.57%, #ff5d17 90.96%); - } - - ${mq_lg} { - padding-top: 128px; - - &::after { - width: calc(100% - 160px); - height: 160px; - } - } -`; - -const BackgroundLight = styled.div` - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-image: url('${lightImg}'); - background-position: top center; - background-repeat: no-repeat; - background-size: cover; -`; - -const Title = styled.h2` - text-align: center; - white-space: pre-wrap; - color: ${({ theme }) => theme.palette.grey.w}; - ${({ theme }) => theme.typo.point.p4}; - - ${mq_lg} { - white-space: normal; - font-size: 32px; - line-height: 38px; - } -`; - -const Description = styled.p` - text-align: center; - color: #ffc7ae; - ${({ theme }) => theme.typo.b1}; - white-space: pre-wrap; - margin-top: 6px; - - ${mq_lg} { - white-space: normal; - margin-top: 8px; - font-size: 20px; - line-height: 32px; - } -`; - -const Button = styled(Link)` - z-index: 1; - cursor: pointer; - padding: 9px 16px; - border-radius: 4px; - margin-top: 12px; - background-color: #ffe9e0; - color: ${({ theme }) => theme.palette.primary.o1}; - ${({ theme }) => theme.typo.sh1}; - - ${mq_lg} { - padding: 13px 20px; - margin-top: 24px; - } -`; - -const PcAdminPreviewImage = styled.img` - display: none; - ${mq_lg} { - display: block; - width: calc(100% - 160px); - max-width: 1080px; - height: auto; - border-radius: 32px 32px 0px 0px; - margin-top: 80px; - } -`; - -const MobileAdminPrevieImage = styled.img` - margin-top: 32px; - max-width: 320px; - height: auto; - width: calc(100% - 168px); - border-radius: 12px 12px 0px 0px; - ${mq_lg} { - display: none; - } -`; - -export default { - Section, - BackgroundLight, - Container, - Title, - Description, - Button, - PcAdminPreviewImage, - MobileAdminPrevieImage, -}; diff --git a/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx b/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx deleted file mode 100644 index e3cb7665..00000000 --- a/apps/admin/src/pages/Landing/components/OrganizerSection/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import createShowImg from '~/assets/images/create-show.png'; -import manageEnteranceImg from '~/assets/images/manage-entrance.png'; -import mobileAdminPreviewImg from '~/assets/images/mobile-admin-preview.png'; -import pcAdminPreviewImg from '~/assets/images/pc-admin-preview.png'; -import { PATH } from '~/constants/routes'; - -import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; -import FeatureItem from '../FeatureItem'; -import Styled from './OrganizerSection.styles'; - -const OrganizerSection = () => { - const { ref: sectionRef } = useVisibleSectionAtom('organizer'); - return ( - - - - 누구보다 바쁜{'\n'}주최자를 위한 웹 - - 공연을 등록하고 방문자 명단과{'\n'} - 정산된 수익을 한눈에 확인해 보세요 - - 공연 준비하기 - - - - - - - ); -}; - -export default OrganizerSection; diff --git a/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts b/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts new file mode 100644 index 00000000..f8608ce5 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/Problem/Problem.styles.ts @@ -0,0 +1,85 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; + +import { mq_desktop } from '../../constants'; + +const Section = styled.section` + position: relative; + width: 100%; + min-height: 360px; + background-color: #020206; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + + ${mq_lg} { + min-height: 480px; + } + + ${mq_desktop} { + height: 631px; + } +`; + +const Title = styled.h2` + position: relative; + z-index: 2; + text-align: center; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 24px; + line-height: 1.45; + letter-spacing: -0.02em; + color: #ffffff; + white-space: pre-line; + padding: 0 24px; + margin: 0; + + ${mq_lg} { + font-size: 32px; + } + + ${mq_desktop} { + font-size: 40px; + padding: 0; + } +`; + +const FloatingLayer = styled.div` + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 1200px; + height: 100%; + display: none; + pointer-events: none; + + ${mq_desktop} { + display: block; + } +`; + +const FloatingLogo = styled.img<{ + top: number; + left: number; + width: number; + height: number; +}>` + position: absolute; + top: ${({ top }) => top}px; + left: ${({ left }) => left}px; + width: ${({ width }) => width}px; + height: ${({ height }) => height}px; + object-fit: contain; + opacity: 0.55; + user-select: none; +`; + +export default { + Section, + Title, + FloatingLayer, + FloatingLogo, +}; diff --git a/apps/admin/src/pages/Landing/components/Problem/index.tsx b/apps/admin/src/pages/Landing/components/Problem/index.tsx new file mode 100644 index 00000000..00a20169 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/Problem/index.tsx @@ -0,0 +1,37 @@ +import problem1 from '~/assets/landing-v2/problem-1.png'; +import problem2 from '~/assets/landing-v2/problem-2.png'; +import problem3 from '~/assets/landing-v2/problem-3.png'; +import problem4 from '~/assets/landing-v2/problem-4.png'; +import problem5 from '~/assets/landing-v2/problem-5.png'; +import problem6 from '~/assets/landing-v2/problem-6.png'; + +import { LANDING_COPY } from '../../constants'; +import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; +import Styled from './Problem.styles'; + +// Figma Desktop 1200px 절대 좌표 +const FLOATING_LOGOS = [ + { src: problem1, top: 164, left: 178, width: 291.64, height: 70.84 }, + { src: problem2, top: 440, left: 681, width: 291.64, height: 70.84 }, + { src: problem3, top: 370, left: 73.39, width: 287.24, height: 88.1 }, + { src: problem4, top: 55, left: 96, width: 260.97, height: 78.2 }, + { src: problem5, top: 126, left: 779.03, width: 317.95, height: 92.37 }, + { src: problem6, top: 325, left: 877.83, width: 240.59, height: 96.6 }, +] as const; + +const Problem = () => { + const { ref } = useVisibleSectionAtom('problem'); + + return ( + + + {FLOATING_LOGOS.map(({ src, ...pos }, index) => ( + + ))} + + {LANDING_COPY.problem.title} + + ); +}; + +export default Problem; diff --git a/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts b/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts new file mode 100644 index 00000000..2b601da1 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/SolutionFeatures/SolutionFeatures.styles.ts @@ -0,0 +1,97 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; + +import { mq_desktop } from '../../constants'; + +const Section = styled.section` + display: flex; + flex-direction: column; + align-items: center; + align-self: stretch; + gap: 48px; + padding: 80px 20px; + background-color: #ffffff; + + ${mq_lg} { + gap: 56px; + padding: 96px 32px; + } + + ${mq_desktop} { + gap: 64px; + padding: 100px 80px; + } +`; + +const Heading = styled.header` + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + text-align: center; +`; + +const Eyebrow = styled.span` + font-family: Pretendard, sans-serif; + font-weight: 400; + font-size: 18px; + line-height: 1.3; + letter-spacing: -0.04em; + color: #a2a5b4; + + ${mq_lg} { + font-size: 22px; + } + + ${mq_desktop} { + font-size: 26px; + } +`; + +const TitleRow = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 24px; + line-height: 1.35; + letter-spacing: -0.02em; + color: #000000; + + ${mq_lg} { + flex-direction: row; + gap: 12px; + font-size: 34px; + } + + ${mq_desktop} { + font-size: 40px; + } +`; + +const CardList = styled.div` + display: flex; + flex-direction: column; + gap: 56px; + width: 100%; + max-width: 1200px; + margin: 0 auto; + + ${mq_lg} { + gap: 88px; + } + + ${mq_desktop} { + gap: 112px; + } +`; + +export default { + Section, + Heading, + Eyebrow, + TitleRow, + CardList, +}; diff --git a/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx b/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx new file mode 100644 index 00000000..5f557995 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/SolutionFeatures/index.tsx @@ -0,0 +1,50 @@ +import entryAsis from '~/assets/landing-v2/entry-asis.png'; +import entryTobe from '~/assets/landing-v2/entry-tobe.png'; +import notifyAsis from '~/assets/landing-v2/notify-asis.png'; +import notifyTobe from '~/assets/landing-v2/notify-tobe.png'; +import salesAsis from '~/assets/landing-v2/sales-asis.png'; +import salesTobe from '~/assets/landing-v2/sales-tobe.png'; +import statsAsis from '~/assets/landing-v2/stats-asis.png'; +import statsTobe from '~/assets/landing-v2/stats-tobe.png'; + +import { LANDING_COPY } from '../../constants'; +import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; +import FeatureCard from '../FeatureCard'; +import Styled from './SolutionFeatures.styles'; + +const FEATURE_MEDIA = [ + { asis: salesAsis, tobe: salesTobe }, + { asis: notifyAsis, tobe: notifyTobe }, + { asis: entryAsis, tobe: entryTobe }, + { asis: statsAsis, tobe: statsTobe }, +]; + +const SolutionFeatures = () => { + const { ref } = useVisibleSectionAtom('solution-features'); + + return ( + + + {LANDING_COPY.solutionFeatures.eyebrow} + + {LANDING_COPY.solutionFeatures.titleLead} + {LANDING_COPY.solutionFeatures.titleTrail} + + + + {LANDING_COPY.solutionFeatures.items.map((item, index) => ( + + ))} + + + ); +}; + +export default SolutionFeatures; diff --git a/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts b/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts new file mode 100644 index 00000000..c05d2769 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/SolutionHighlight/SolutionHighlight.styles.ts @@ -0,0 +1,272 @@ +import { mq_lg } from '@boolti/ui'; +import styled from '@emotion/styled'; + +import { LANDING_COLORS, mq_desktop } from '../../constants'; + +const Section = styled.section` + display: flex; + flex-direction: column; + align-items: center; + align-self: stretch; + gap: 40px; + padding: 80px 0; + background-color: ${LANDING_COLORS.solutionLightBg}; + + ${mq_lg} { + gap: 56px; + padding: 96px 0; + } + + ${mq_desktop} { + gap: 64px; + padding: 100px 0; + } +`; + +const Title = styled.h2` + text-align: center; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 24px; + line-height: 1.35; + letter-spacing: -0.02em; + color: #000000; + white-space: pre-line; + padding: 0 20px; + margin: 0; + + ${mq_lg} { + font-size: 34px; + } + + ${mq_desktop} { + font-size: 40px; + padding: 0; + } +`; + +const ScrollArea = styled.div` + display: flex; + flex-direction: row; + gap: 16px; + overflow-x: auto; + width: 100%; + padding: 0 20px; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } + + ${mq_lg} { + gap: 16px; + padding: 0 32px; + justify-content: center; + } + + ${mq_desktop} { + padding: 0 80px; + } +`; + +const Card = styled.div<{ variant: 'light' | 'dark' }>` + flex-shrink: 0; + width: 320px; + display: flex; + flex-direction: column; + border-radius: 16px; + overflow: hidden; + border: ${({ variant }) => + variant === 'dark' ? 'none' : `1px solid ${LANDING_COLORS.cardBorder}`}; + background-color: ${({ variant }) => + variant === 'dark' ? LANDING_COLORS.darkCardBg : '#FFFFFF'}; + + ${mq_lg} { + flex-direction: row; + width: 560px; + height: 420px; + } + + ${mq_desktop} { + width: 620px; + height: 480px; + } +`; + +const TextCard = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; + padding: 32px; + background-color: #ffffff; + + ${mq_lg} { + flex: 0 0 55%; + gap: 24px; + padding: 48px 40px; + } + + ${mq_desktop} { + gap: 28px; + padding: 60px 52px; + } +`; + +const Chip = styled.span` + display: inline-flex; + padding: 8px 16px; + border-radius: 200px; + background-color: ${LANDING_COLORS.chipBg}; + color: ${LANDING_COLORS.chipText}; + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 16px; + line-height: 1.3; + + ${mq_lg} { + font-size: 18px; + } + + ${mq_desktop} { + font-size: 24px; + padding: 10px 16px; + } +`; + +const CardTitle = styled.h3` + font-family: Pretendard, sans-serif; + font-weight: 600; + font-size: 24px; + line-height: 1.35; + letter-spacing: -0.02em; + white-space: pre-line; + color: #000000; + margin: 0; + + ${mq_lg} { + font-size: 28px; + } + + ${mq_desktop} { + font-size: 32px; + } +`; + +const CardDescription = styled.p` + font-family: Pretendard, sans-serif; + font-weight: 400; + font-size: 16px; + line-height: 1.5; + color: #a2a5b4; + margin: 0; + + ${mq_lg} { + font-size: 20px; + } + + ${mq_desktop} { + font-size: 24px; + } +`; + +const ImgCard = styled.div<{ variant: 'light' | 'dark' }>` + position: relative; + flex: 1; + min-height: 260px; + overflow: hidden; + background: ${({ variant }) => + variant === 'dark' ? LANDING_COLORS.paymentGradient : LANDING_COLORS.promoGradient}; + + ${mq_lg} { + min-height: 0; + } +`; + +const PromoStack = styled.div` + position: relative; + width: 100%; + height: 100%; + min-height: 260px; +`; + +const PromoImage = styled.img<{ offset: 'back' | 'front' }>` + position: absolute; + width: 55%; + max-width: 180px; + height: auto; + border-radius: 20px; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15); + + ${({ offset }) => + offset === 'back' + ? ` + bottom: -20%; + left: 8%; + transform: rotate(-10deg); + z-index: 1; + ` + : ` + bottom: -32%; + right: 0%; + transform: rotate(6deg); + z-index: 2; + `} + + ${mq_lg} { + max-width: 200px; + + ${({ offset }) => + offset === 'back' + ? ` + bottom: -15%; + left: 8%; + ` + : ` + bottom: -28%; + right: -5%; + `} + } +`; + +const PaymentWrap = styled.div` + display: flex; + justify-content: center; + align-items: flex-end; + width: 100%; + height: 100%; + min-height: 260px; + padding-top: 24px; + + ${mq_lg} { + padding-top: 40px; + } +`; + +const PaymentImage = styled.img` + width: 70%; + max-width: 260px; + height: auto; + border-radius: 28px; + box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2); + + ${mq_desktop} { + max-width: 320px; + } +`; + +export default { + Section, + Title, + ScrollArea, + Card, + TextCard, + Chip, + CardTitle, + CardDescription, + ImgCard, + PromoStack, + PromoImage, + PaymentWrap, + PaymentImage, +}; diff --git a/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx b/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx new file mode 100644 index 00000000..53932a54 --- /dev/null +++ b/apps/admin/src/pages/Landing/components/SolutionHighlight/index.tsx @@ -0,0 +1,41 @@ +import payment from '~/assets/landing-v2/payment.png'; +import promo1 from '~/assets/landing-v2/promo-1.png'; +import promo2 from '~/assets/landing-v2/promo-2.png'; + +import { LANDING_COPY } from '../../constants'; +import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; +import Styled from './SolutionHighlight.styles'; + +const HIGHLIGHT_MEDIA = [ + + + + , + + + , +]; + +const SolutionHighlight = () => { + const { ref } = useVisibleSectionAtom('solution-highlight'); + + return ( + + {LANDING_COPY.solutionHighlight.title} + + {LANDING_COPY.solutionHighlight.items.map((item, index) => ( + + + {item.chip} + {item.title} + {item.description} + + {HIGHLIGHT_MEDIA[index]} + + ))} + + + ); +}; + +export default SolutionHighlight; diff --git a/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts b/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts deleted file mode 100644 index 31c58dba..00000000 --- a/apps/admin/src/pages/Landing/components/Tab/Tab.styles.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { mq_lg } from '@boolti/ui'; -import styled from '@emotion/styled'; -import { m } from 'framer-motion'; - -const Container = styled(m.div)` - display: flex; - justify-content: center; - align-items: center; - height: 48px; - width: 100%; - ${mq_lg} { - height: 64px; - } -`; - -const List = styled.div` - display: flex; - align-items: flex-end; - width: 100%; - height: 100%; - max-width: ${({ theme }) => theme.breakpoint.desktop}; -`; - -const Button = styled.button<{ isActive?: boolean }>` - cursor: pointer; - box-sizing: border-box; - padding: 12px 0; - ${({ theme }) => theme.typo.sh1}; - color: ${({ theme }) => theme.palette.grey.g00}; - - &:not(:first-of-type) { - margin-left: 20px; - } - - border-bottom: 2px solid - ${({ isActive, theme }) => (isActive ? theme.palette.primary.o1 : 'transparent')}; - - ${mq_lg} { - padding: 12px 0 16px 0; - } -`; - -export default { Container, Button, List }; diff --git a/apps/admin/src/pages/Landing/components/Tab/index.tsx b/apps/admin/src/pages/Landing/components/Tab/index.tsx deleted file mode 100644 index b6079d7e..00000000 --- a/apps/admin/src/pages/Landing/components/Tab/index.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { useAtom } from 'jotai'; - -import { visibleSectionAtom } from '../../atoms/visibleSectionAtom'; -import Styled from './Tab.styles'; - -const items = [ - { key: 'organizer', children: '주최자용 웹' }, - { key: 'user', children: '방문자용 앱' }, -] as const; - -const Tab = () => { - const [currentVisibleSection, setCurrentVisibleSection] = useAtom(visibleSectionAtom); - return ( - - - {items.map((item) => ( - { - const element = document.getElementById(item.key); - if (element) { - setCurrentVisibleSection(item.key); - const top = window.scrollY + element.getBoundingClientRect().top - 60; - setTimeout(() => { - window.scrollTo({ top, behavior: 'smooth' }); - }, 0); - } - }} - > - {item.children} - - ))} - - - ); -}; - -export default Tab; diff --git a/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts b/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts deleted file mode 100644 index 3682e9bb..00000000 --- a/apps/admin/src/pages/Landing/components/UserSection/UserSection.styles.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Button as _Button, mq_lg } from '@boolti/ui'; -import styled from '@emotion/styled'; - -const Section = styled.section` - width: 100%; -`; - -const Container = styled.div` - position: relative; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - background-color: ${({ theme }) => theme.palette.mobile.grey.g95}; - padding-top: 80px; - - ${mq_lg} { - padding-top: 128px; - } -`; - -const Title = styled.h2` - text-align: center; - white-space: pre-wrap; - color: ${({ theme }) => theme.palette.grey.w}; - ${({ theme }) => theme.typo.point.p4}; - - ${mq_lg} { - white-space: normal; - font-size: 32px; - line-height: 38px; - } -`; - -const Description = styled.p` - text-align: center; - color: ${({ theme }) => theme.palette.grey.g30}; - ${({ theme }) => theme.typo.b1}; - white-space: pre-wrap; - margin-top: 6px; - - ${mq_lg} { - white-space: normal; - margin-top: 8px; - font-size: 20px; - line-height: 32px; - } -`; - -const Button = styled(_Button)` - cursor: pointer; - margin-top: 12px; - - ${mq_lg} { - margin-top: 24px; - } -`; - -const TicketPreviewImage = styled.img` - display: none; - ${mq_lg} { - display: block; - width: calc(100% - 160px); - max-width: 1080px; - margin-top: 80px; - } -`; - -const MobileTicketPreviewImage = styled.img` - margin-top: 32px; - width: calc(100% - 60px); - display: block; - ${mq_lg} { - display: none; - } -`; - -export default { - Section, - Container, - Title, - Description, - Button, - TicketPreviewImage, - MobileTicketPreviewImage, -}; diff --git a/apps/admin/src/pages/Landing/components/UserSection/index.tsx b/apps/admin/src/pages/Landing/components/UserSection/index.tsx deleted file mode 100644 index 56a02c88..00000000 --- a/apps/admin/src/pages/Landing/components/UserSection/index.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { useTheme } from '@emotion/react'; -import { useNavigate } from 'react-router-dom'; - -import entranceNotificationImg from '~/assets/images/entrance-notification.png'; -import mobileTicketPreivewImg from '~/assets/images/mobile-ticket-preview.png'; -import pcTicketPreviewImg from '~/assets/images/pc-ticket-preview.png'; -import showInfoImg from '~/assets/images/show-info.png'; -import ticketPurchaseImg from '~/assets/images/ticket-purchase.png'; -import { PATH } from '~/constants/routes'; -import { useDeviceWidth } from '~/hooks/useDeviceWidth'; - -import { useVisibleSectionAtom } from '../../atoms/visibleSectionAtom'; -import FeatureItem from '../FeatureItem'; -import Styled from './UserSection.styles'; -import { openStoreLink } from '~/utils/link'; - -const UserSection = () => { - const { ref: sectionRef } = useVisibleSectionAtom('user'); - const navigate = useNavigate(); - const deviceWidth = useDeviceWidth(); - const theme = useTheme(); - const isMobile = deviceWidth < parseInt(theme.breakpoint.mobile, 10); - return ( - - - 빠른 입장을 원하는{'\n'}방문자를 위한 앱 - - 번거로운 티켓 찾기는 이제 그만!{'\n'}앱에서 바로 티켓을 제시해 보세요 - - { - if (isMobile) { - openStoreLink(); - return; - } - navigate(PATH.QR); - }} - > - 앱 바로가기 - - - - - - - - - ); -}; - -export default UserSection; diff --git a/apps/admin/src/pages/Landing/components/index.ts b/apps/admin/src/pages/Landing/components/index.ts index 5e8762d8..e5e1049c 100644 --- a/apps/admin/src/pages/Landing/components/index.ts +++ b/apps/admin/src/pages/Landing/components/index.ts @@ -1,8 +1,9 @@ +import FeatureCard from './FeatureCard'; import Header from './Header'; -import KeyVisual from './KeyVisual'; -import MoreInformation from './MoreInformation'; -import OrganizerSection from './OrganizerSection'; -import Tab from './Tab'; -import UserSection from './UserSection'; +import Hero from './Hero'; +import HowToUse from './HowToUse'; +import Problem from './Problem'; +import SolutionFeatures from './SolutionFeatures'; +import SolutionHighlight from './SolutionHighlight'; -export { Header, KeyVisual, MoreInformation, OrganizerSection, Tab, UserSection }; +export { FeatureCard, Header, Hero, HowToUse, Problem, SolutionFeatures, SolutionHighlight }; diff --git a/apps/admin/src/pages/Landing/constants.ts b/apps/admin/src/pages/Landing/constants.ts new file mode 100644 index 00000000..7755fb08 --- /dev/null +++ b/apps/admin/src/pages/Landing/constants.ts @@ -0,0 +1,78 @@ +export const mq_desktop = '@media (min-width: 1120px)'; + +export const LANDING_COLORS = { + heroGradient: 'linear-gradient(180deg, #131343 0%, #020206 100%)', + heroBottom: '#020206', + solutionLightBg: '#ECEFF3', + chipBg: 'rgba(255, 207, 186, 0.5)', + chipText: '#FF6827', + primaryCta: '#FF6827', + darkButton: '#282B33', + darkButtonText: '#A2A5B4', + darkCardBg: '#A2A5B4', + headerGlass: 'rgba(111, 116, 133, 0.4)', + headerBorder: 'rgba(136, 141, 157, 0.3)', + cardBorder: '#D8DBE5', + promoGradient: 'linear-gradient(180deg, #FFE6DF 0%, #F3F5F9 100%)', + paymentGradient: 'linear-gradient(180deg, #E9EBFE 0%, #F3F5F9 100%)', +} as const; + +export const LANDING_COPY = { + hero: { + eyebrow: '공연 등록 · 판매 · 입장 관리까지', + titleLead: '소규모 공연을 위한', + titleTrail: '올인원 플랫폼,', + }, + problem: { + title: '공연 준비,\n아직도 수작업으로 하시나요?', + }, + solutionFeatures: { + eyebrow: '공연 등록부터 정산까지', + titleLead: '번거로운 일은', + titleTrail: '불티에서 한 번에 해결!', + items: [ + { + chip: '티켓 판매', + title: '입금/환불 걱정 끝', + description: '입금 확인부터 환불 처리까지,\n번거로웠던 모든 과정을 자동으로 처리', + }, + { + chip: '관람안내', + title: '놓칠 걱정 없는 자동 알림 시스템', + description: '일일이 문자를 보내지 않아도\n자동 알림으로 관객이 공연을 놓치지 않게', + }, + { + chip: '입장 관리', + title: '입장은 QR로 빠르게', + description: '번거로운 발권이나 확인 절차 없이\nQR 스캔만으로 대기 없는 입장 가능', + }, + { + chip: '실시간 현황', + title: '실시간 현황을 한눈에', + description: '티켓 판매 현황, 실제 입장 관객 수 등\n주요 정보를 모니터링하고 빠르게 대응', + }, + ], + }, + solutionHighlight: { + title: '링크 하나로 가볍게\n다양한 결제 수단으로 편리하게', + items: [ + { + chip: '공연 홍보', + title: '링크 하나로\n홍보 끝!', + description: '일일이 정보를 첨부할 필요 없이, 링크만 공유하면 공연 홍보 완료', + variant: 'light' as const, + }, + { + chip: '결제/발권', + title: '다양한 결제 수단 지원', + description: '번거로운 입금 대조 과정 없이 실시간으로 티켓 발권 가능', + variant: 'dark' as const, + }, + ], + }, + howToUse: { + title: '불티와 함께 온전히,\n공연과 무대에 집중해 보세요', + primaryCta: '3분만에 끝나는 공연 등록 →', + secondaryCta: '앱 둘러보기', + }, +} as const; diff --git a/apps/admin/src/pages/Landing/index.tsx b/apps/admin/src/pages/Landing/index.tsx index 39bf3c64..98ba59b0 100644 --- a/apps/admin/src/pages/Landing/index.tsx +++ b/apps/admin/src/pages/Landing/index.tsx @@ -1,31 +1,36 @@ import { Footer } from '@boolti/ui'; - -import { Header, KeyVisual, MoreInformation, OrganizerSection, UserSection } from './components'; -import Styled from './LandingPage.styles'; import { usePopup } from '@boolti/api'; + import usePopupDialog from '~/hooks/usePopupDialog'; +import { + Header, + Hero, + HowToUse, + Problem, + SolutionFeatures, + SolutionHighlight, +} from './components'; +import Styled from './LandingPage.styles'; + const LandingPage = () => { const { data: popupData } = usePopup('HOME'); usePopupDialog(popupData); - return ( - <> - -
- - - - - - - - - -