diff --git a/src/App.tsx b/src/App.tsx index 39b22502..6eeb380a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,6 +6,7 @@ import { Header } from "./marketing/Header"; import { How } from "./marketing/How"; import { Mission } from "./marketing/Mission"; import { Navigation } from "./marketing/Navigation"; +import { Team } from "./marketing/Team"; function App() { const scrollToSection = useCallback((sectionId: string) => { @@ -56,6 +57,7 @@ function App() { + > ); diff --git a/src/assets/images/marketing/team/github-dark.webp b/src/assets/images/marketing/team/github-dark.webp new file mode 100644 index 00000000..5d624b4c Binary files /dev/null and b/src/assets/images/marketing/team/github-dark.webp differ diff --git a/src/assets/images/marketing/team/github-light.webp b/src/assets/images/marketing/team/github-light.webp new file mode 100644 index 00000000..e03ad570 Binary files /dev/null and b/src/assets/images/marketing/team/github-light.webp differ diff --git a/src/assets/images/marketing/team/linkedIn-dark.webp b/src/assets/images/marketing/team/linkedIn-dark.webp new file mode 100644 index 00000000..f9f9e36c Binary files /dev/null and b/src/assets/images/marketing/team/linkedIn-dark.webp differ diff --git a/src/assets/images/marketing/team/linkedIn-light.webp b/src/assets/images/marketing/team/linkedIn-light.webp new file mode 100644 index 00000000..41318e81 Binary files /dev/null and b/src/assets/images/marketing/team/linkedIn-light.webp differ diff --git a/src/marketing/Team.stories.tsx b/src/marketing/Team.stories.tsx new file mode 100644 index 00000000..727f5060 --- /dev/null +++ b/src/marketing/Team.stories.tsx @@ -0,0 +1,21 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { Team } from "./Team"; + +const meta = { + title: "Marketing/Team", + component: Team, + parameters: { + layout: "fullscreen", + docs: { + story: { + inline: false, + iframeHeight: 900, + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/src/marketing/Team.tsx b/src/marketing/Team.tsx new file mode 100644 index 00000000..d1287718 --- /dev/null +++ b/src/marketing/Team.tsx @@ -0,0 +1,389 @@ +import { useEffect, useState } from "react"; +import { css } from "../../styled-system/css"; +import githubLightIcon from "../assets/images/marketing/team/github-light.webp"; +import githubDarkIcon from "../assets/images/marketing/team/github-dark.webp"; +import linkedInLightIcon from "../assets/images/marketing/team/linkedIn-light.webp"; +import linkedInDarkIcon from "../assets/images/marketing/team/linkedIn-dark.webp"; + +import { Card } from "../components/Card/Card"; +import { Flex } from "../components/Flex/Flex"; +import { Heading } from "../components/Heading/Heading"; +import { HStack } from "../components/HStack/HStack"; +import { Link } from "../components/Link/Link"; +import { Tag } from "../components/Tag/Tag"; +import { Text } from "../components/Text/Text"; +import { VStack } from "../components/VStack/VStack"; + +export interface TeamMember { + /** 팀원 이름 */ + name: string; + /** 역할 */ + role: string; + /** 국기 이모지 (예: 🇰🇷, 🇨🇦, 🇺🇸) */ + flag?: string; + /** 장소 (예: 서울, 토론토) */ + location: string; + /** 프로필 이미지 (없으면 기본 아바타 표시) */ + avatar?: string; + /** GitHub URL */ + githubUrl?: string; + /** LinkedIn URL */ + linkedinUrl?: string; +} + +interface TeamCardProps { + member: TeamMember; + isDark: boolean; +} + +function TeamCard({ member, isDark }: TeamCardProps) { + const { name, role, flag, location, avatar, githubUrl, linkedinUrl } = member; + + return ( + + + + {avatar ? ( + + ) : ( + + + + + + + + + + + + )} + + + + {name} + + + + {flag && {flag} } + {location} + + + | + + + {role} + + + + + + {githubUrl && ( + + + + )} + {linkedinUrl && ( + + + + )} + + + ); +} + +export interface TeamProps { + members?: TeamMember[]; +} + +const Members: TeamMember[] = [ + { + name: "달레", + role: "Engineer", + flag: "🇨🇦", + location: "Toronto", + githubUrl: "https://github.com/DaleSeo", + linkedinUrl: "https://www.linkedin.com/in/daleseo/", + avatar: "https://avatars.githubusercontent.com/u/5466341", + }, + { + name: "Helena", + role: "Engineer", + flag: "🇨🇦", + location: "Toronto", + githubUrl: "https://github.com/yolophg", + linkedinUrl: "https://www.linkedin.com/in/yolophg/", + avatar: "https://avatars.githubusercontent.com/u/38199103", + }, + { + name: "Evan (에반)", + role: "Engineer", + flag: "🇨🇦", + location: "Toronto", + githubUrl: "https://github.com/sounmind", + linkedinUrl: "https://www.linkedin.com/in/suhyeong-evan-lee/", + avatar: "https://avatars.githubusercontent.com/u/37020415", + }, + { + name: "hyoseong", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + avatar: "https://avatars.githubusercontent.com/u/50227228", + githubUrl: "https://github.com/hyoseong1994", + linkedinUrl: "https://www.linkedin.com/in/hyoseong1994/", + }, + { + name: "Ria (리아)", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + avatar: "https://avatars.githubusercontent.com/u/83909755", + githubUrl: "https://github.com/RiaOh", + linkedinUrl: "https://www.linkedin.com/in/riaoh/", + }, + { + name: "살미", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + githubUrl: "https://github.com/Lustellz", + linkedinUrl: "https://www.linkedin.com/in/tasha0417/", + avatar: "https://avatars.githubusercontent.com/u/45252527", + }, + { + name: "은지", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + githubUrl: "https://github.com/y00eunji", + linkedinUrl: "https://www.linkedin.com/in/y00eunji/", + avatar: "https://avatars.githubusercontent.com/u/27201591", + }, + { + name: "한샘", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + avatar: "https://avatars.githubusercontent.com/u/51806574", + githubUrl: "https://github.com/Hecklebot", + linkedinUrl: "https://www.linkedin.com/in/hansaem-so/", + }, + { + name: "Aka (아카)", + role: "Engineer", + flag: "🇰🇷", + location: "Seoul", + githubUrl: "https://github.com/HowToBeAHappyBoy", + linkedinUrl: "https://www.linkedin.com/in/seozi/", + avatar: "https://avatars.githubusercontent.com/u/30362922", + }, + { + name: "승현", + role: "Designer", + flag: "🇰🇷", + location: "Seoul", + githubUrl: "https://github.com/sseung30", + linkedinUrl: undefined, + avatar: "https://avatars.githubusercontent.com/u/69985950", + }, + { + name: "자혜", + role: "Designer", + flag: "🇰🇷", + location: "Seoul", + githubUrl: "https://github.com/jj5u", + linkedinUrl: undefined, + avatar: "https://avatars.githubusercontent.com/u/89135410", + }, +]; + +export function Team({ members = Members }: TeamProps) { + const [isDark, setIsDark] = useState(() => { + const el = document.documentElement; + return el.classList.contains("dark"); + }); + + useEffect(() => { + const el = document.documentElement; + + const updateThemeState = () => { + const hasDarkClass = el.classList.contains("dark"); + setIsDark(hasDarkClass); + }; + + const observer = new MutationObserver(updateThemeState); + observer.observe(el, { + attributes: true, + }); + + return () => observer.disconnect(); + }, []); + + return ( + + + + 팀 소개 + + 함께 성장하고 있는 달레 UI 팀을 소개합니다. + + + + {members.map((member) => ( + + ))} + + + + ); +}