05-회의진행 화면 UI/UX 개선 및 모바일 최적화

주요 변경사항:
- 전체 화면 레이아웃 개선 (좌우 여백 제거, 반응형 비율 조정)
- 모바일 플로팅 버튼 + 바텀시트 패턴 구현
- 참고자료 영역 접근성 개선 (웹/모바일 분기)
- 관련회의록 상세 모달 추가

UI 개선:
- Live Speech 영역 제거
- 상단 여백 최소화 (모바일 0px, 데스크톱 8px)
- AI 재생성 버튼 추가 (secondary 스타일)
- 편집 버튼 스타일 통일 (primary, 아이콘 제거)
- 플로팅 버튼 이미지 적용 (review.png + 배지 카운터)

모바일 기능:
- 플로팅 버튼 (우하단, 70px 간격)
- 바텀시트 (참고자료, 80vh 높이)
- 드래그 핸들 및 제스처 지원
- 관련회의록 핵심 내용 모달

반응형 처리:
- 웹 (1024px+): 62-65% 회의록 / 35-38% 참고자료
- 모바일 (1024px-): 100% 회의록 + 플로팅 버튼
- 아이패드 최적화 (바텀시트 높이 및 위치 조정)

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yabo0812 2025-10-22 19:50:32 +09:00
parent cf4cd5a436
commit f5aa92944d
7 changed files with 800 additions and 52 deletions

View File

