Skip to content

Commit

Permalink
feat: wedding layouts and components
Browse files Browse the repository at this point in the history
  • Loading branch information
jakepro657 committed Feb 6, 2024
1 parent 16ab46c commit 7254e13
Show file tree
Hide file tree
Showing 13 changed files with 419 additions and 4 deletions.
58 changes: 55 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,63 @@
import React from 'react'
import classNames from 'classnames/bind'
import { useEffect, useState } from 'react'
import styles from './App.module.scss'
import Heading from './components/sections/Heading'
import Video from './components/sections/Video'

import FullScreenMessage from './components/shared/FullScreenMessage'
import { Wedding } from './models/wedding'

const cx = classNames.bind(styles)

function App() {
return <div className={cx('container')}></div>
const [wedding, setWedding] = useState<Wedding | null>(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)

useEffect(() => {
setLoading(true)
fetch('http://localhost:8888/wedding')
.then((response) => {
if (response.ok === false) {
throw new Error('청첩장 정보를 가져오는데 실패했습니다.')
}

return response.json()
})
.then((data) => {
setWedding(data)
setLoading(false)
})
.catch((error) => {
console.error('Error:', error)
setError(true)
})
.finally(() => {
setLoading(false)
})
}, [])

if (loading) {
return <FullScreenMessage type="loading" />
}

if (error) {
return <FullScreenMessage type="error" />
}

if (wedding == null) {
return null
}

const { date } = wedding

return (
<div className={cx('container')}>
<Heading date={date} />
<Video />
{JSON.stringify(wedding)}
</div>
)
}

export default App
export default App
14 changes: 14 additions & 0 deletions src/components/sections/Heading.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.container {
background-color: antiquewhite;
text-align: center;
font-weight: bold;

.txt-date {
font-size: 30px;
margin-bottom: 8px;
}

.txt-day {
font-size: 17px;
}
}
32 changes: 32 additions & 0 deletions src/components/sections/Heading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { parseISO, format, getDay } from 'date-fns'
import classNames from 'classnames/bind'
import styles from './Heading.module.scss'

import Section from '../shared/Section'

const cx = classNames.bind(styles)

const DAYS = [
'SUNDAY',
'MONDAY',
'TUESDAY',
'WEDNESDAY',
'THURSDAY',
'FRIDAY',
'SATURDAY',
]

function Heading({ date }: { date: string }) {
const weddingDate = parseISO(date)

return (
<Section className={cx('container')}>
<div className={cx('txt-date')}>
{format(weddingDate, 'yy.MM.dd')}
</div>
<div className={cx('txt-day')}>{DAYS[getDay(weddingDate)]}</div>
</Section>
)
}

export default Heading
Empty file.
9 changes: 9 additions & 0 deletions src/components/sections/Video.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Section from '../shared/Section'

// const cx = classNames.bind(styles)

function Video() {
return <Section>Heading</Section>
}

export default Video
42 changes: 42 additions & 0 deletions src/components/shared/FullScreenMessage.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.container {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;

display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.icon-heart {
fill: var(--red);
width: 60px;
height: 60px;

animation: heart 1.2s infinite linear;
}

@keyframes heart {
0% {
transform: scale(0.95);
}
5% {
transform: scale(1.1);
}
38% {
transform: scale(0.85);
}
45% {
transform: scale(1);
}
60% {
transform: scale(0.95);
}
100% {
transform: scale(0.9);
}
}

60 changes: 60 additions & 0 deletions src/components/shared/FullScreenMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import styles from './FullScreenMessage.module.scss'
import classNames from 'classnames/bind'

const cx = classNames.bind(styles)

interface FullScreenMessageProps {
type: 'loading' | 'error'
}

function FullScreenMessage({ type }: FullScreenMessageProps) {
return (
<div className={cx('container')}>
{type === 'loading' ? (
<Heart />
) : (
<>
<Error />
에러가 발생했어요. 잠시 후 다시 시도해주세요.
</>
)}
</div>
)
}

function Heart() {
return (
<svg
className={cx('icon-heart')}
height="512px"
version="1.1"
viewBox="0 0 512 512"
width="512px"
xmlns="http://www.w3.org/2000/svg"
>
<g id="_x31_66_x2C__Heart_x2C__Love_x2C__Like_x2C__Twitter">
<g>
<path d="M365.4,59.628c60.56,0,109.6,49.03,109.6,109.47c0,109.47-109.6,171.8-219.06,281.271 C146.47,340.898,37,278.568,37,169.099c0-60.44,49.04-109.47,109.47-109.47c54.73,0,82.1,27.37,109.47,82.1 C283.3,86.999,310.67,59.628,365.4,59.628z" />
</g>
</g>
<g id="Layer_1" />
</svg>
)
}

function Error() {
return (
<svg
className={cx('icon-error')}
height="48"
viewBox="0 0 48 48"
width="48"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M0 0h48v48H0V0z" fill="none" />
<path d="M22 30h4v4h-4zm0-16h4v12h-4zm1.99-10C12.94 4 4 12.95 4 24s8.94 20 19.99 20S44 35.05 44 24 35.04 4 23.99 4zM24 40c-8.84 0-16-7.16-16-16S15.16 8 24 8s16 7.16 16 16-7.16 16-16 16z" />
</svg>
)
}

export default FullScreenMessage
3 changes: 3 additions & 0 deletions src/components/shared/Section.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.container {
padding: 24px;
}
18 changes: 18 additions & 0 deletions src/components/shared/Section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import classNames from 'classnames/bind'
import React from 'react'
import styles from './Section.module.scss'

type Props = {
className?: string
children: React.ReactNode
}

const cx = classNames.bind(styles)

function Section({ children, className }: Props) {
return (
<section className={cx(['container', className])}>{children}</section>
)
}

export default Section
1 change: 0 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import App from './App'
import reportWebVitals from './reportWebVitals'
import './scss/global.scss'
Expand Down
38 changes: 38 additions & 0 deletions src/models/wedding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
export interface Wedding {
id: number
date: string
location: Location

message: {
intro: string
invitation: string
}

galleryImages: string[]
attendCount: number

groom: Person & { parents: Person[] }
bride: Person & { parents: Person[] }
}

export interface Location {
lat: number
lng: number
name: string
link: string
waytocome: {
metro: string[]
bus: string[]
}
}

export interface Account {
bankName: string
accountNumber: string
}

export interface Person {
name: string
phoneNumber: string
account: Account
}
13 changes: 13 additions & 0 deletions src/scss/global.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
@charset "utf-8";

@import url('./reset.scss');

:root {
--red: #ea7664;
--black: #544f4f;
--brown: #89757a;
--beige: #f6f5f5;
}

@font-face {
font-family: 'omyu_pretty';
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/[email protected]/omyu_pretty.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

body {
font-family: 'omyu_pretty', sans-serif;
}
Loading

0 comments on commit 7254e13

Please sign in to comment.