Skip to content

Commit 32b3e60

Browse files
Migrate makes info data
1 parent 35f3850 commit 32b3e60

File tree

3 files changed

+354
-6
lines changed

3 files changed

+354
-6
lines changed
File renamed without changes.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import Image from 'next/image';
2+
import React from 'react';
3+
4+
interface MakerCardProps {
5+
title: string;
6+
subtitle: string;
7+
position?: string;
8+
active?: boolean;
9+
launched?: string;
10+
isProject?: boolean;
11+
onClick?: () => void;
12+
}
13+
14+
const MakerCard: React.FC<MakerCardProps> = ({
15+
title,
16+
subtitle,
17+
position,
18+
active = false,
19+
launched,
20+
isProject = false,
21+
onClick
22+
}) => {
23+
if (isProject) {
24+
return (
25+
<div
26+
className={`
27+
w-[220px] h-[80px] rounded-[10px] bg-white flex flex-col items-center justify-center
28+
relative hover:shadow-lg transition-shadow duration-300 ease-in-out
29+
${active ? 'shadow-md' : 'shadow-sm'}
30+
cursor-pointer
31+
sm:w-[110px]
32+
`}
33+
onClick={onClick}
34+
>
35+
<span className="text-[15px] font-bold leading-[1.47] sm:text-[12px] sm:text-center">
36+
{title}
37+
</span>
38+
<span className="mt-[12px] text-[9px] font-medium leading-[1.44] text-gray-400">
39+
{subtitle}
40+
</span>
41+
{launched && (
42+
<span className="text-[9px] font-medium leading-[1.44] text-gray-400">
43+
launched at {launched}
44+
</span>
45+
)}
46+
</div>
47+
);
48+
}
49+
50+
return (
51+
<div className={`
52+
w-[280px] h-[120px] py-0 px-[36px] rounded-[10px] shadow-md bg-white
53+
flex flex-row items-center justify-between
54+
hover:shadow-lg transition-shadow duration-300 ease-in-out
55+
sm:w-[120px] sm:flex-col sm:justify-center
56+
`}>
57+
<div className="flex flex-col items-start sm:items-center">
58+
<span className="text-[20px] font-bold leading-[1.5] sm:text-[14px] sm:text-center">
59+
{title}
60+
</span>
61+
<div className="mt-[4px] flex flex-row items-start">
62+
<div className="w-[13px] h-[20px] overflow-hidden">
63+
<Image
64+
src="SparcsLogo.svg"
65+
alt="Sparcs Logo"
66+
width={70}
67+
height={20}
68+
className="w-[70px] max-w-none filter-[invert(63%)_sepia(71%)_saturate(514%)_hue-rotate(352deg)_brightness(97%)_contrast(91%)]"
69+
/>
70+
</div>
71+
<span className="text-[13px] font-extrabold leading-[1.5] font-['Raleway'] text-[#eba12a]">
72+
{subtitle}
73+
</span>
74+
</div>
75+
</div>
76+
<span className="text-[10px] font-medium leading-[1.5] text-gray-400 sm:mt-[5px] sm:text-center">
77+
{position}
78+
</span>
79+
</div>
80+
);
81+
};
82+
83+
export default MakerCard;

src/app/makers/page.tsx