@ -5,28 +5,79 @@
<title>회의 진행 중 - 회의록 서비스</title> <title>회의 진행 중 - 회의록 서비스</title>
<link rel="stylesheet" href="common.css"> <link rel="stylesheet" href="common.css">
<style> <style>
/* 레이아웃: 모바일에서는 메인 콘텐츠만, 태블릿+ 에서는 우측 사이드바 표시 */ /* 화면 전체를 사용하는 레이아웃 */
body {
margin: 0;
padding: 0;
overflow-x: hidden;
}
.page {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
max-width: 100% !important;
padding: 0 !important;
margin: 0 !important;
flex: 1;
display: flex;
flex-direction: column;
}
/* 레이아웃: 모바일에서는 메인 콘텐츠만, 데스크톱에서는 좌우 2열 */
.main-layout { .main-layout {
display: flex; display: flex;
gap: var(--space-md); gap: 0;
flex: 1;
overflow: hidden;
} }
.main-content { .main-content {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
overflow-y: auto;
padding: 0 var(--space-md) var(--space-md);
background: var(--gray-50);
} }
.right-sidebar { .right-sidebar {
display: none; /* 태블릿 이하에서는 숨김 */ display: none; /* 모바일에서는 숨김 */
} }
/* 데스크톱: 좌우 비율 조정 (60-65% : 35-40%) */
@media (min-width: 1024px) { @media (min-width: 1024px) {
.main-content {
flex: 0 0 62%;
max-width: 62%;
padding: var(--space-sm) var(--space-lg);
}
.right-sidebar { .right-sidebar {
display: block; display: block;
width: 320px; flex: 0 0 38%;
flex-shrink: 0; max-width: 38%;
border-left: 1px solid var(--gray-300); border-left: 1px solid var(--gray-300);
padding-left: var(--space-md); padding: var(--space-sm) var(--space-lg);
overflow-y: auto;
background: var(--white);
}
}
/* 대형 화면: 최대 너비 제한 없이 비율 유지 */
@media (min-width: 1440px) {
.main-content {
flex: 0 0 65%;
max-width: 65%;
padding: var(--space-sm) var(--space-xl);
}
.right-sidebar {
flex: 0 0 35%;
max-width: 35%;
padding: var(--space-sm) var(--space-xl);
} }
} }
@ -70,14 +121,6 @@
50% { transform: scaleY(0.5); } 50% { transform: scaleY(0.5); }
} }
.live-speech {
background: var(--primary-light);
border-left: 4px solid var(--primary);
padding: var(--space-md);
border-radius: var(--radius-md);
margin-bottom: var(--space-md);
}
.term-highlight { .term-highlight {
background: #FFF3CD; background: #FFF3CD;
padding: 2px 4px; padding: 2px 4px;
@ -323,13 +366,233 @@
color: var(--gray-900); color: var(--gray-900);
margin-bottom: var(--space-sm); margin-bottom: var(--space-sm);
} }
/* 헤더 반응형 패딩 */
header .header-content {
padding: var(--space-md);
}
@media (min-width: 1024px) {
header .header-content {
padding: var(--space-md) var(--space-lg);
}
}
@media (min-width: 1440px) {
header .header-content {
padding: var(--space-md) var(--space-xl);
}
}
/* 하단 액션바 반응형 패딩 */
.bottom-action-bar {
padding: var(--space-md);
}
@media (min-width: 1024px) {
.bottom-action-bar {
padding: var(--space-md) var(--space-lg);
}
}
@media (min-width: 1440px) {
.bottom-action-bar {
padding: var(--space-md) var(--space-xl);
}
}
/* ========================================
모바일 플로팅 버튼 & 바텀시트
======================================== */
/* 플로팅 버튼 (모바일 전용) */
.floating-btn {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
bottom: 100px;
right: 16px;
width: 56px;
height: 56px;
background: transparent;
border: none;
cursor: pointer;
z-index: 90;
padding: 0;
transition: all var(--transition-normal);
}
.floating-btn img {
width: 100%;
height: 100%;
object-fit: contain;
}
.floating-btn:hover {
transform: scale(1.1);
}
.floating-btn:active {
transform: scale(0.95);
}
.floating-badge {
position: absolute;
top: -2px;
right: -2px;
background: #DC2626;
color: var(--white);
font-size: 11px;
font-weight: bold;
padding: 3px 6px;
border-radius: var(--radius-full);
min-width: 22px;
height: 22px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
/* 데스크톱에서는 플로팅 버튼 숨김 */
@media (min-width: 1024px) {
.floating-btn {
display: none;
}
}
/* 바텀시트 오버레이 */
.bottom-sheet-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 95;
opacity: 0;
transition: opacity var(--transition-normal);
}
.bottom-sheet-overlay.active {
display: block;
opacity: 1;
}
/* 바텀시트 */
.bottom-sheet {
display: none;
position: fixed;
left: 0;
right: 0;
bottom: 0;
max-height: 80vh;
background: var(--white);
border-radius: 16px 16px 0 0;
z-index: 100;
transform: translateY(calc(100% + 70px));
transition: transform var(--transition-slow);
overflow: hidden;
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.12);
padding-bottom: 70px;
}
.bottom-sheet.active {
display: flex;
flex-direction: column;
transform: translateY(0);
}
/* 바텀시트 드래그 핸들 */
.bottom-sheet-handle {
display: flex;
justify-content: center;
align-items: center;
padding: var(--space-sm) 0;
cursor: grab;
}
.bottom-sheet-handle-bar {
width: 40px;
height: 4px;
background: var(--gray-300);
border-radius: 2px;
}
/* 바텀시트 헤더 */
.bottom-sheet-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-md);
border-bottom: 1px solid var(--gray-300);
}
.bottom-sheet-title {
font-size: var(--font-h3);
font-weight: var(--font-weight-bold);
color: var(--gray-900);
margin: 0;
}
.bottom-sheet-close {
background: transparent;
border: none;
font-size: 24px;
color: var(--gray-500);
cursor: pointer;
padding: 0;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
transition: background var(--transition-fast);
}
.bottom-sheet-close:hover {
background: var(--gray-100);
}
/* 바텀시트 콘텐츠 */
.bottom-sheet-content {
flex: 1;
overflow-y: auto;
padding: 0 var(--space-md) var(--space-md);
}
/* 바텀시트 내부 사이드바 탭 스타일 조정 */
.bottom-sheet .sidebar-tabs {
margin-bottom: var(--space-md);
background: var(--white);
position: sticky;
top: 0;
z-index: 10;
padding-top: var(--space-sm);
}
/* 바텀시트 내부 패널 간격 */
.bottom-sheet .sidebar-panel {
padding-bottom: var(--space-lg);
}
/* 데스크톱에서는 바텀시트 숨김 */
@media (min-width: 1024px) {
.bottom-sheet,
.bottom-sheet-overlay {
display: none !important;
}
}
</style> </style>
</head> </head>
<body> <body>
<div class="page"> <div class="page">
<!-- Header (Fixed, Collapsible) --> <!-- Header (Fixed, Collapsible) -->
<header style="position: sticky; top: 0; background: var(--white); border-bottom: 1px solid var(--gray-300); z-index: 100;"> <header style="position: sticky; top: 0; background: var(--white); border-bottom: 1px solid var(--gray-300); z-index: 100;">
<div style="padding: var(--space-md);"> <div class="header-content">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-sm);"> <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-sm);">
<h1 style="font-size: var(--font-h3); margin: 0;">2025년 1분기 제품 기획 회의</h1> <h1 style="font-size: var(--font-h3); margin: 0;">2025년 1분기 제품 기획 회의</h1>
</div> </div>
@ -361,21 +624,9 @@
<div class="container"> <div class="container">
<div class="main-layout"> <div class="main-layout">
<!-- Left: Main Content --> <!-- Left: Main Content -->
<div class="main-content"> <div class="main-content" style="margin-top: 0px;;">
<!-- Live Speech Area --> <!-- Meeting Sections (Tabs) -->
<div class="live-speech"> <div class="tabs" id="sectionTamain-contentbs">
<div style="display: flex; align-items: center; gap: var(--space-sm); margin-bottom: var(--space-sm);">
<div class="avatar avatar-blue avatar-sm"></div>
<span class="text-small font-medium">박서연</span>
<span class="badge badge-ongoing">발언 중</span>
</div>
<p id="liveText" style="font-size: var(--font-body); line-height: 1.6; margin: 0;">
AI 기반 회의록 자동 생성 기능에 대해 <span class="term-highlight" onclick="showTermExplanation('NLP')">NLP</span> 모델을 적용하면 정확도를 95% 이상으로 높일 수 있습니다...
</p>
</div>
<!-- Meeting Sections (Tabs) -->
<div class="tabs" id="sectionTabs">
<div class="tab active" data-section="0" onclick="switchSection(0)">회의 개요</div> <div class="tab active" data-section="0" onclick="switchSection(0)">회의 개요</div>
<div class="tab" data-section="1" onclick="switchSection(1)">논의 사항</div> <div class="tab" data-section="1" onclick="switchSection(1)">논의 사항</div>
<div class="tab" data-section="2" onclick="switchSection(2)">결정 사항</div> <div class="tab" data-section="2" onclick="switchSection(2)">결정 사항</div>
@ -392,7 +643,7 @@
<h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3> <h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3>
<div style="display: flex; gap: var(--space-sm);"> <div style="display: flex; gap: var(--space-sm);">
<span class="text-caption text-muted">2분 전 생성</span> <span class="text-caption text-muted">2분 전 생성</span>
<button class="btn btn-ghost btn-sm" onclick="editSummary(0)">편집</button> <button class="btn btn-secondary btn-sm" onclick="regenerateSummary(0)">AI재생성</button>
</div> </div>
</div> </div>
<p class="text-small" id="summary-0"> <p class="text-small" id="summary-0">
@ -404,7 +655,7 @@
<div class="card mb-md"> <div class="card mb-md">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md);"> <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md);">
<h3 class="text-small font-bold" style="margin: 0;">내용</h3> <h3 class="text-small font-bold" style="margin: 0;">내용</h3>
<button class="btn btn-ghost btn-sm" onclick="editContent(0)">✏️ 편집</button> <button class="btn btn-primary btn-sm" onclick="editContent(0)">편집</button>
</div> </div>
<div id="content-0" style="line-height: 1.8;"> <div id="content-0" style="line-height: 1.8;">
<p><strong>회의 목적:</strong> 2025년 1분기 신제품 개발 방향 수립</p> <p><strong>회의 목적:</strong> 2025년 1분기 신제품 개발 방향 수립</p>
@ -428,7 +679,7 @@
<h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3> <h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3>
<div style="display: flex; gap: var(--space-sm);"> <div style="display: flex; gap: var(--space-sm);">
<span class="text-caption text-muted">5분 전 생성</span> <span class="text-caption text-muted">5분 전 생성</span>
<button class="btn btn-ghost btn-sm" onclick="editSummary(1)">편집</button> <button class="btn btn-secondary btn-sm" onclick="regenerateSummary(1)">AI재생성</button>
</div> </div>
</div> </div>
<p class="text-small" id="summary-1"> <p class="text-small" id="summary-1">
@ -437,6 +688,10 @@
</div> </div>
<div class="card mb-md"> <div class="card mb-md">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md);">
<h3 class="text-small font-bold" style="margin: 0;">내용</h3>
<button class="btn btn-primary btn-sm" onclick="editContent(1)">편집</button>
</div>
<div id="content-1" style="line-height: 1.8;"> <div id="content-1" style="line-height: 1.8;">
<p><strong>1. AI 모델 정확도</strong></p> <p><strong>1. AI 모델 정확도</strong></p>
<p>- 현재 STT 정확도: 92%</p> <p>- 현재 STT 정확도: 92%</p>
@ -461,7 +716,7 @@
<h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3> <h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3>
<div style="display: flex; gap: var(--space-sm);"> <div style="display: flex; gap: var(--space-sm);">
<span class="text-caption text-muted">3분 전 생성</span> <span class="text-caption text-muted">3분 전 생성</span>
<button class="btn btn-ghost btn-sm" onclick="editSummary(2)">편집</button> <button class="btn btn-secondary btn-sm" onclick="regenerateSummary(2)">AI재생성</button>
</div> </div>
</div> </div>
<p class="text-small" id="summary-2"> <p class="text-small" id="summary-2">
@ -470,6 +725,10 @@
</div> </div>
<div class="card mb-md"> <div class="card mb-md">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md);">
<h3 class="text-small font-bold" style="margin: 0;">내용</h3>
<button class="btn btn-primary btn-sm" onclick="editContent(2)">편집</button>
</div>
<div id="content-2" style="line-height: 1.8;"> <div id="content-2" style="line-height: 1.8;">
<p><strong>✓ MVP 범위 확정</strong></p> <p><strong>✓ MVP 범위 확정</strong></p>
<p>- 실시간 STT 및 회의록 자동 생성</p> <p>- 실시간 STT 및 회의록 자동 생성</p>
@ -495,7 +754,7 @@
<h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3> <h3 class="text-small font-bold" style="margin: 0;">🤖 AI 요약</h3>
<div style="display: flex; gap: var(--space-sm);"> <div style="display: flex; gap: var(--space-sm);">
<span class="text-caption text-muted">1분 전 생성</span> <span class="text-caption text-muted">1분 전 생성</span>
<button class="btn btn-ghost btn-sm" onclick="editSummary(3)">편집</button> <button class="btn btn-secondary btn-sm" onclick="regenerateSummary(3)">AI재생성</button>
</div> </div>
</div> </div>
<p class="text-small" id="summary-3"> <p class="text-small" id="summary-3">
@ -504,6 +763,10 @@
</div> </div>
<div class="card mb-md"> <div class="card mb-md">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-md);">
<h3 class="text-small font-bold" style="margin: 0;">내용</h3>
<button class="btn btn-primary btn-sm" onclick="editContent(3)">편집</button>
</div>
<div id="content-3" style="line-height: 1.8;"> <div id="content-3" style="line-height: 1.8;">
<div class="list-item mb-sm"> <div class="list-item mb-sm">
<input type="checkbox" class="checkbox"> <input type="checkbox" class="checkbox">
@ -756,26 +1019,28 @@
<div class="sidebar-panel" id="sidebar-references"> <div class="sidebar-panel" id="sidebar-references">
<h3 class="text-small font-bold mb-md">관련 자료</h3> <h3 class="text-small font-bold mb-md">관련 자료</h3>
<h4 style="font-size: var(--font-body); font-weight: var(--font-weight-semibold); color: var(--gray-700); margin-bottom: var(--space-sm);"> <div class="related-doc-item" onclick="openRelatedDoc(1)">
📄 관련 회의록 (3건) <div class="related-doc-title">Q4 회의록 작성 가이드 배포</div>
</h4>
<div class="related-doc-item" onclick="openRelatedDoc('meeting-001')">
<div class="related-doc-header">
2024년 4분기 제품 기획 회의
</div>
<div class="related-doc-meta"> <div class="related-doc-meta">
<span class="date">2024-10-15</span> | <span class="related-doc-relevance">관련도 92%</span> <span class="date">2024-10-01</span> | <span class="related-doc-relevance">관련도 95%</span>
</div> </div>
<div class="related-doc-text"> <div class="related-doc-text">
신규 회의록 서비스 MVP 개발 일정 논의. AI 기능 우선순위와 예산 확정. 회의록 자동 작성 기능 개발을 위한 요구사항 정의 회의. AI 정확도 목표 85% 이상.
</div> </div>
</div> </div>
<div class="related-doc-item" onclick="openRelatedDoc('meeting-002')"> <div class="related-doc-item" onclick="openRelatedDoc(2)">
<div class="related-doc-header"> <div class="related-doc-title">신제품 개발 킥오프</div>
API 설계 리뷰 회의 <div class="related-doc-meta">
<span class="date">2024-09-15</span> | <span class="related-doc-relevance">관련도 82%</span>
</div> </div>
<div class="related-doc-text">
1분기 신제품 개발 방향성 논의. 협업 도구 시장 분석 및 차별화 전략 수립.
</div>
</div>
<div class="related-doc-item" onclick="openRelatedDoc(3)">
<div class="related-doc-title">API 설계 리뷰</div>
<div class="related-doc-meta"> <div class="related-doc-meta">
<span class="date">2024-09-28</span> | <span class="related-doc-relevance">관련도 78%</span> <span class="date">2024-09-28</span> | <span class="related-doc-relevance">관련도 78%</span>
</div> </div>
@ -786,10 +1051,238 @@
</div> </div>
</aside> </aside>
</div> </div>
<!-- 모바일 플로팅 버튼 -->
<button class="floating-btn" onclick="openBottomSheet()" id="floatingBtn">
<img src="img/review.png" alt="참고자료">
<span class="floating-badge" id="floatingBadge">32</span>
</button>
<!-- 바텀시트 오버레이 -->
<div class="bottom-sheet-overlay" id="bottomSheetOverlay" onclick="closeBottomSheet()"></div>
<!-- 바텀시트 -->
<div class="bottom-sheet" id="bottomSheet">
<div class="bottom-sheet-handle">
<div class="bottom-sheet-handle-bar"></div>
</div>
<div class="bottom-sheet-header">
<h3 class="bottom-sheet-title">참고자료</h3>
<button class="bottom-sheet-close" onclick="closeBottomSheet()"></button>
</div>
<div class="bottom-sheet-content">
<!-- 탭 메뉴 -->
<div class="sidebar-tabs">
<button class="sidebar-tab active" data-sidebar="participants" onclick="switchBottomSheetTab('participants')">참석자</button>
<button class="sidebar-tab" data-sidebar="ai-suggestions" onclick="switchBottomSheetTab('ai-suggestions')">AI 제안</button>
<button class="sidebar-tab" data-sidebar="terms" onclick="switchBottomSheetTab('terms')">용어 사전</button>
<button class="sidebar-tab" data-sidebar="references" onclick="switchBottomSheetTab('references')">관련회의록</button>
</div>
<!-- 참석자 패널 -->
<div class="sidebar-panel active" id="bs-participants">
<h3 class="text-small font-bold mb-sm">참석자 (<span id="bsParticipantCount">4</span>명)</h3>
<!-- 참석자 추가 폼 -->
<div style="margin-bottom: var(--space-md);">
<div style="display: flex; gap: var(--space-xs);">
<input type="email" placeholder="이메일 주소 입력" class="form-control" id="bsInviteEmailInput" style="flex: 1;">
<button class="btn btn-primary btn-sm" onclick="inviteParticipant()">초대</button>
</div>
</div>
<!-- 참석자 리스트 -->
<div id="bsParticipantList">
<div class="participant-item">
<div class="avatar avatar-green avatar-sm"></div>
<div style="flex: 1;">
<div class="text-small font-medium">김민준</div>
</div>
</div>
<div class="participant-item">
<div class="avatar avatar-blue avatar-sm"></div>
<div style="flex: 1;">
<div class="text-small font-medium">박서연</div>
</div>
</div>
<div class="participant-item">
<div class="avatar avatar-yellow avatar-sm"></div>
<div style="flex: 1;">
<div class="text-small font-medium">이준호</div>
</div>
</div>
<div class="participant-item">
<div class="avatar avatar-purple avatar-sm"></div>
<div style="flex: 1;">
<div class="text-small font-medium">최유진</div>
</div>
</div>
</div>
</div>
<!-- AI 제안 패널 -->
<div class="sidebar-panel" id="bs-ai-suggestions">
<h3 class="text-small font-bold mb-sm">AI 제안</h3>
<!-- 논의사항 제안 -->
<div class="ai-suggestion-card" id="bs-suggestion-discussion">
<div class="ai-suggestion-header">
💬 논의사항 제안
</div>
<div class="ai-suggestion-text">
<strong>AI 모델 정확도 향상 방안</strong><br>
- 현재 STT 정확도: 92%<br>
- 목표 정확도: 95% 이상<br>
- 도메인 특화 학습 데이터 확보 필요
</div>
<div class="ai-actions">
<button class="btn btn-primary btn-sm" onclick="applyDiscussionSuggestion()">논의사항에 적용</button>
<button class="btn btn-ghost btn-sm" onclick="dismissSuggestion('discussion')">수정</button>
</div>
</div>
<!-- 결정사항 제안 -->
<div class="ai-suggestion-card" id="bs-suggestion-decision">
<div class="ai-suggestion-header">
✅ 결정사항 제안
</div>
<div class="ai-suggestion-text">
<strong>개발 일정 최종 확정</strong><br>
- 설계: 2주 (11/1~11/14)<br>
- 개발: 10주 (11/15~1/23)<br>
- 테스트 및 배포: 2주 (1/24~2/6)
</div>
<div class="ai-actions">
<button class="btn btn-primary btn-sm" onclick="applyDecisionSuggestion()">결정사항에 적용</button>
<button class="btn btn-ghost btn-sm" onclick="dismissSuggestion('decision')">수정</button>
</div>
</div>
<!-- 액션아이템 제안 -->
<div class="ai-suggestion-card" id="bs-suggestion-todo">
<div class="ai-suggestion-header">
📋 액션 아이템(Todo) 자동 추출
</div>
<div class="ai-suggestion-text">
1. API 명세서 작성 (이준호, 10/23까지)<br>
2. UI 프로토타입 디자인 (최유진, 10/28까지)<br>
3. AI 모델 성능 테스트 (박서연, 10/25까지)
</div>
<div class="ai-actions">
<button class="btn btn-primary btn-sm" onclick="applyTodoSuggestion()">3개 Todo 생성</button>
<button class="btn btn-ghost btn-sm" onclick="dismissSuggestion('todo')">수정</button>
</div>
</div>
</div>
<!-- 용어 사전 패널 -->
<div class="sidebar-panel" id="bs-terms">
<h3 class="text-small font-bold mb-sm">용어 사전</h3>
<div style="margin-bottom: var(--space-md);">
<input type="text" placeholder="용어를 검색하세요 (예: API, Mobile First)" class="form-control" id="bsTermSearchInput">
</div>
<div id="bsTermList">
<div class="term-item highlight" onclick="showTermDetail('STT')">
<div class="term-name">
STT
<span class="term-badge">기술</span>
<span class="term-mention-icon">💬</span>
</div>
<div class="term-definition">
Speech-to-Text의 약자. 음성을 텍스트로 변환하는 AI 기술입니다.
</div>
<div class="term-context">회의에서 3회 언급됨</div>
</div>
<div class="term-item highlight" onclick="showTermDetail('마이크로서비스')">
<div class="term-name">
마이크로서비스
<span class="term-badge">아키텍처</span>
<span class="term-mention-icon">💬</span>
</div>
<div class="term-definition">
애플리케이션을 작고 독립적인 서비스들로 분리하여 개발하고 배포하는 아키텍처 패턴입니다.
</div>
<div class="term-context">회의에서 언급됨</div>
</div>
<div class="term-item highlight" onclick="showTermDetail('MVP')">
<div class="term-name">
MVP
<span class="term-badge">방법론</span>
<span class="term-mention-icon">💬</span>
</div>
<div class="term-definition">
Minimum Viable Product의 약자. 최소한의 기능만 갖춘 제품으로, 시장 반응을 빠르게 확인하기 위해 개발합니다.
</div>
<div class="term-context">개발 일정 논의에서 언급</div>
</div>
<div class="term-item" onclick="showTermDetail('RESTful API')">
<div class="term-name">
RESTful API
<span class="term-badge">기술</span>
</div>
<div class="term-definition">
REST(Representational State Transfer) 아키텍처 스타일을 따르는 웹 서비스 API 설계 방식입니다.
</div>
<div class="term-context">API 설계 리뷰 회의 참조</div>
</div>
<div class="term-item" onclick="showTermDetail('JWT')">
<div class="term-name">
JWT
<span class="term-badge">보안</span>
</div>
<div class="term-definition">
JSON Web Token의 약자. 사용자 인증 정보를 안전하게 전송하기 위한 토큰 기반 인증 방식입니다.
</div>
<div class="term-context">API Gateway 보안 정책에서 채택</div>
</div>
</div>
</div>
<!-- 관련회의록 패널 -->
<div class="sidebar-panel" id="bs-references">
<h3 class="text-small font-bold mb-md">관련 자료</h3>
<div class="related-doc-item" onclick="openRelatedDoc(1)">
<div class="related-doc-title">Q4 회의록 작성 가이드 배포</div>
<div class="related-doc-meta">
<span class="date">2024-10-01</span> | <span class="related-doc-relevance">관련도 95%</span>
</div>
<div class="related-doc-text">
회의록 자동 작성 기능 개발을 위한 요구사항 정의 회의. AI 정확도 목표 85% 이상.
</div>
</div>
<div class="related-doc-item" onclick="openRelatedDoc(2)">
<div class="related-doc-title">신제품 개발 킥오프</div>
<div class="related-doc-meta">
<span class="date">2024-09-15</span> | <span class="related-doc-relevance">관련도 82%</span>
</div>
<div class="related-doc-text">
1분기 신제품 개발 방향성 논의. 협업 도구 시장 분석 및 차별화 전략 수립.
</div>
</div>
<div class="related-doc-item" onclick="openRelatedDoc(3)">
<div class="related-doc-title">API 설계 리뷰</div>
<div class="related-doc-meta">
<span class="date">2024-09-28</span> | <span class="related-doc-relevance">관련도 78%</span>
</div>
<div class="related-doc-text">
RESTful API 설계 원칙과 보안 정책 확정. 담당자별 역할 분담.
</div>
</div>
</div>
</div>
</div>
</div> </div>
<!-- Bottom Action Bar (Fixed) --> <!-- Bottom Action Bar (Fixed) -->
<div style="position: fixed; bottom: 0; left: 0; right: 0; background: var(--white); border-top: 1px solid var(--gray-300); padding: var(--space-md); display: flex; gap: var(--space-sm); z-index: 100;"> <div class="bottom-action-bar" style="position: fixed; bottom: 0; left: 0; right: 0; background: var(--white); border-top: 1px solid var(--gray-300); display: flex; gap: var(--space-sm); z-index: 100;">
<button class="btn btn-ghost" onclick="pauseRecording()" id="pauseBtn"> <button class="btn btn-ghost" onclick="pauseRecording()" id="pauseBtn">
<span>⏸️</span> <span>⏸️</span>
<span>일시정지</span> <span>일시정지</span>
@ -845,6 +1338,50 @@
</div> </div>
</div> </div>
<!-- Related Document Detail Modal (모바일 전용) -->
<div id="relatedDocModal" class="modal-overlay">
<div class="modal" style="max-width: 600px;">
<div class="modal-header">
<h2 class="modal-title" id="relatedDocTitle">회의록 제목</h2>
<button class="modal-close" onclick="closeModal('relatedDocModal')"></button>
</div>
<div class="modal-body">
<div style="margin-bottom: var(--space-md);">
<div style="display: flex; gap: var(--space-sm); align-items: center; margin-bottom: var(--space-sm);">
<span class="badge badge-primary" id="relatedDocDate">2024-10-01</span>
<span class="text-small text-gray-500" id="relatedDocRelevance">관련도 95%</span>
</div>
</div>
<h3 class="text-small font-bold mb-sm" style="color: var(--gray-700);">📝 회의 개요</h3>
<p class="text-small mb-md" id="relatedDocOverview" style="line-height: 1.6;">
회의록 자동 작성 기능 개발을 위한 요구사항 정의 회의입니다.
</p>
<h3 class="text-small font-bold mb-sm" style="color: var(--gray-700);">💡 주요 논의사항</h3>
<ul class="text-small mb-md" id="relatedDocDiscussions" style="line-height: 1.6; padding-left: var(--space-md);">
<li>AI 모델 정확도 목표: 85% 이상</li>
<li>실시간 STT 처리 성능 요구사항</li>
<li>회의록 자동 요약 알고리즘 검토</li>
</ul>
<h3 class="text-small font-bold mb-sm" style="color: var(--gray-700);">✅ 결정사항</h3>
<ul class="text-small mb-md" id="relatedDocDecisions" style="line-height: 1.6; padding-left: var(--space-md);">
<li>OpenAI Whisper API 활용 결정</li>
<li>MVP 개발 범위 확정</li>
<li>개발 일정: 2개월 (설계 2주 + 개발 6주)</li>
</ul>
<h3 class="text-small font-bold mb-sm" style="color: var(--gray-700);">📋 액션 아이템</h3>
<ul class="text-small mb-md" id="relatedDocTodos" style="line-height: 1.6; padding-left: var(--space-md);">
<li>AI 모델 성능 테스트 (박서연, ~10/10)</li>
<li>UI 프로토타입 디자인 (최유진, ~10/15)</li>
<li>API 명세서 작성 (이준호, ~10/12)</li>
</ul>
</div>
</div>
</div>
<script src="common.js"></script> <script src="common.js"></script>
<script> <script>
let currentSection = 0; let currentSection = 0;
@ -1120,10 +1657,221 @@
// 실제로는 모달로 상세 정보 표시 // 실제로는 모달로 상세 정보 표시
} }
// 관련회의록 열기 // 관련회의록 데이터
const relatedDocsData = {
1: {
title: 'Q4 회의록 작성 가이드 배포',
date: '2024-10-01',
relevance: '95%',
overview: '회의록 자동 작성 기능 개발을 위한 요구사항 정의 회의. AI 정확도 목표 85% 이상 설정.',
discussions: [
'AI 모델 정확도 목표: 85% 이상',
'실시간 STT 처리 성능 요구사항',
'회의록 자동 요약 알고리즘 검토',
'다국어 지원 범위 논의'
],
decisions: [
'OpenAI Whisper API 활용 결정',
'MVP 개발 범위 확정',
'개발 일정: 2개월 (설계 2주 + 개발 6주)',
'베타 테스트 대상: 내부 팀 10명'
],
todos: [
'AI 모델 성능 테스트 (박서연, ~10/10)',
'UI 프로토타입 디자인 (최유진, ~10/15)',
'API 명세서 작성 (이준호, ~10/12)',
'베타 테스터 모집 (김민준, ~10/20)'
],
url: '10-회의록상세조회.html'
},
2: {
title: '신제품 개발 킥오프',
date: '2024-09-15',
relevance: '82%',
overview: '1분기 신제품 개발 방향성 논의. 협업 도구 시장 분석 및 차별화 전략 수립.',
discussions: [
'경쟁사 분석: Notion, Slack, Teams',
'AI 기반 자동화 기능의 차별점',
'목표 고객층: 중소기업 및 스타트업',
'가격 정책 및 수익 모델'
],
decisions: [
'AI 회의록 자동 작성을 핵심 기능으로 선정',
'Freemium 모델 적용',
'론칭 목표: 2025년 1분기',
'MVP 먼저 출시 후 점진적 기능 확장'
],
todos: [
'시장 조사 보고서 작성 (김민준, ~9/25)',
'기술 스택 검토 (이준호, ~9/20)',
'디자인 시스템 구축 (최유진, ~9/30)'
],
url: '10-회의록상세조회.html'
},
3: {
title: 'API 설계 리뷰',
date: '2024-09-28',
relevance: '78%',
overview: 'RESTful API 설계 원칙과 보안 정책 확정. 담당자별 역할 분담.',
discussions: [
'REST API 엔드포인트 구조',
'인증/인가 방식: JWT vs OAuth2',
'API 버전 관리 전략',
'에러 핸들링 표준화'
],
decisions: [
'JWT 기반 인증 방식 채택',
'API 버저닝: URL 경로 방식 (/v1/, /v2/)',
'표준 HTTP 상태 코드 사용',
'Rate Limiting 적용: 분당 100회'
],
todos: [
'API 명세서 초안 작성 (이준호, ~10/5)',
'보안 테스트 수행 (보안팀, ~10/10)',
'API 문서 자동화 도구 검토 (이준호, ~10/8)'
],
url: '10-회의록상세조회.html'
}
};
// 관련회의록 열기 (반응형 분기)
function openRelatedDoc(docId) { function openRelatedDoc(docId) {
showToast('관련회의록을 새 탭에서 엽니다', 'info'); const isMobile = window.innerWidth < 1024;
// 실제로는 window.open()으로 새 탭 열기
if (isMobile) {
// 모바일: 모달로 핵심 내용 표시
showRelatedDocModal(docId);
} else {
// 웹: 새 탭으로 전체 회의록 열기
const docData = relatedDocsData[docId];
if (docData && docData.url) {
window.open(docData.url, '_blank');
showToast('관련회의록을 새 탭에서 열었습니다', 'info');
}
}
}
// 관련회의록 모달 표시 (모바일)
function showRelatedDocModal(docId) {
const docData = relatedDocsData[docId];
if (!docData) return;
// 모달 제목과 메타 정보 업데이트
$('#relatedDocTitle').textContent = docData.title;
$('#relatedDocDate').textContent = docData.date;
$('#relatedDocRelevance').textContent = `관련도 ${docData.relevance}`;
// 회의 개요
$('#relatedDocOverview').textContent = docData.overview;
// 주요 논의사항
const discussionsHtml = docData.discussions.map(item => `<li>${item}</li>`).join('');
$('#relatedDocDiscussions').innerHTML = discussionsHtml;
// 결정사항
const decisionsHtml = docData.decisions.map(item => `<li>${item}</li>`).join('');
$('#relatedDocDecisions').innerHTML = decisionsHtml;
// 액션 아이템
const todosHtml = docData.todos.map(item => `<li>${item}</li>`).join('');
$('#relatedDocTodos').innerHTML = todosHtml;
// 모달 열기
openModal('relatedDocModal');
}
// 바텀시트 열기
function openBottomSheet() {
const bottomSheet = $('#bottomSheet');
const overlay = $('#bottomSheetOverlay');
overlay.classList.add('active');
bottomSheet.classList.add('active');
// 바디 스크롤 방지
document.body.style.overflow = 'hidden';
}
// 바텀시트 닫기
function closeBottomSheet() {
const bottomSheet = $('#bottomSheet');
const overlay = $('#bottomSheetOverlay');
overlay.classList.remove('active');
bottomSheet.classList.remove('active');
// 바디 스크롤 복원
document.body.style.overflow = '';
}
// 바텀시트 탭 전환
function switchBottomSheetTab(tabName) {
// 바텀시트 내부의 탭 버튼 업데이트
const tabs = document.querySelectorAll('.bottom-sheet .sidebar-tab');
tabs.forEach(tab => {
tab.classList.remove('active');
});
// 선택된 탭 활성화
const selectedTab = document.querySelector(`.bottom-sheet .sidebar-tab[data-sidebar="${tabName}"]`);
if (selectedTab) {
selectedTab.classList.add('active');
}
// 바텀시트 내부의 패널 전환
const panels = {
'participants': $('#bs-participants'),
'ai-suggestions': $('#bs-ai-suggestions'),
'terms': $('#bs-terms'),
'references': $('#bs-references')
};
// 모든 패널 숨김
Object.values(panels).forEach(panel => {
if (panel) panel.classList.remove('active');
});
// 선택된 패널 표시
if (panels[tabName]) {
panels[tabName].classList.add('active');
}
}
// 바텀시트 드래그 다운 제스처 (추가 개선 가능)
let startY = 0;
let currentY = 0;
const bottomSheetElement = $('#bottomSheet');
const handleElement = bottomSheetElement?.querySelector('.bottom-sheet-handle');
if (handleElement) {
handleElement.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
});
handleElement.addEventListener('touchmove', (e) => {
currentY = e.touches[0].clientY;
const deltaY = currentY - startY;
// 아래로 드래그 시에만 반응
if (deltaY > 0) {
bottomSheetElement.style.transform = `translateY(${deltaY}px)`;
}
});
handleElement.addEventListener('touchend', (e) => {
const deltaY = currentY - startY;
// 100px 이상 드래그 시 닫기
if (deltaY > 100) {
closeBottomSheet();
}
// 원래 위치로 복원
bottomSheetElement.style.transform = '';
startY = 0;
currentY = 0;
});
} }
// 페이지 이탈 경고 // 페이지 이탈 경고

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB