diff --git a/public/images/members/152.png b/public/images/members/152.png
new file mode 100644
index 00000000..72710449
Binary files /dev/null and b/public/images/members/152.png differ
diff --git a/public/images/members/174.png b/public/images/members/174.png
new file mode 100644
index 00000000..34f75121
Binary files /dev/null and b/public/images/members/174.png differ
diff --git a/public/images/members/209.png b/public/images/members/209.png
new file mode 100644
index 00000000..cfe76147
Binary files /dev/null and b/public/images/members/209.png differ
diff --git a/public/images/members/246.png b/public/images/members/246.png
new file mode 100644
index 00000000..0ae996b7
Binary files /dev/null and b/public/images/members/246.png differ
diff --git a/public/images/members/291.png b/public/images/members/291.png
new file mode 100644
index 00000000..518cd757
Binary files /dev/null and b/public/images/members/291.png differ
diff --git a/public/images/members/354.png b/public/images/members/354.png
new file mode 100644
index 00000000..d6312779
Binary files /dev/null and b/public/images/members/354.png differ
diff --git a/public/images/members/387.png b/public/images/members/387.png
new file mode 100644
index 00000000..66f07452
Binary files /dev/null and b/public/images/members/387.png differ
diff --git a/public/images/members/408.png b/public/images/members/408.png
new file mode 100644
index 00000000..fe4ab66d
Binary files /dev/null and b/public/images/members/408.png differ
diff --git a/public/images/members/49.png b/public/images/members/49.png
new file mode 100644
index 00000000..05a4929a
Binary files /dev/null and b/public/images/members/49.png differ
diff --git a/public/images/members/57.png b/public/images/members/57.png
new file mode 100644
index 00000000..05a2cb2d
Binary files /dev/null and b/public/images/members/57.png differ
diff --git a/public/images/members/80.png b/public/images/members/80.png
new file mode 100644
index 00000000..f8087529
Binary files /dev/null and b/public/images/members/80.png differ
diff --git a/src/assets/icons/ic_github.svg b/src/assets/icons/ic_github.svg
new file mode 100644
index 00000000..35fc3351
--- /dev/null
+++ b/src/assets/icons/ic_github.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/icons/ic_linkedin.svg b/src/assets/icons/ic_linkedin.svg
new file mode 100644
index 00000000..2e36a0f4
--- /dev/null
+++ b/src/assets/icons/ic_linkedin.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/icons/ic_school.svg b/src/assets/icons/ic_school.svg
new file mode 100644
index 00000000..e0beb67f
--- /dev/null
+++ b/src/assets/icons/ic_school.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/lib/api/mock/about.ts b/src/lib/api/mock/about.ts
index 3f643275..db96e16e 100644
--- a/src/lib/api/mock/about.ts
+++ b/src/lib/api/mock/about.ts
@@ -51,18 +51,112 @@ const getAboutInfo = async (): Promise => ({
},
});
-const getMemberInfo = async (part?: Part): Promise => ({
- members: Array.from({ length: 12 }, () =>
- (part ? [part] : [Part.PLAN, Part.ANDROID, Part.DESIGN, Part.IOS, Part.SERVER, Part.WEB]).map(
- (part) => ({
- id: Math.floor(Math.random() * 200),
- name: '이주함',
- description: `2023년 현존하는 최고의 ${part}`,
- part,
- src: SRC,
- }),
- ),
- ).flat(),
+const getMemberInfo = async (): Promise => ({
+ members: [
+ {
+ id: 80,
+ name: '양정윤',
+ position: '회장',
+ currentProject: 'palmspring',
+ description: '알은 세계이다. 태어나려는 자는 세계를 부숴야 한다.',
+ imageSrc: '/images/members/80.png',
+ gmail: 'oilburner0320@gmail.com',
+ },
+ {
+ id: 291,
+ name: '김대덕',
+ position: '부회장',
+ currentProject: 'palmspring',
+ imageSrc: '/images/members/291.png',
+ gmail: 'psalm1266@gmail.com',
+ },
+ {
+ id: 49,
+ name: '이호재',
+ position: '총무',
+ currentProject: 'ZOOC',
+ description: '함께 성장하는 환경',
+ imageSrc: '/images/members/49.png',
+ gmail: 'artjr97@naver.com',
+ },
+ {
+ id: 246,
+ name: '김해린',
+ position: '미디어 팀장',
+ currentProject: '타투어',
+ description: '순간의 감정까지 쌓이도록 온 마음을 담아 기록합니다',
+ imageSrc: '/images/members/246.png',
+ gmail: 'gogolyn@gmail.com',
+ linkedin: '해린-김-bb4a8027a',
+ },
+ {
+ id: 354,
+ name: '이승준',
+ position: '운영 팀장',
+ currentProject: '엄빠도 어렸다',
+ description: '안녕하세요',
+ imageSrc: '/images/members/354.png',
+ gmail: 'tmdwns0527@gmail.com',
+ },
+ {
+ id: 408,
+ name: '서지원',
+ position: '기획 파트장',
+ currentProject: 'ASAP',
+ description: '프로덕트 성공에 대한 모든 책임을 질 것',
+ imageSrc: '/images/members/408.png',
+ gmail: 'smallbae99@gmail.com',
+ },
+ {
+ id: 174,
+ name: '김채현',
+ position: '디자인 파트장',
+ currentProject: '타투어',
+ imageSrc: '/images/members/174.png',
+ gmail: 'elina001106@gmail.com',
+ },
+ {
+ id: 57,
+ name: '이태희',
+ position: '안드로이드 파트장',
+ currentProject: 'SPARKLE',
+ description: '안드로이드 그 자체가 되고 싶은 남자',
+ imageSrc: '/images/members/57.png',
+ gmail: 't9h9@naver.com',
+ github: 'taeheeL',
+ linkedin: '태희-이-b4988a272',
+ },
+ {
+ id: 387,
+ name: '박익범',
+ position: 'iOS 파트장',
+ currentProject: 'SPARKLE',
+ imageSrc: '/images/members/387.png',
+ gmail: 'pibum@naver.com',
+ github: 'parkikbum',
+ },
+ {
+ id: 209,
+ name: '김서현',
+ position: '웹 파트장',
+ currentProject: 'palmspring',
+ description: '사용자를 생각하는 개발자',
+ imageSrc: '/images/members/209.png',
+ gmail: 'seobbangway@ewhain.net',
+ github: 'seobbang',
+ linkedin: 'seohyun-kim-9784ab29a',
+ },
+ {
+ id: 152,
+ name: '최윤한',
+ position: '서버 파트장',
+ currentProject: '스밈, 포포리, 캐쳡',
+ description: '아슈파',
+ imageSrc: '/images/members/152.png',
+ gmail: 'unusualc@likelion.org',
+ github: 'unanchoi',
+ },
+ ],
});
const getStudyInfo = async (): Promise => ({
diff --git a/src/lib/api/remote/about.ts b/src/lib/api/remote/about.ts
index 840eb508..3e3833d2 100644
--- a/src/lib/api/remote/about.ts
+++ b/src/lib/api/remote/about.ts
@@ -4,11 +4,11 @@ import {
GetMembersInfoResponse,
GetStudyInfoResponse,
} from '@src/lib/types/about';
-import { CoreValueResponseDto, MemberResponseDto, StudyResponseDto } from '@src/lib/types/dto';
+import { CoreValueResponseDto, StudyResponseDto } from '@src/lib/types/dto';
import { Part } from '@src/lib/types/universal';
import { parseStringToPart } from '@src/lib/utils/parseStringToPart';
import axios from 'axios';
-import qs from 'qs';
+import { mockAboutAPI } from '../mock/about';
const client = axios.create({
baseURL: BASE_URL,
@@ -51,43 +51,8 @@ const getAboutInfo = async (): Promise => {
};
};
-const partToFilterParam: Record = {
- PLAN: 1,
- DESIGN: 2,
- WEB: 3,
- SERVER: 4,
- ANDROID: 5,
- iOS: 6,
-};
-
-const getMemberInfoParams = (part?: Part): { filter?: number; generation: number } => {
- const generation = 32;
-
- if (!part) return { generation };
-
- const filter = partToFilterParam[part];
-
- return { filter, generation };
-};
-
-const getMemberInfo = async (part?: Part): Promise => {
- const parameter = qs.stringify(getMemberInfoParams(part));
-
- const {
- data: { members },
- } = await client.get<{ members: MemberResponseDto[] }>(`/member?${parameter}`);
-
- return {
- members: members
- .filter((member) => member.name && member.part)
- .map((member) => ({
- id: member.id,
- name: member.name,
- description: member.introduction,
- part: member.part,
- src: member.profileImage,
- })),
- };
+const getMemberInfo = async (): Promise => {
+ return mockAboutAPI.getMemberInfo(); // todo : implement server connection
};
const getStudyInfo = async (): Promise => {
diff --git a/src/lib/types/about.ts b/src/lib/types/about.ts
index a5b29771..41b07bfd 100644
--- a/src/lib/types/about.ts
+++ b/src/lib/types/about.ts
@@ -9,11 +9,29 @@ export interface CoreValueType {
export interface MemberType {
id: number;
name: string;
+ position: PositionType;
+ currentProject: string;
description?: string;
- part: string;
- src?: string;
+ imageSrc?: string;
+ gmail?: string;
+ linkedin?: string;
+ github?: string;
}
+export type PositionType =
+ | '회장'
+ | '부회장'
+ | '총무'
+ | '미디어 팀장'
+ | '운영 팀장'
+ | '기획 파트장'
+ | '디자인 파트장'
+ | '안드로이드 파트장'
+ | 'iOS 파트장'
+ | '웹 파트장'
+ | '서버 파트장'
+ | '';
+
export interface AboutInfoType {
generation: number;
title: string;
@@ -56,7 +74,7 @@ export interface GetStudyInfoResponse {
export interface AboutAPI {
getAboutInfo(): Promise;
- getMemberInfo(part?: Part): Promise;
+ getMemberInfo(): Promise;
getStudyInfo(generation?: number): Promise;
}
diff --git a/src/pages/about.tsx b/src/pages/about.tsx
index 7fe4b6f8..872c03b0 100644
--- a/src/pages/about.tsx
+++ b/src/pages/about.tsx
@@ -22,11 +22,11 @@ const AboutPage = ({ aboutInfo }: InferGetServerSidePropsType
+
-
);
diff --git a/src/views/AboutPage/components/Member/Card/index.tsx b/src/views/AboutPage/components/Member/Card/index.tsx
index fb326719..16a5f2bc 100644
--- a/src/views/AboutPage/components/Member/Card/index.tsx
+++ b/src/views/AboutPage/components/Member/Card/index.tsx
@@ -1,22 +1,59 @@
+import { ReactComponent as IcGithub } from '@src/assets/icons/ic_github.svg';
+import { ReactComponent as IcLinkedin } from '@src/assets/icons/ic_linkedin.svg';
+import { ReactComponent as IcMail } from '@src/assets/icons/mail.svg';
import NullImage from '@src/assets/images/null_image.png';
+import { PositionType } from '@src/lib/types/about';
import * as St from './style';
type MeberCardProps = {
- imgSrc?: string;
name: string;
+ position: PositionType;
description?: string;
- part: string;
+ currentProject: string;
+ imageSrc?: string;
+ gmail?: string;
+ linkedin?: string;
+ github?: string;
};
-const MemberCard = ({ imgSrc, name, description, part }: MeberCardProps) => {
+const MemberCard = ({
+ name,
+ position,
+ description,
+ currentProject,
+ imageSrc,
+ gmail,
+ linkedin,
+ github,
+}: MeberCardProps) => {
return (
-
+
- {name}
+
+ {position}
+ {name}
+
+ {currentProject}
{description || '-'}
- {part}
+
+ {gmail && (
+
+
+
+ )}
+ {linkedin && (
+
+
+
+ )}
+ {github && (
+
+
+
+ )}
+
);
};
diff --git a/src/views/AboutPage/components/Member/Card/style.ts b/src/views/AboutPage/components/Member/Card/style.ts
index 28c7327d..a5b8239d 100644
--- a/src/views/AboutPage/components/Member/Card/style.ts
+++ b/src/views/AboutPage/components/Member/Card/style.ts
@@ -1,36 +1,29 @@
import styled from '@emotion/styled';
+import { colors } from '@sopt-makers/colors';
import Image from 'next/image';
-import { textSingularLineEllipsis } from '@src/lib/styles/textEllipsis';
+import icSchool from '@src/assets/icons/ic_school.svg';
export const Card = styled.article`
display: flex;
flex-direction: column;
align-items: center;
- width: 270px;
- height: 400px;
+ height: 484px;
- margin-bottom: 60px;
- padding: 38px 49px;
+ padding: 30px 0;
background: #000000;
border-radius: 10px;
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- width: 209px;
- height: 300px;
-
- margin-bottom: 40px;
- padding: 26px 40px;
+ @media (max-width: 768px) and (min-width: 428px) {
+ height: 377px;
+ padding: 26px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- width: 160px;
- height: 265px;
-
- margin-bottom: 32px;
- padding: 18px 17px;
+ @media (max-width: 427.9px) {
+ height: 214px;
+ padding: 12px 0;
}
`;
@@ -48,91 +41,192 @@ export const ImageWrapper = styled.div`
overflow: hidden;
/* 태블릿, 모바일 뷰 */
- @media (max-width: 1199px) {
- width: 126px;
- height: 126px;
+ @media (max-width: 768px) and (min-width: 428px) {
+ width: 120px;
+ height: 120px;
+ }
+ /* 태블릿, 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ width: 80px;
+ height: 80px;
}
`;
-export const Name = styled.strong`
- ${textSingularLineEllipsis}
- width: 100%;
- text-align: center;
+export const NameWrapper = styled.div`
+ display: flex;
+ gap: 4px;
+ align-items: center;
+ justify-content: center;
+ margin-top: 40px;
- margin-top: 24px;
+ /* 태블릿 뷰 */
+ @media (max-width: 768px) and (min-width: 428px) {
+ margin-top: 30px;
+ gap: 3px;
+ }
+ /* 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ margin-top: 18px;
+ gap: 2px;
+ }
+`;
- font-weight: 700;
- font-size: 28px;
+export const Position = styled.span`
+ padding: 6px 7px;
+ color: ${colors.white};
- color: #ffffff;
+ text-align: center;
+ font-size: 17px;
+ font-weight: 600;
+ line-height: 26px; /* 152.941% */
+ letter-spacing: -0.34px;
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- margin-top: 16px;
-
- font-size: 18px;
+ @media (max-width: 768px) and (min-width: 428px) {
+ padding: 4px;
+ font-size: 12.413px;
+ line-height: 18.984px; /* 152.941% */
+ letter-spacing: -0.248px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- margin-top: 16px;
-
- font-size: 16px;
+ @media (max-width: 427.9px) {
+ padding: 3px;
+ font-size: 7.535px;
+ line-height: 11.524px; /* 152.941% */
+ letter-spacing: -0.151px;
}
`;
-export const Desc = styled.p`
- ${textSingularLineEllipsis}
- width: 100%;
- height: 26px;
+export const Name = styled.strong`
text-align: center;
+ font-size: 28px;
- margin-top: 8px;
- font-size: 18px;
- line-height: 26px;
+ color: ${colors.white};
+ font-weight: 600;
+ line-height: 100%; /* 28px */
+ letter-spacing: -0.28px;
- color: rgba(255, 255, 255, 0.5);
+ /* 태블릿 뷰 */
+ @media (max-width: 768px) and (min-width: 428px) {
+ font-size: 18px;
+ }
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- margin-top: 4px;
+ @media (max-width: 427.9px) {
font-size: 16px;
}
`;
-export const Part = styled.div`
- ${textSingularLineEllipsis}
- max-width: 100%;
-
- display: flex;
- justify-content: center;
- align-items: center;
+export const Desc = styled.span`
+ text-align: center;
- margin-top: 12px;
+ margin-top: 15px;
+ font-size: 15px;
+ font-style: normal;
+ line-height: 26px; /* 173.333% */
+ letter-spacing: -0.3px;
+ color: ${colors.white};
+ background-color: #21212c;
padding: 10px 16px;
+ border-radius: 10px;
+ /* 태블릿 뷰 */
+ @media (max-width: 768px) and (min-width: 428px) {
+ font-size: 10.952px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 18.984px; /* 173.333% */
+ letter-spacing: -0.219px;
+ padding: 7px 12px;
+ border-radius: 8px;
+ }
+ /* 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ font-size: 6.648px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 11.524px; /* 173.333% */
+ letter-spacing: -0.133px;
+ padding: 4px 7px;
+ border-radius: 4px;
+ }
+`;
- background: #333333;
- border-radius: 30px;
-
- font-size: 18px;
- line-height: 26px;
+export const CurrentProject = styled.span`
+ position: relative;
+ &::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ background-image: url(${icSchool});
+ background-repeat: no-repeat;
+ background-size: contain;
+ width: 24px;
+ height: 24px;
+ /* 태블릿 뷰 */
+ @media (max-width: 768px) and (min-width: 428px) {
+ width: 18px;
+ height: 18px;
+ }
+ /* 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ width: 12px;
+ height: 12px;
+ }
+ }
- color: #ffffff;
+ height: 24px;
+ padding-left: 28px;
+ color: #bcbcbc;
+ font-size: 15px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 26px; /* 173.333% */
+ letter-spacing: -0.3px;
+ margin-top: 16px;
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
+ @media (max-width: 768px) and (min-width: 428px) {
+ height: 18px;
+ padding-left: 20px;
+ font-size: 10.952px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 18.984px; /* 173.333% */
+ letter-spacing: -0.219px;
+ margin-top: 12px;
+ }
+ /* 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ height: 12px;
+ padding-left: 13px;
+ font-size: 6.648px;
+ font-weight: 400;
+ line-height: 11.524px; /* 173.333% */
+ letter-spacing: -0.133px;
margin-top: 8px;
- padding: 10px 16px;
-
- background: #333333;
- border-radius: 30px;
+ }
+`;
- font-size: 18px;
- line-height: 26px;
+export const LinkWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: flex-end;
+ gap: 16px;
+ flex: 1;
+ height: 100%;
+ /* 태블릿 뷰 */
+ @media (max-width: 768px) and (min-width: 428px) {
+ gap: 12px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- margin-top: 6px;
+ @media (max-width: 427.9px) {
+ gap: 0;
+ }
+`;
- font-size: 12px;
- line-height: 15px;
+export const AnchorIconWrapper = styled.a`
+ /* 모바일 뷰 */
+ @media (max-width: 427.9px) {
+ transform: scale(0.7);
}
`;
diff --git a/src/views/AboutPage/components/Member/Content/index.tsx b/src/views/AboutPage/components/Member/Content/index.tsx
index 0ec418c9..7dabb01d 100644
--- a/src/views/AboutPage/components/Member/Content/index.tsx
+++ b/src/views/AboutPage/components/Member/Content/index.tsx
@@ -1,53 +1,59 @@
-import { track } from '@amplitude/analytics-browser';
-import { useMemo, useState } from 'react';
+import { useMemo } from 'react';
import DataErrorBanner from '@src/components/DataErrorBanner';
import Flex from '@src/components/common/Flex';
-import { ExtraPart, ExtraTabType } from '@src/lib/types/universal';
-import { PartExtraType } from '@src/lib/types/universal';
import { emptyMembers } from '@src/views/AboutPage/constant/emptyMembers';
import useFetchMember from '@src/views/AboutPage/hooks/useFetchMemeber';
-import useResponsiveMember from '@src/views/AboutPage/hooks/useResponsiveMember';
import { OvalSpinner } from '@src/views/ProjectPage/components';
-import TabBar from '../../common/TabBar';
import MemberCard from '../Card';
import * as St from './style';
const MemberContent = () => {
- const { memberCardsCount, shouldNotShownWithError } = useResponsiveMember();
-
- const [currentPart, setCurrentPart] = useState(PartExtraType.ALL);
- const state = useFetchMember(currentPart);
+ const state = useFetchMember();
const errorContent = state._TAG === 'ERROR' && ;
- const handleTabClick = (tab: ExtraTabType) => {
- setCurrentPart(tab.value);
- track('click_about_member_part', { part: tab.label });
- };
- const tabBarContent = !(state._TAG === 'ERROR' && shouldNotShownWithError) && (
-
- );
- const cardContent = useMemo(() => {
- if (state._TAG === 'OK')
- return state.data.members.map(({ id, name, src, description, part }) => (
-
- ));
- if (state._TAG === 'ERROR')
- return emptyMembers(memberCardsCount).map(({ id, name, src, description, part }) => (
-
- ));
+ const cardContent = useMemo(() => {
+ if (state._TAG === 'OK' || state._TAG === 'ERROR')
+ return (state._TAG === 'OK' ? state.data.members : emptyMembers(6)).map(
+ ({
+ id,
+ name,
+ position,
+ description,
+ currentProject,
+ imageSrc,
+ gmail,
+ linkedin,
+ github,
+ }) => (
+
+ ),
+ );
return (
);
- }, [state, memberCardsCount]);
+ }, [state]);
return (
-
+
{errorContent}
- {tabBarContent}
{cardContent}
);
diff --git a/src/views/AboutPage/components/Member/Content/style.ts b/src/views/AboutPage/components/Member/Content/style.ts
index 0983407e..2230df1d 100644
--- a/src/views/AboutPage/components/Member/Content/style.ts
+++ b/src/views/AboutPage/components/Member/Content/style.ts
@@ -1,16 +1,31 @@
import styled from '@emotion/styled';
export const CardContainer = styled.div`
- display: flex;
- flex-wrap: wrap;
- gap: 30px;
- /* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- gap: 20px;
+ display: grid;
+
+ grid-template-columns: repeat(3, 1fr);
+ gap: 34px;
+ width: 1200px;
+
+ @media (max-width: 1280px) and (min-width: 1170px) {
+ width: calc(100% - 40px);
+ }
+
+ @media (max-width: 1170px) and (min-width: 768px) {
+ grid-template-columns: repeat(2, 1fr);
+ width: 752px;
+ }
+
+ @media (max-width: 768px) and (min-width: 584px) {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 24px;
+ width: 576px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- gap: 10px;
+ @media (max-width: 584px) {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 15px;
+ width: max(350px, 100% - 40px);
}
`;
diff --git a/src/views/AboutPage/components/Member/Section/index.tsx b/src/views/AboutPage/components/Member/Section/index.tsx
index 14301579..0129e631 100644
--- a/src/views/AboutPage/components/Member/Section/index.tsx
+++ b/src/views/AboutPage/components/Member/Section/index.tsx
@@ -1,7 +1,7 @@
-import styled from '@emotion/styled';
import Flex from '@src/components/common/Flex';
-import SectionTitle from '../../common/SectionTitle';
+import SectionTop from '../../common/SectionTop';
import MemberContent from '../Content';
+import * as St from './style';
type MemberSectionProps = {
generation: number;
@@ -14,22 +14,16 @@ const MemberSection = ({ generation }: MemberSectionProps) => {
gap={{ mobile: 24, tablet: 48, desktop: 60 }}
style={{ position: 'relative' }}
>
- {/* member 2뎁스 탭 개발 이 삭제 필요 */}
-
- {generation - 1}기 활동 멤버들
+
+
+ {/* TODO : 서버에서 description을 받아오도록 수정 */}
);
};
-const ScrollGhost = styled.div`
- position: absolute;
- top: -100px;
-
- /* 모바일 뷰 */
- @media (max-width: 765.9px) {
- top: -60px;
- }
-`;
-
export default MemberSection;
diff --git a/src/views/AboutPage/components/Member/Section/style.ts b/src/views/AboutPage/components/Member/Section/style.ts
new file mode 100644
index 00000000..e7333aa6
--- /dev/null
+++ b/src/views/AboutPage/components/Member/Section/style.ts
@@ -0,0 +1,12 @@
+import styled from '@emotion/styled';
+
+export const MarginTop = styled.div`
+ height: 275px;
+ @media (max-width: 1440px) and (min-width: 766px) {
+ height: 190px;
+ }
+ /* 모바일 뷰 */
+ @media (max-width: 765.9px) {
+ height: 120px;
+ }
+`;
diff --git a/src/views/AboutPage/components/Record/Item/index.tsx b/src/views/AboutPage/components/Record/Item/index.tsx
index 82ff5aa3..d79a77b3 100644
--- a/src/views/AboutPage/components/Record/Item/index.tsx
+++ b/src/views/AboutPage/components/Record/Item/index.tsx
@@ -1,24 +1,43 @@
import { track } from '@amplitude/analytics-browser';
+import { PropsWithChildren } from 'react';
import Flex from '@src/components/common/Flex';
import NumberRoller from '@src/components/common/NumberRoller';
import { RECORD_TITLE } from '@src/lib/constants/about';
import { RecordTitle } from '@src/lib/types/about';
import * as St from './style';
-type RecordItemProps = {
- href: string;
- title: RecordTitle;
- countNumber?: number;
- countString?: string;
-};
+type RecordItemProps =
+ | {
+ type: 'link';
+ href: string;
+ title: RecordTitle;
+ countNumber?: number;
+ countString?: string;
+ }
+ | {
+ type: 'block';
+ title: RecordTitle;
+ countNumber?: number;
+ countString?: string;
+ };
-const RecordItem = (props: RecordItemProps) => {
+const RecordItemWrapper = (props: PropsWithChildren) => {
const trackRecordClick = () => {
track(`click_about_${RECORD_TITLE[props.title]}`);
};
+ if (props.type == 'link')
+ return (
+
+ {props.children}
+
+ );
+ return {props.children};
+};
+
+const RecordItem = (props: RecordItemProps) => {
return (
-
+
{
{props.countString && {props.countString}}
-
+
);
};
diff --git a/src/views/AboutPage/components/Record/Item/style.ts b/src/views/AboutPage/components/Record/Item/style.ts
index 450158aa..71c42977 100644
--- a/src/views/AboutPage/components/Record/Item/style.ts
+++ b/src/views/AboutPage/components/Record/Item/style.ts
@@ -1,34 +1,54 @@
import styled from '@emotion/styled';
import Link from 'next/link';
-import arrowRight from '@src/assets/icons/arrow_right_16x16.svg';
+import { css } from '@emotion/react';
-export const LinkWrapper = styled(Link)`
- width: 100%;
- background-color: #000000;
- border-radius: 10px;
+const wrapperStyle = css`
+ width: 380px;
height: 280px;
+ background-color: #141518;
+ border-radius: 10px;
+
+ @media (max-width: 996px) and (min-width: 766px) {
+ width: 285px;
+ height: 210px;
+ }
+
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- height: 180px;
+ @media (max-width: 766px) and (min-width: 428px) {
+ width: 204px;
+ height: 150px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- height: 120px;
+ @media (max-width: 428px) {
+ width: 204px;
+ height: 150px;
}
`;
+export const LinkWrapper = styled(Link)`
+ ${wrapperStyle}
+`;
+
+export const BlockWrapper = styled.div`
+ ${wrapperStyle}
+`;
+
export const Title = styled.div`
font-size: 20px;
letter-spacing: -1%;
color: white;
+ @media (max-width: 996px) and (min-width: 766px) {
+ font-size: 16px;
+ }
+
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- font-size: 18px;
+ @media (max-width: 766px) and (min-width: 428px) {
+ font-size: 10px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- font-size: 12px;
+ @media (max-width: 428px) {
+ font-size: 10px;
}
`;
@@ -38,39 +58,19 @@ export const Count = styled.div`
font-size: 45px;
color: white;
line-height: 60px;
+
+ @media (max-width: 996px) and (min-width: 766px) {
+ font-size: 38px;
+ line-height: 48px;
+ }
/* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- font-size: 28px;
- line-height: 40px;
+ @media (max-width: 766px) and (min-width: 428px) {
+ font-size: 24px;
+ line-height: 32px;
}
/* 모바일 뷰 */
- @media (max-width: 765.9px) {
- font-size: 18px;
- line-height: 18px;
- }
-
- &::after {
- position: absolute;
- content: '';
- mask-image: url(${arrowRight});
- mask-repeat: no-repeat;
- mask-size: cover;
- background-color: #787878;
- width: 32px;
- height: 40px;
- margin-top: 9px;
-
- /* 태블릿 뷰 */
- @media (max-width: 1199px) and (min-width: 766px) {
- width: 16px;
- height: 20px;
- margin-top: 9px;
- }
- /* 모바일 뷰 */
- @media (max-width: 765.9px) {
- width: 12px;
- height: 15px;
- margin-top: 1px;
- }
+ @media (max-width: 428px) {
+ font-size: 14px;
+ line-height: 32px;
}
`;
diff --git a/src/views/AboutPage/components/Record/List/index.tsx b/src/views/AboutPage/components/Record/List/index.tsx
index 14963e4c..556a33fe 100644
--- a/src/views/AboutPage/components/Record/List/index.tsx
+++ b/src/views/AboutPage/components/Record/List/index.tsx
@@ -1,31 +1,32 @@
-import Flex from '@src/components/common/Flex';
import { AboutInfoType } from '@src/lib/types/about';
import RecordItem from '../Item';
+import * as St from './style';
type RecordListProps = Pick;
const RecordList = (props: RecordListProps) => {
return (
-
+
-
+
);
};
diff --git a/src/views/AboutPage/components/Record/List/style.ts b/src/views/AboutPage/components/Record/List/style.ts
new file mode 100644
index 00000000..5fcebe4a
--- /dev/null
+++ b/src/views/AboutPage/components/Record/List/style.ts
@@ -0,0 +1,27 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.div`
+ display: flex;
+ gap: 30px;
+ justify-content: center;
+ align-items: center;
+ padding: 0 20px;
+
+ @media (max-width: 996px) and (min-width: 766px) {
+ gap: 24px;
+ }
+
+ @media (max-width: 766px) and (min-width: 428px) {
+ gap: 20px;
+ }
+
+ @media (max-width: 520px) {
+ flex-direction: column;
+ }
+
+ /* 모바일 뷰 */
+ @media (max-width: 428px) {
+ flex-direction: column;
+ gap: 16px;
+ }
+`;
diff --git a/src/views/AboutPage/components/Record/Section/index.tsx b/src/views/AboutPage/components/Record/Section/index.tsx
index 46f4565d..6919cb59 100644
--- a/src/views/AboutPage/components/Record/Section/index.tsx
+++ b/src/views/AboutPage/components/Record/Section/index.tsx
@@ -1,16 +1,16 @@
-import Flex from '@src/components/common/Flex';
import { AboutInfoType } from '@src/lib/types/about';
-import SectionTitle from '../../common/SectionTitle';
+import SectionTop from '../../common/SectionTop';
import RecordList from '../List';
+import * as St from './style';
type RecordSectionProps = Pick;
const RecordSection = (props: RecordSectionProps) => {
return (
-
- {props.generation - 1}기 활동 레코드
+
+
-
+
);
};
diff --git a/src/views/AboutPage/components/Record/Section/style.ts b/src/views/AboutPage/components/Record/Section/style.ts
new file mode 100644
index 00000000..82893127
--- /dev/null
+++ b/src/views/AboutPage/components/Record/Section/style.ts
@@ -0,0 +1,22 @@
+import styled from '@emotion/styled';
+
+export const Wrapper = styled.section`
+ margin-top: 275px;
+ margin-bottom: 340px;
+ gap: 48px;
+ display: flex;
+ flex-direction: column;
+
+ @media (max-width: 766px) and (min-width: 428px) {
+ margin-top: 190px;
+ margin-bottom: 218px;
+ gap: 28px;
+ }
+
+ /* 모바일 뷰 */
+ @media (max-width: 428px) {
+ margin-top: 120px;
+ margin-bottom: 136px;
+ gap: 26px;
+ }
+`;
diff --git a/src/views/AboutPage/constant/emptyMembers.ts b/src/views/AboutPage/constant/emptyMembers.ts
index 407f9c3a..caa2bda4 100644
--- a/src/views/AboutPage/constant/emptyMembers.ts
+++ b/src/views/AboutPage/constant/emptyMembers.ts
@@ -5,8 +5,10 @@ export const emptyMembers = (count: number): MemberType[] => {
return Array.from({ length: count }).map((_, idx) => ({
id: idx,
name: '-',
+ position: '',
+ currentProject: '',
description: '-',
part: '-',
- src: NullImage.src,
+ imageSrc: NullImage.src,
}));
};
diff --git a/src/views/AboutPage/hooks/useFetchMemeber.ts b/src/views/AboutPage/hooks/useFetchMemeber.ts
index c78b6697..07d270f6 100644
--- a/src/views/AboutPage/hooks/useFetchMemeber.ts
+++ b/src/views/AboutPage/hooks/useFetchMemeber.ts
@@ -1,15 +1,12 @@
import { useCallback } from 'react';
import useFetchBase from '@src/hooks/useFetchBase';
import { api } from '@src/lib/api';
-import { ExtraPart, PartExtraType } from '@src/lib/types/universal';
-const useFetchMember = (part: ExtraPart) => {
+const useFetchMember = () => {
const willFetch = useCallback(async () => {
- const response = await api.aboutAPI.getMemberInfo(
- part === PartExtraType.ALL ? undefined : part,
- );
+ const response = await api.aboutAPI.getMemberInfo();
return response;
- }, [part]);
+ }, []);
const state = useFetchBase(willFetch);
return state;
};
diff --git a/src/views/AboutPage/hooks/useResponsiveMember.ts b/src/views/AboutPage/hooks/useResponsiveMember.ts
deleted file mode 100644
index 5effc229..00000000
--- a/src/views/AboutPage/hooks/useResponsiveMember.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { useMemo } from 'react';
-import { useIsMobile, useIsTablet } from '@src/hooks/useDevice';
-
-const useResponsiveMember = () => {
- const isTablet = useIsTablet('766px', '1199.9px');
- const isMobile = useIsMobile();
-
- const memberCardsCount = useMemo(() => {
- if (isMobile) return 2;
- if (isTablet) return 3;
- return 4;
- }, [isMobile, isTablet]);
-
- return { memberCardsCount, shouldNotShownWithError: isMobile };
-};
-
-export default useResponsiveMember;