Lines changed: 271 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,273 @@
1+
'use client';
2+
3+
import React, { useState, useEffect } from 'react';
4+
import MakerCard from './components/MakerCard';
5+
6+
// 포지션 약어 정의
7+
const abbr = {
8+
SO: 'SysOp',
9+
PM: 'Project Manager',
10+
DS: 'Designer',
11+
DV: 'Developer'
12+
};
13+
14+
// 프로젝트 데이터 - 모든 프로젝트 포함
15+
const projects = [
16+
{
17+
name: 'SPARCS BBS', // Eagle BBs 기반 아라
18+
period: '1991~1998',
19+
launched: '1991',
20+
description:
21+
`1991년에 창립된 SPARCS가 가장 먼저 선보였던 아라입니다.
22+
Eagle BBS (Pirite BBS) 기반으로 개발된 아라로, 우리나라에서 두번째로 생긴
23+
Internet에 연결된 BBS (Bulletin Board System) 서비스입니다. 이때부터 아라는
24+
계속해서 리뉴얼되어 왔으며, 현존하는 BBS 서비스 중에서는 가장 오래되었습니다.`,
25+
members: {
26+
SO: ['cdpark:박종대']
27+
}
28+
},
29+
{
30+
name: 'NeoAra', // NNTP 기반 아라
31+
period: '1998~2006',
32+
launched: '1998',
33+
description:
34+
`NeoAra는 NewsGroup을 연동하고자 한 NNTP 기반의 아라입니다.
35+
KAIST 구성원만을 위한 NewsGroup 뿐만 아니라 KAIST 주변의 한국 내 인터넷 사용자
36+
모두를 위한 NewsGroup 으로서의 역할도 하려고 하였습니다`,
37+
members: {
38+
SO: [
39+
'kaien:박상진', 'godslord:권용철', 'algepher:변창환',
40+
'neosado:김영준', 'tapung:채주병'
41+
]
42+
}
43+
},
44+
{
45+
name: 'NeoAra & WebAra',
46+
period: '2006~2008',
47+
launched: '2006',
48+
description:
49+
`NeoAra & WebAra는 웹과의 연동이 시작된 아라입니다.
50+
덕분에 Telnet, NNTP 뿐만 아니라 Web 으로도 아라를 이용이 가능해졌습니다.
51+
또한 파일 첨부기능이 추가되어 학우들이 더 다양한 방식으로 아라를 이용할 수 있었습니다.`,
52+
members: {
53+
SO: ['airlover:김유승', 'pcpenpal:박용수', 'softdie:김동주']
54+
}
55+
},
56+
{
57+
name: 'Arara 1세대',
58+
period: '2008~2010',
59+
launched: '2008',
60+
description:
61+
`Arara 1세대는 유지보수가 어려워진 NeoAra & WebAra를 대체하기 위해 출범하였으며,
62+
이종 언어가 자유로이 쓰이는 확장가능 구조로 개발되었습니다.
63+
Python을 기반으로 백엔드에서는 SQLAlchemy, 미들웨어로는 Thrift RPC,
64+
프론트엔드에서는 Django Template Engine 을 사용하였습니다.`,
65+
members: {
66+
DV: [
67+
'serialx:홍성진', 'pipocket:서우석', 'ssaljalu:조준희', 'breadfish:구성모',
68+
'jcob:조지혁', 'peremen:박신조', 'combacsa:변규홍'
69+
]
70+
}
71+
},
72+
{
73+
name: 'Arara 2세대', // XpressEngine 기반 아라
74+
period: '2010~2020',
75+
launched: '2011',
76+
description:
77+
`Arara 2세대는 2010년부터 2020년 10월까지 학우들이 가장 오랫동안 이용한 아라입니다.
78+
2011년 리뉴얼된 당시 동시접속자수 200명, 하루 평균 접속자수가 7000명으로 KAIST 학내
79+
공식 커뮤니티로서 아라의 위상을 확인할 수 있었습니다.
80+
기존 ARAra 엔진 디자인을 새롭게 하고, 동시에 XpressEngine 기반 아라를 개발하려는
81+
노력이 있었습니다. 또한 RSS 등 사용자들이 필요로 한 기능이 구현되었습니다.`,
82+
members: {
83+
PM: ['combacsa:변규홍'],
84+
DV: [
85+
'mikkang:김문범', 'reniowood:김진혁', 'harry:이대근', 'jeanclaire:이현진',
86+
'ssaljalu:조준희', 'anna418:조유정', 'richking:김창하', 'xhark:김재홍',
87+
'leopine:이가영', 'snogar:차동훈', 'imai:배성경', 'r4t5y6:임규리',
88+
'kuss:안재만', 'hodduc:이준성', 'leeopop:이근홍'
89+
]
90+
}
91+
},
92+
{
93+
name: '모바일 아라',
94+
period: '2011~2020',
95+
launched: '2012',
96+
description:
97+
`모바일 아라는 아라를 모바일로 이용하는 수요가 늘면서,
98+
그에 맞게 디자인을 개선시키고 Arara의 엔진 성능을 개선하고자한 프로젝트입니다.`,
99+
members: {
100+
PM: ['hodduc:이준성'],
101+
DV: [
102+
'richking:김창하', 'combasa:변규홍', 'grandmarnier:차준호', 'bbashong:최낙현',
103+
'panda:조민지', 'elaborate:안병욱', 'penguin:민서영', 'pocari:이경태',
104+
'zzongaly:정진근'
105+
]
106+
}
107+
},
108+
{
109+
name: '아라리',
110+
period: '2012~2013',
111+
members: {
112+
PM: ['zzongaly:정진근'],
113+
DV: [
114+
'bbashong:최낙현', 'undead:이창원', 'boolgom:심규민', 'rodumani:정창제',
115+
'panda:조민지', 'naldo:박지혁', 'yasik:박중언', 'apple:김영석',
116+
'veritas:정진훈', 'jjus:김지현', 'alice:문슬기', 'penguin:민서영'
117+
]
118+
}
119+
},
120+
{
121+
name: '아라2',
122+
period: '2013~2014',
123+
members: {
124+
PM: ['serialx:홍성진'],
125+
DV: [
126+
'hodduc:이준성', 'raon:김강인', 'bbashong:최낙현', 'richking:김창하'
127+
]
128+
}
129+
},
130+
{
131+
name: '아라플러스',
132+
period: '2015~2016',
133+
description:
134+
`아라플러스는 KAIST 학생 사회에서 ARA를 다시 활성화하기 위해, 커뮤니티 활동을 즐길 수
135+
있는 풍부한 기능들을 새로운 UI와 함께 제공하고자 했던 프로젝트입니다. 사용자들이 특정
136+
주제에 대해 채팅을 나눌 수 있는 '불판', 동아리나 자치단체, 소모임을 위한 '그룹게시판',
137+
익명 글작성, 포인트 제도 등 재미있는 기능들이 기획되고 개발되었습니다.`,
138+
members: {
139+
PM: [
140+
'story:김동화', 'kyeome:김태겸'
141+
],
142+
DV: [
143+
'kanon:김민수', 'apple:김영석', 'zealot:한승현', 'undead:이창원',
144+
'mandu:황태현', 'samjo:조성원', 'suckzoo:홍석주', 'luan:이상국',
145+
'george:조형준', 'jara:이문영'
146+
]
147+
}
148+
},
149+
{
150+
name: '뉴아라',
151+
period: '2017~On-going',
152+
launched: '2020',
153+
description:
154+
`2020년 11월 출범한 뉴아라는 '가장 정확한 정보를 가장 신속하게'라는 슬로건으로 10년간
155+
이용되던 Arara 를 새롭게 리뉴얼한 프로젝트입니다. 뉴아라에서는 카이스트 포탈공지를
156+
아라에서도 제공하기 시작했고, 기존 ARA의 게시물과 댓글을 모두 이전시켰음에도 빠른 속도를
157+
유지했으며, elasticsearch를 도입해 발전된 검색기능을 선보였습니다.
158+
또한 아라의 아이덴티티가 잘 드러나도록 홈페이지 디자인을 개선하였습니다.`,
159+
members: {
160+
PM: [
161+
['killerwhale:박승범', '2025~'], ['hyooyh:권효진', '2024'], ['yuwol:황인준', '2022~2023' ],
162+
['jessie:윤지수', '2021'], ['victory:김주연', '2020'], ['leo:정진우', '2019'],
163+
['yujingaya:김유진', '2018'], ['swan:지수환', '2018'], ['raon:김강인', '2017']
164+
],
165+
DV: [
166+
'casio:임가은', 'soom:이수민', 'edge:정재현', 'hyuk:장승혁',
167+
'king:김세종', 'roul:신도윤', 'default:김현수', 'phenol:권영완',
168+
'arcticfox:고예준', 'alvin:김상오', 'retro:최상아', 'ina:송인화',
169+
'ddungiii:김기영', 'duncan:이동재', 'panya:김지연', 'ivy:이융희',
170+
'jungnoh:노정훈', 'water:김윤수', 'triangle:주예준', 'hanski:한석휘',
171+
'idev:이재현', 'doolly:김제윤', 'nenw:김요한', 'fi:김도현',
172+
'james:문재호', 'busan:안재웅', 'kidevelop:함종현', 'holymolly:김태원',
173+
'gunwoo:김건우', 'todo:김동관', 'his:황인승', 'rongrong:이승민',
174+
'leesia:강현우', 'seol:설윤아', 'youns:최윤서', 'appleseed:강찬규'
175+
],
176+
DS: [
177+
'yumyum:조유민', 'nine:배세윤', 'cheddar:최다은',
178+
'stitch:이채영', 'zero:임현정', 'luny:김나영'
179+
]
180+
}
181+
}
182+
];
183+
1184
export default function Makers() {
2-
return (
3-
<div>
4-
<h1>만든사람들</h1>
185+
const [selected, setSelected] = useState(9); // 기본 선택은 뉴아라 (마지막 항목)
186+
const positions = ['SO', 'PM', 'DS', 'DV'];
187+
188+
useEffect(() => {
189+
document.body.style.background = '#fafafa';
190+
return () => {
191+
document.body.style.background = '';
192+
};
193+
}, []);
194+
195+
// 프로젝트 이름 포맷팅
196+
const projectName = (project: any) => {
197+
return project.launched ? `🚀 ${project.name}` : project.name;
198+
};
199+
200+
// 멤버 이름 추출
201+
const memberName = (member: any) => {
202+
if (Array.isArray(member)) member = member[0];
203+
return member.split(':')[1];
204+
};
205+
206+
// 멤버 닉네임 추출
207+
const memberNickname = (member: any) => {
208+
if (Array.isArray(member)) member = member[0];
209+
return member.split(':')[0];
210+
};
211+
212+
// 멤버 포지션 포맷팅
213+
const memberPosition = (member: any, position: string) => {
214+
if (Array.isArray(member)) {
215+
return `${member[1]} ${abbr[position as keyof typeof abbr]}`;
216+
} else {
217+
return abbr[position as keyof typeof abbr];
218+
}
219+
};
220+
221+
return (
222+
<div className="max-w-[1280px] mx-auto px-4 py-8 bg-[#fafafa]">
223+
<h1 className="text-[20px] font-bold leading-[1.45] mb-[18px] mx-[90px] md:mx-0 sm:mx-[50px] xs:mx-[20px]">
224+
Project
225+
</h1>
226+
227+
<div className="grid gap-[10px] justify-center mb-[48px] grid-cols-[repeat(auto-fit,minmax(220px,max-content))] sm:grid-cols-[repeat(auto-fit,minmax(110px,max-content))]">
228+
{projects.map((project, index) => (
229+
<MakerCard
230+
key={project.name}
231+
title={projectName(project)}
232+
subtitle={project.period}
233+
active={selected === index}
234+
launched={project.launched}
235+
isProject={true}
236+
onClick={() => setSelected(index)}
237+
/>
238+
))}
5239
</div>
6-
);
7-
}
8-
240+
241+
{projects[selected]?.description && (
242+
<div className="flex w-full flex-col justify-center my-[48px]">
243+
<h2 className="text-[20px] font-bold leading-[1.45] mb-[18px] mx-[90px] md:mx-0 sm:mx-[50px] xs:mx-[20px]">
244+
Description
245+
</h2>
246+
<div className="rounded-[10px] shadow-md bg-white p-[22px_64px] mt-[30px] mx-[90px] md:mx-0 sm:mx-[50px] sm:p-[22px_22px] xs:mx-[20px]">
247+
<p className="text-[15px] font-medium leading-[1.47] text-left sm:text-[12px]">
248+
{projects[selected].description}
249+
</p>
250+
</div>
251+
</div>
252+
)}
253+
254+
<h2 className="text-[20px] font-bold leading-[1.45] mb-[18px] mx-[90px] md:mx-0 sm:mx-[50px] xs:mx-[20px]">
255+
Member
256+
</h2>
257+
258+
<div className="grid gap-[10px] justify-center mt-[48px] mb-[10px] grid-cols-[repeat(auto-fit,minmax(280px,max-content))] sm:grid-cols-[repeat(auto-fit,minmax(120px,max-content))]">
259+
{positions.map(position =>
260+
projects[selected].members[position as keyof typeof projects[typeof selected]['members']]?.map((member: any) => (
261+
<MakerCard
262+
key={Array.isArray(member) ? member[0] : member}
263+
title={memberName(member)}
264+
subtitle={memberNickname(member)}
265+
position={memberPosition(member, position)}
266+
isProject={false}
267+
/>
268+
))
269+
)}
270+
</div>
271+
</div>
272+
);
273+
}

0 commit comments

Comments
 (0)