Skip to content
Merged
1 change: 1 addition & 0 deletions docs/FRONTEND_ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ src/
- 학생 전용 route
- 선생님 전용 route
- 내부 사용자 공통 도서관 route
- `학생 관리` route는 선생님 전용 route로 분리하고, 학생 권한 내비게이션에는 노출하지 않는다.

예시:

Expand Down
6 changes: 6 additions & 0 deletions docs/USER_ROLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
- 레주메북 변환을 실행한다.
- 내부 도서관을 열람하고 관리한다.

### 선생님 전용 화면

- `학생 관리` 화면은 선생님 권한에서만 제공한다.
- 학생 사용자는 `학생 관리` 메뉴와 반별 학생 제출 현황 모달에 접근하지 않는다.
- 프론트엔드 내비게이션에서 학생 역할에는 `홈`, `이력서 관리`, `도서관`만 노출하고, 선생님 역할에는 `전공 관리`, `학생 관리`, `도서관`을 노출한다.

## 로그인한 내부 사용자

학생/선생님 등 서비스에 로그인한 사용자는 내부 레주메북 도서관을 볼 수 있습니다.
Expand Down
176 changes: 0 additions & 176 deletions src/app/(public)/resume-books/[bookId]/page.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,182 +223,6 @@
line-height: var(--repo-font-title-tiny-line-height);
}

.sheet {
width: 423px;
height: 599px;
overflow: hidden;
padding: 20px;
color: var(--repo-text-black);
background: var(--repo-gray-50);
}

.sheetHeader {
display: grid;
grid-template-columns: 50px minmax(0, 1fr) 47px;
gap: 13px;
align-items: start;
}

.profileImage {
width: 47px;
height: 47px;
border-radius: var(--repo-radius-pill);
background:
radial-gradient(circle at 58% 42%, #ffffff 0 8px, #d7d7d7 9px 10px, transparent 11px),
radial-gradient(circle at 37% 41%, #f7f7f7 0 12px, #d8d8d8 13px 15px, transparent 16px),
radial-gradient(circle at 40% 38%, #323232 0 2px, transparent 3px),
radial-gradient(circle at 61% 37%, #323232 0 2px, transparent 3px),
linear-gradient(135deg, #e8e4de, #c8c1b7 46%, #f1eee9);
}

.identity {
display: grid;
gap: 5px;
min-width: 0;
}

.nameRow {
display: flex;
align-items: baseline;
gap: 9px;
min-width: 0;
}

.name {
margin: 0;
color: var(--repo-text-black);
font-size: var(--repo-font-title-small-size);
font-weight: var(--repo-font-title-small-weight);
line-height: var(--repo-font-title-small-line-height);
letter-spacing: 0;
}

.major {
color: var(--repo-gray-500);
font-size: 9px;
font-weight: 500;
line-height: 1;
white-space: nowrap;
}

.meta {
margin: 0;
color: var(--repo-text-black);
font-size: var(--repo-font-body-very-tiny-size);
font-weight: var(--repo-font-body-very-tiny-weight);
line-height: var(--repo-font-body-very-tiny-line-height);
}

.qrCode {
width: 47px;
height: 47px;
margin-left: auto;
background:
linear-gradient(90deg, #000 50%, transparent 0) 0 0 / 9px 9px,
linear-gradient(#000 50%, transparent 0) 0 0 / 9px 9px,
linear-gradient(90deg, transparent 35%, #000 0 65%, transparent 0) 0 0 / 18px 18px,
var(--repo-gray-50);
image-rendering: pixelated;
outline: 4px solid var(--repo-gray-50);
}

.introBox {
display: grid;
gap: 7px;
margin-top: 14px;
padding: 11px 13px;
border-radius: 8px;
background: var(--repo-gray-100);
}

.introBox h2,
.section h2 {
margin: 0;
color: var(--repo-text-black);
font-size: var(--repo-font-body-tiny-size);
font-weight: var(--repo-font-body-tiny-weight);
line-height: var(--repo-font-body-tiny-line-height);
letter-spacing: 0;
}

.introBox p {
margin: 0;
color: var(--repo-gray-800);
font-size: var(--repo-font-resume-small-size);
font-weight: var(--repo-font-resume-small-weight);
line-height: var(--repo-font-resume-small-line-height);
}

.section {
display: grid;
gap: 9px;
margin-top: 14px;
}

.skillList {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 0;
margin: 0;
list-style: none;
}

.skillList li {
min-width: 52px;
padding: 5px 12px;
border-radius: var(--repo-radius-pill);
background: var(--repo-gray-100);
font-size: 8px;
line-height: 1;
text-align: center;
}

.activityList {
display: grid;
gap: 10px;
padding: 11px 0 13px;
margin: 0;
border-top: 1px solid var(--repo-gray-300);
list-style: none;
}

.activityList li {
display: grid;
gap: 3px;
color: var(--repo-text-black);
font-size: 11px;
line-height: 1.25;
}

.activityList time,
.detailSection h3 {
color: var(--repo-gray-500);
font-size: 12px;
font-weight: 500;
}

.detailSection {
padding-top: 5px;
border-top: 1px dashed var(--repo-gray-300);
}

.detailSection + .detailSection {
margin-top: 9px;
}

.detailSection h3 {
margin: 0 0 4px;
}

.detailSection ul {
padding-left: 16px;
margin: 0;
color: var(--repo-text-black);
font-size: 11px;
line-height: 1.25;
}

.filterPanel {
position: absolute;
top: 0;
Expand Down
81 changes: 3 additions & 78 deletions src/app/(public)/resume-books/[bookId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useRef, useState, type ReactNode } from 'react'
import { useRouter } from 'next/navigation'

import type { AppHeaderItem } from '@/shared/ui'
import { AppHeader, Button, CheckboxOption, SearchField, Tag, Toast } from '@/shared/ui'
import { AppHeader, Button, CheckboxOption, ResumeBookSheet, SearchField, Tag, Toast } from '@/shared/ui'

import styles from './page.module.css'

Expand All @@ -14,16 +14,6 @@ const navigationItems = [
{ href: '/library', label: '도서관', value: 'library' },
] satisfies readonly AppHeaderItem[]

const skills = ['Figma', 'illustrator', 'photoshop']

const activities = [
{ date: '2025.12.25', title: '제 1회 SCSC 온라인 해커톤 2위' },
{ date: '2025.07.18', title: '2025 교내 해커톤 우수상' },
]

const contests = ['제4회 2026 블레이버스 MVP 개발 해커톤', '제 1회 SCSC온라인 해커톤', '2025 교내 해커톤']
const projects = ['TEENS', '스플', 'D-ask', 'DSG', 'Studiz', 'hear', '마음씨', 'Repo']

const majorFilters = [
{ chipLabel: 'Frontend', label: 'Frontend Developer', value: 'frontend' },
{ chipLabel: 'Backend', label: 'Backend Developer', value: 'backend' },
Expand Down Expand Up @@ -217,8 +207,8 @@ export default function ResumeBookPage() {
</button>
<div className={styles.sheets} aria-label="포트폴리오 문서 페이지">
<ResumeSheet />
<ResumeSheet />
<ResumeBookSheet />
<ResumeBookSheet />
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
</div>
<button className={`${styles.pageArrow} ${styles.nextArrow}`} type="button" aria-label="다음 페이지">
Expand Down Expand Up @@ -335,71 +325,6 @@ function FilterSection({
)
}

function ResumeSheet() {
return (
<article className={styles.sheet} aria-label="최하은 포트폴리오">
<header className={styles.sheetHeader}>
<div className={styles.profileImage} aria-label="프로필 이미지" />
<div className={styles.identity}>
<div className={styles.nameRow}>
<h1 className={styles.name}>최하은</h1>
<span className={styles.major}>Frontend Developer</span>
</div>
<p className={styles.meta}>2415 인공지능소프트웨어과 | mare2mare6@gmail.com</p>
</div>
<div className={styles.qrCode} aria-label="포트폴리오 QR 코드" />
</header>

<section className={styles.introBox}>
<h2>안녕하세요 저는 디자이너가 되고 싶은 인간입니다</h2>
<p>
새벽자습너무 졸립니다. 뭘 적지.. 한줄소개는 이런식으로 쭉쭉 들어갑니다.
줄넘김 가능합니다. 자기소개자기소개자기소개자기소개자기소개자기소개.. 최대 4줄이면 충분하겠지만..
</p>
</section>

<section className={styles.section}>
<h2>기술스택</h2>
<ul className={styles.skillList}>
{skills.map((skill) => (
<li key={skill}>{skill}</li>
))}
</ul>
</section>

<section className={styles.section}>
<h2>활동</h2>
<ol className={styles.activityList}>
{activities.map((activity) => (
<li key={activity.title}>
<time>{activity.date}</time>
<span>{activity.title}</span>
</li>
))}
</ol>
</section>

<section className={styles.detailSection}>
<h3>대회</h3>
<ul>
{contests.map((contest) => (
<li key={contest}>{contest}</li>
))}
</ul>
</section>

<section className={styles.detailSection}>
<h3>Project</h3>
<ul>
{projects.map((project) => (
<li key={project}>{project}</li>
))}
</ul>
</section>
</article>
)
}

function FilterIcon() {
return (
<svg aria-hidden="true" className={styles.filterIcon} fill="none" viewBox="0 0 24 24">
Expand Down
Loading
Loading