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

feat(함수랑피플): hello world #2

Merged
merged 3 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions apps/people-1/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/** @type {import('eslint').Linter.Config} */
module.exports = {
root: true,
extends: [
'@hamsurang/eslint-config/react-ts',
'plugin:@next/next/recommended',
],
parserOptions: {
tsconfigRootDir: __dirname,
project: 'tsconfig.json',
},
rules: {
'@next/next/no-img-element': 'off',
},
}
36 changes: 36 additions & 0 deletions apps/people-1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
23 changes: 23 additions & 0 deletions apps/people-1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "@hamsurang/people-1",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"next": "^14.1.3"
},
"devDependencies": {
"@hamsurang/eslint-config": "workspace:*",
"@hamsurang/tsconfig": "workspace:*",
"@types/react": "^18.2.65",
"@types/react-dom": "^18.2.21",
"eslint-config-next": "^14.1.3"
}
}
16 changes: 16 additions & 0 deletions apps/people-1/public/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions apps/people-1/src/app/layout.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.html {
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
}

.body {
height: 100%;
}

.header {
padding: 26px;
}
32 changes: 32 additions & 0 deletions apps/people-1/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Metadata } from 'next'
import '~/styles/reset.css'
import styles from './layout.module.css'

const NOTION_URL =
'https://hamsurang.notion.site/4ec7716aa5354fc280cac5aa70a2800b'

export const metadata = {
title: '함수랑피플',
metadataBase: new URL(NOTION_URL),
description: '함수랑산악회 멤버를 소개합니다',
keywords: ['함수랑산악회', '프론트엔드', '함수랑피플'],
applicationName: '함수랑피플',
generator: 'Next.js',
} satisfies Metadata

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html className={styles.html} lang="ko">
<body className={styles.body}>
<header className={styles.header}>
<img src="/logo.svg" alt="함수랑산악회 로고" />
</header>
{children}
</body>
</html>
)
}
5 changes: 5 additions & 0 deletions apps/people-1/src/app/page.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.main {
display: flex;
align-items: center;
justify-content: center;
}
10 changes: 10 additions & 0 deletions apps/people-1/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import styles from './page.module.css'
import { CardList } from '~/components/client'

export default function Home() {
return (
<main className={styles.main}>
<CardList />
</main>
)
}
81 changes: 81 additions & 0 deletions apps/people-1/src/components/client/Card/Card.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.card {
position: relative;
width: 300px;
height: 420px;
background-color: black;
border-radius: 10px;
overflow: hidden;
box-sizing: border-box;
cursor: pointer;
transition: transform 0.3s ease;
display: flex;
flex-direction: column;
color: #efefef;
padding: 20px;
gap: 8px;
}

.card h3 {
font-weight: 700;
font-size: 20px;
}

.card img {
width: 100%;
border-radius: 5px;
}

.card figcaption {
padding-top: 6px;
}

.shine,
.glare {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}

.shine {
background: linear-gradient(
120deg,
rgba(255, 255, 255, 0) 25%,
rgba(255, 255, 255, 0.2) 50%,
rgba(255, 255, 255, 0) 75%
);
background-size: 200% 100%;
animation: shine 15s infinite;
opacity: 0.2;
}
.glare {
background-image: radial-gradient(
circle,
rgba(255, 255, 255, 0.6) 0%,
rgba(255, 255, 255, 0) 80%
);
background-size: 200% 200%;
opacity: 0.5;
transition: opacity 0.3s ease-in-out;
animation: glare 3s ease-in-out infinite;
}

@keyframes shine {
0% {
background-position: 200% 0;
}
to {
background-position: -200% 0;
}
}
@keyframes glare {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 0.5;
}
}
52 changes: 52 additions & 0 deletions apps/people-1/src/components/client/Card/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useRef } from 'react'
import styles from './Card.module.css'

interface CardProps {
name: string
imageSrc: string
description: string
}

export const Card = ({ name, imageSrc, description }: CardProps) => {
const cardRef = useRef<HTMLDivElement>(null)

const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
if (!cardRef.current) return

const { clientX, clientY } = e
const { left, top, width, height } = cardRef.current.getBoundingClientRect()
const x = (clientX - left) / width - 0.5
const y = (clientY - top) / height - 0.5
cardRef.current.style.transform = `rotateY(${x * 45}deg) rotateX(${-y * 45}deg)`
}

const handleMouseLeave = () => {
if (cardRef.current) {
cardRef.current.style.transform = ''
}
}

const handleClick = () => {
if (cardRef.current) {
cardRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
}

return (
<figure
className={styles.card}
onClick={handleClick}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
ref={cardRef}
tabIndex={0}
aria-label={`Card for ${name}`}
>
<h3>{name}</h3>
<img src={imageSrc} alt={name} />
<figcaption>{description}</figcaption>
<div className={styles.shine} />
<div className={styles.glare} />
</figure>
)
}
27 changes: 27 additions & 0 deletions apps/people-1/src/components/client/CardList/CardList.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.card-list {
display: flex;
overflow-x: auto;
scrollbar-width: none;
padding: 52px 26px;
}

.card-list::-webkit-scrollbar {
display: none;
}

.card-list li {
transition: transform 0.3s ease;
}

.card-list li:not(:first-child) {
margin-left: -60px;
}

.card-list li:hover {
transform: scale(1.1);
z-index: 1;
}

.card-list li:hover ~ li {
transform: translateX(10%);
}
15 changes: 15 additions & 0 deletions apps/people-1/src/components/client/CardList/CardList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Card } from '../Card/Card'
import styles from './CardList.module.css'
import { profile } from '~/constants/profile'

export const CardList = () => {
return (
<ul className={styles['card-list']}>
{profile.map((user) => (
<li key={user.name}>
<Card {...user} />
</li>
))}
</ul>
)
}
4 changes: 4 additions & 0 deletions apps/people-1/src/components/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
'use client'

export * from './Card/Card'
export * from './CardList/CardList'
47 changes: 47 additions & 0 deletions apps/people-1/src/constants/profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export const profile = [
{
name: '웨일',
imageSrc: 'https://avatars.githubusercontent.com/u/71202076?v=4',
description: '오늘 칼국수를 먹었습니다.',
},
{
name: '쏘니',
imageSrc: 'https://avatars.githubusercontent.com/u/47546413?v=4',
description: '후후.. 헬린이여서 3대 30입니다.',
},
{
name: '민수르',
imageSrc: 'https://avatars.githubusercontent.com/u/40910757?v=4',
description: '꾸준히 하는거 잘합니다.',
},
{
name: '민초당',
imageSrc: 'https://avatars.githubusercontent.com/u/90169703?v=4',
description: '세상사에 다양하게 관심이 많습니다.',
},
{
name: '마누',
imageSrc: 'https://avatars.githubusercontent.com/u/61593290?v=4',
description: '지속적인 플러팅 ENTP입니다.',
},
{
name: '쿼카',
imageSrc: 'https://avatars.githubusercontent.com/u/57122180?v=4',
description: '단축키 진짜 많이 압니다.',
},
{
name: '퉁이리',
imageSrc: 'https://avatars.githubusercontent.com/u/77133565?v=4',
description: '토마토 스파게티 좋아합니다.',
},
{
name: '모리',
imageSrc: 'https://avatars.githubusercontent.com/u/89721027?v=4',
description: '좋아하는 음식은 대부분 다 좋아합니다.',
},
{
name: '쉽',
imageSrc: 'https://avatars.githubusercontent.com/u/43772082?v=4',
description: '클라이밍 1년째 하지만, 여전히 초보에서 벗어나지 못합니다.',
},
]
Loading
Loading