mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 12:36:23 +00:00
- 가파팀 프로토타입 파일 삭제 - 가파팀 유저스토리 삭제 - 실시간 회의록 작성 플로우 설계서 추가 (Mermaid, Markdown) - 백업 및 데이터 디렉토리 추가 - AI 데이터 샘플 생성 도구 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
648 lines
22 KiB
HTML
648 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>회의 진행 - 회의록 서비스</title>
|
|
<link rel="stylesheet" href="common.css">
|
|
<style>
|
|
body {
|
|
background-color: var(--color-gray-50);
|
|
margin: 0;
|
|
overflow: hidden;
|
|
}
|
|
.meeting-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100vh;
|
|
}
|
|
.meeting-header {
|
|
background: var(--color-white);
|
|
border-bottom: 1px solid var(--color-gray-200);
|
|
padding: var(--spacing-4) var(--spacing-6);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
.meeting-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-4);
|
|
}
|
|
.meeting-title {
|
|
font-size: var(--font-size-h4);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-gray-900);
|
|
}
|
|
.recording-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-2);
|
|
padding: var(--spacing-2) var(--spacing-3);
|
|
background-color: var(--color-error-light);
|
|
color: var(--color-error-dark);
|
|
border-radius: var(--radius-md);
|
|
font-size: var(--font-size-body-small);
|
|
font-weight: var(--font-weight-medium);
|
|
}
|
|
.recording-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
background-color: var(--color-error-main);
|
|
border-radius: var(--radius-full);
|
|
animation: blink 1.5s ease-in-out infinite;
|
|
}
|
|
@keyframes blink {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.3; }
|
|
}
|
|
.meeting-body {
|
|
display: flex;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
}
|
|
.editor-panel {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--color-white);
|
|
border-right: 1px solid var(--color-gray-200);
|
|
}
|
|
.editor-toolbar {
|
|
padding: var(--spacing-3) var(--spacing-4);
|
|
border-bottom: 1px solid var(--color-gray-200);
|
|
display: flex;
|
|
gap: var(--spacing-2);
|
|
}
|
|
.editor-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: var(--spacing-6);
|
|
}
|
|
.editor-textarea {
|
|
width: 100%;
|
|
min-height: 300px;
|
|
border: none;
|
|
font-family: inherit;
|
|
font-size: var(--font-size-body);
|
|
line-height: var(--line-height-relaxed);
|
|
resize: none;
|
|
outline: none;
|
|
}
|
|
.side-panel {
|
|
width: 400px;
|
|
background: var(--color-white);
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-left: 1px solid var(--color-gray-200);
|
|
}
|
|
.side-panel-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid var(--color-gray-200);
|
|
}
|
|
.side-tab {
|
|
flex: 1;
|
|
padding: var(--spacing-3) var(--spacing-4);
|
|
background: transparent;
|
|
border: none;
|
|
border-bottom: 3px solid transparent;
|
|
font-size: var(--font-size-body-small);
|
|
font-weight: var(--font-weight-medium);
|
|
color: var(--color-gray-600);
|
|
cursor: pointer;
|
|
transition: all var(--transition-fast);
|
|
}
|
|
.side-tab.active {
|
|
color: var(--color-primary-main);
|
|
border-bottom-color: var(--color-primary-main);
|
|
}
|
|
.side-panel-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: var(--spacing-4);
|
|
}
|
|
.attendee-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-3);
|
|
padding: var(--spacing-3);
|
|
margin-bottom: var(--spacing-2);
|
|
background: var(--color-gray-50);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
.attendee-avatar {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: var(--radius-full);
|
|
background-color: var(--color-primary-main);
|
|
color: var(--color-white);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: var(--font-weight-semibold);
|
|
}
|
|
.attendee-info {
|
|
flex: 1;
|
|
}
|
|
.attendee-name {
|
|
font-weight: var(--font-weight-medium);
|
|
color: var(--color-gray-900);
|
|
}
|
|
.attendee-status {
|
|
font-size: var(--font-size-caption);
|
|
color: var(--color-gray-500);
|
|
}
|
|
.ai-suggestion {
|
|
background-color: var(--color-gray-50);
|
|
border: 1px dashed var(--color-primary-main);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--spacing-4);
|
|
margin-bottom: var(--spacing-4);
|
|
}
|
|
.ai-suggestion-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-2);
|
|
margin-bottom: var(--spacing-3);
|
|
font-weight: var(--font-weight-medium);
|
|
color: var(--color-primary-main);
|
|
}
|
|
.ai-suggestion-text {
|
|
font-size: var(--font-size-body-small);
|
|
color: var(--color-gray-600);
|
|
line-height: var(--line-height-relaxed);
|
|
margin-bottom: var(--spacing-3);
|
|
}
|
|
.ai-actions {
|
|
display: flex;
|
|
gap: var(--spacing-2);
|
|
}
|
|
|
|
/* 용어 사전 탭 스타일 */
|
|
.term-search-box {
|
|
margin-bottom: var(--spacing-4);
|
|
}
|
|
.term-search-input {
|
|
width: 100%;
|
|
padding: var(--spacing-3);
|
|
border: 1px solid var(--color-gray-300);
|
|
border-radius: var(--radius-md);
|
|
font-size: var(--font-size-body);
|
|
outline: none;
|
|
transition: all var(--transition-fast);
|
|
}
|
|
.term-search-input:focus {
|
|
border-color: var(--color-primary-main);
|
|
box-shadow: 0 0 0 3px rgba(0, 217, 177, 0.1);
|
|
}
|
|
.term-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--spacing-3);
|
|
}
|
|
.term-item {
|
|
background: var(--color-white);
|
|
border: 1px solid var(--color-gray-200);
|
|
border-radius: var(--radius-md);
|
|
padding: var(--spacing-4);
|
|
cursor: pointer;
|
|
transition: all var(--transition-fast);
|
|
}
|
|
.term-item:hover {
|
|
border-color: var(--color-primary-main);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
}
|
|
.term-item.highlight {
|
|
background-color: var(--color-primary-light);
|
|
border-color: var(--color-primary-main);
|
|
}
|
|
.term-name {
|
|
font-size: var(--font-size-body);
|
|
font-weight: var(--font-weight-semibold);
|
|
color: var(--color-gray-900);
|
|
margin-bottom: var(--spacing-2);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--spacing-2);
|
|
}
|
|
.term-badge {
|
|
font-size: var(--font-size-caption);
|
|
padding: 2px var(--spacing-2);
|
|
background-color: var(--color-primary-light);
|
|
color: var(--color-primary-dark);
|
|
border-radius: var(--radius-sm);
|
|
font-weight: var(--font-weight-medium);
|
|
}
|
|
.term-definition {
|
|
font-size: var(--font-size-body-small);
|
|
color: var(--color-gray-600);
|
|
line-height: var(--line-height-relaxed);
|
|
margin-bottom: var(--spacing-2);
|
|
}
|
|
.term-context {
|
|
font-size: var(--font-size-caption);
|
|
color: var(--color-gray-500);
|
|
padding-top: var(--spacing-2);
|
|
border-top: 1px solid var(--color-gray-100);
|
|
}
|
|
.no-results {
|
|
text-align: center;
|
|
padding: var(--spacing-8);
|
|
color: var(--color-gray-500);
|
|
}
|
|
|
|
@media (max-width: 1023px) {
|
|
.side-panel {
|
|
position: fixed;
|
|
right: -400px;
|
|
top: 0;
|
|
height: 100vh;
|
|
z-index: var(--z-sticky);
|
|
box-shadow: var(--shadow-lg);
|
|
transition: right var(--transition-base);
|
|
}
|
|
.side-panel.open {
|
|
right: 0;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="meeting-container">
|
|
<!-- 헤더 -->
|
|
<div class="meeting-header">
|
|
<div class="meeting-info">
|
|
<h1 class="meeting-title" id="meetingTitle">회의 진행 중</h1>
|
|
<div class="recording-indicator">
|
|
<div class="recording-dot"></div>
|
|
<span id="recordingTime">00:00</span>
|
|
</div>
|
|
</div>
|
|
<div style="display: flex; gap: var(--spacing-3);">
|
|
<button class="btn btn-text btn-icon hide-desktop" id="toggleSidePanel">☰</button>
|
|
<button class="btn btn-secondary" onclick="if(confirm('회의를 종료하시겠습니까?')) window.location.href='06-검증완료.html'">
|
|
회의 종료
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 본문 -->
|
|
<div class="meeting-body">
|
|
<!-- 에디터 패널 -->
|
|
<div class="editor-panel">
|
|
<div class="editor-toolbar">
|
|
<button class="btn btn-text btn-icon-sm">B</button>
|
|
<button class="btn btn-text btn-icon-sm">I</button>
|
|
<button class="btn btn-text btn-icon-sm">U</button>
|
|
<button class="btn btn-text btn-icon-sm">📝</button>
|
|
<button class="btn btn-text btn-icon-sm">🔗</button>
|
|
</div>
|
|
<div class="editor-content">
|
|
<textarea class="editor-textarea" id="meetingContent" placeholder="회의 내용을 작성하거나 AI가 자동으로 작성합니다...
|
|
|
|
# 참석자
|
|
- 김민준
|
|
- 박서연
|
|
- 이준호
|
|
|
|
# 안건
|
|
1. 신규 기능 개발 일정 논의
|
|
2. 예산 편성 검토
|
|
|
|
# 논의 내용
|
|
Mobile First 설계 방침으로 진행하기로 결정
|
|
AI 기반 회의록 자동 작성 기능을 핵심으로 개발
|
|
API Gateway 구축 및 마이크로서비스 아키텍처 적용
|
|
|
|
"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 사이드 패널 -->
|
|
<div class="side-panel" id="sidePanel">
|
|
<div class="side-panel-tabs">
|
|
<button class="side-tab active" data-tab="attendees">참석자</button>
|
|
<button class="side-tab" data-tab="ai">AI 제안</button>
|
|
<button class="side-tab" data-tab="terms">용어 사전</button>
|
|
<button class="side-tab" data-tab="related">관련 자료</button>
|
|
</div>
|
|
|
|
<div class="side-panel-content">
|
|
<!-- 참석자 탭 -->
|
|
<div class="tab-content" data-content="attendees">
|
|
<h3 style="margin-bottom: var(--spacing-4); font-size: var(--font-size-h4);">참석자 (3명)</h3>
|
|
<div class="attendee-item">
|
|
<div class="attendee-avatar">김</div>
|
|
<div class="attendee-info">
|
|
<div class="attendee-name">김민준</div>
|
|
<div class="attendee-status">발언 중 ✍️</div>
|
|
</div>
|
|
</div>
|
|
<div class="attendee-item">
|
|
<div class="attendee-avatar" style="background-color: var(--color-secondary-main);">박</div>
|
|
<div class="attendee-info">
|
|
<div class="attendee-name">박서연</div>
|
|
<div class="attendee-status">온라인</div>
|
|
</div>
|
|
</div>
|
|
<div class="attendee-item">
|
|
<div class="attendee-avatar" style="background-color: var(--color-info-main);">이</div>
|
|
<div class="attendee-info">
|
|
<div class="attendee-name">이준호</div>
|
|
<div class="attendee-status">온라인</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- AI 제안 탭 -->
|
|
<div class="tab-content" data-content="ai" style="display: none;">
|
|
<h3 style="margin-bottom: var(--spacing-4); font-size: var(--font-size-h4);">AI 제안</h3>
|
|
|
|
<div class="ai-suggestion">
|
|
<div class="ai-suggestion-header">
|
|
✨ 회의록 요약 제안
|
|
</div>
|
|
<div class="ai-suggestion-text">
|
|
Mobile First 설계 방침 확정 및 AI 기반 자동 작성 기능 개발 착수 결정. 마이크로서비스 아키텍처와 API Gateway 구축 계획 수립.
|
|
</div>
|
|
<div class="ai-actions">
|
|
<button class="btn btn-primary btn-sm">회의록에 적용</button>
|
|
<button class="btn btn-text btn-sm">수정</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ai-suggestion">
|
|
<div class="ai-suggestion-header">
|
|
📋 액션 아이템(Todo) 자동 추출
|
|
</div>
|
|
<div class="ai-suggestion-text">
|
|
1. API 명세서 작성 (이준호, 3/25까지)<br>
|
|
2. UI 프로토타입 완성 (최유진, 3/15까지)<br>
|
|
3. 예산 편성안 최종 검토 (박서연, 3/20까지)
|
|
</div>
|
|
<div class="ai-actions">
|
|
<button class="btn btn-primary btn-sm">3개 Todo 생성</button>
|
|
<button class="btn btn-text btn-sm">수정</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 용어 사전 탭 (NEW) -->
|
|
<div class="tab-content" data-content="terms" style="display: none;">
|
|
<h3 style="margin-bottom: var(--spacing-4); font-size: var(--font-size-h4);">용어 사전</h3>
|
|
|
|
<!-- 검색 입력 -->
|
|
<div class="term-search-box">
|
|
<input
|
|
type="text"
|
|
class="term-search-input"
|
|
id="termSearchInput"
|
|
placeholder="용어를 검색하세요 (예: API, Mobile First)"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 용어 목록 -->
|
|
<div class="term-list" id="termList">
|
|
<!-- JavaScript로 동적 생성 -->
|
|
</div>
|
|
|
|
<!-- 검색 결과 없음 -->
|
|
<div class="no-results" id="noResults" style="display: none;">
|
|
<div style="font-size: 48px; opacity: 0.3; margin-bottom: var(--spacing-3);">🔍</div>
|
|
<div>검색 결과가 없습니다</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 관련 자료 탭 -->
|
|
<div class="tab-content" data-content="related" style="display: none;">
|
|
<h3 style="margin-bottom: var(--spacing-4); font-size: var(--font-size-h4);">관련 자료</h3>
|
|
|
|
<div style="margin-bottom: var(--spacing-6);">
|
|
<h4 style="font-size: var(--font-size-body); font-weight: var(--font-weight-semibold); color: var(--color-gray-700); margin-bottom: var(--spacing-3);">
|
|
📄 관련 회의록 (3건)
|
|
</h4>
|
|
|
|
<div class="ai-suggestion" style="cursor: pointer;">
|
|
<div class="ai-suggestion-header" style="color: var(--color-gray-900);">
|
|
2024년 4분기 제품 기획 회의
|
|
</div>
|
|
<div class="ai-suggestion-text">
|
|
<div style="display: flex; gap: var(--spacing-2); margin-bottom: var(--spacing-2); font-size: var(--font-size-caption);">
|
|
<span>2024-10-15</span> | <span style="color: var(--color-success-main);">관련도 92%</span>
|
|
</div>
|
|
<div>신규 회의록 서비스 MVP 개발 일정 논의. AI 기능 우선순위와 예산 확정.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="ai-suggestion" style="cursor: pointer;">
|
|
<div class="ai-suggestion-header" style="color: var(--color-gray-900);">
|
|
API 설계 리뷰 회의
|
|
</div>
|
|
<div class="ai-suggestion-text">
|
|
<div style="display: flex; gap: var(--spacing-2); margin-bottom: var(--spacing-2); font-size: var(--font-size-caption);">
|
|
<span>2024-09-28</span> | <span style="color: var(--color-warning-main);">관련도 78%</span>
|
|
</div>
|
|
<div>RESTful API 설계 원칙과 보안 정책 확정. 담당자별 역할 분담.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="common.js"></script>
|
|
<script>
|
|
// 용어 사전 데이터
|
|
const TERMINOLOGY = [
|
|
{
|
|
id: 'mobile-first',
|
|
name: 'Mobile First',
|
|
category: '설계 방법론',
|
|
definition: '모바일 환경을 우선적으로 고려하여 디자인하고, 이후 더 큰 화면으로 확장하는 설계 방법론입니다.',
|
|
context: '회의에서 언급됨 (14:23)',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'ai',
|
|
name: 'AI',
|
|
category: '기술',
|
|
definition: 'Artificial Intelligence의 약자로, 인공지능을 의미합니다. 이 프로젝트에서는 회의록 자동 작성에 활용됩니다.',
|
|
context: '회의에서 5회 언급됨',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'api',
|
|
name: 'API',
|
|
category: '기술',
|
|
definition: 'Application Programming Interface의 약자로, 소프트웨어 간 상호작용을 위한 인터페이스입니다.',
|
|
context: '회의에서 3회 언급됨',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'api-gateway',
|
|
name: 'API Gateway',
|
|
category: '아키텍처',
|
|
definition: '클라이언트와 백엔드 마이크로서비스 사이의 단일 진입점 역할을 하는 서버. 요청 라우팅, 인증, 속도 제한, 로드 밸런싱 등을 처리합니다.',
|
|
context: 'API 설계 리뷰 회의 (2024-09-28)에서 AWS API Gateway 채택 결정',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'microservice',
|
|
name: '마이크로서비스',
|
|
category: '아키텍처',
|
|
definition: '애플리케이션을 작고 독립적인 서비스들로 분리하여 개발하고 배포하는 아키텍처 패턴입니다.',
|
|
context: '회의에서 언급됨',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'mvp',
|
|
name: 'MVP',
|
|
category: '방법론',
|
|
definition: 'Minimum Viable Product의 약자. 최소한의 기능만 갖춘 제품으로, 시장 반응을 빠르게 확인하기 위해 개발합니다.',
|
|
context: '개발 일정 논의에서 언급',
|
|
usedInMeeting: true
|
|
},
|
|
{
|
|
id: 'restful',
|
|
name: 'RESTful API',
|
|
category: '기술',
|
|
definition: 'REST(Representational State Transfer) 아키텍처 스타일을 따르는 웹 서비스 API 설계 방식입니다.',
|
|
context: 'API 설계 리뷰 회의 참조',
|
|
usedInMeeting: false
|
|
},
|
|
{
|
|
id: 'jwt',
|
|
name: 'JWT',
|
|
category: '보안',
|
|
definition: 'JSON Web Token의 약자. 사용자 인증 정보를 안전하게 전송하기 위한 토큰 기반 인증 방식입니다.',
|
|
context: 'API Gateway 보안 정책에서 채택',
|
|
usedInMeeting: false
|
|
}
|
|
];
|
|
|
|
// 용어 렌더링
|
|
function renderTerms(terms) {
|
|
const termList = document.getElementById('termList');
|
|
const noResults = document.getElementById('noResults');
|
|
|
|
if (terms.length === 0) {
|
|
termList.innerHTML = '';
|
|
noResults.style.display = 'block';
|
|
return;
|
|
}
|
|
|
|
noResults.style.display = 'none';
|
|
termList.innerHTML = terms.map(term => `
|
|
<div class="term-item ${term.usedInMeeting ? 'highlight' : ''}" onclick="showTermDetail('${term.id}')">
|
|
<div class="term-name">
|
|
${term.name}
|
|
<span class="term-badge">${term.category}</span>
|
|
${term.usedInMeeting ? '<span style="font-size: 16px;">💬</span>' : ''}
|
|
</div>
|
|
<div class="term-definition">${term.definition}</div>
|
|
<div class="term-context">${term.context}</div>
|
|
</div>
|
|
`).join('');
|
|
}
|
|
|
|
// 용어 검색
|
|
function searchTerms(query) {
|
|
if (!query || query.trim() === '') {
|
|
renderTerms(TERMINOLOGY);
|
|
return;
|
|
}
|
|
|
|
const lowerQuery = query.toLowerCase();
|
|
const filtered = TERMINOLOGY.filter(term =>
|
|
term.name.toLowerCase().includes(lowerQuery) ||
|
|
term.definition.toLowerCase().includes(lowerQuery) ||
|
|
term.category.toLowerCase().includes(lowerQuery)
|
|
);
|
|
|
|
renderTerms(filtered);
|
|
}
|
|
|
|
// 용어 상세 보기
|
|
function showTermDetail(termId) {
|
|
const term = TERMINOLOGY.find(t => t.id === termId);
|
|
if (!term) return;
|
|
|
|
window.MeetingApp.Toast.show(
|
|
`📚 ${term.name}\n\n${term.definition}\n\n${term.context}`,
|
|
'info',
|
|
5000
|
|
);
|
|
}
|
|
|
|
// 검색 입력 이벤트
|
|
const searchInput = document.getElementById('termSearchInput');
|
|
if (searchInput) {
|
|
searchInput.addEventListener('input', (e) => {
|
|
searchTerms(e.target.value);
|
|
});
|
|
}
|
|
|
|
// 탭 전환
|
|
const tabs = document.querySelectorAll('.side-tab');
|
|
const tabContents = document.querySelectorAll('.tab-content');
|
|
|
|
tabs.forEach(tab => {
|
|
tab.addEventListener('click', () => {
|
|
const targetTab = tab.getAttribute('data-tab');
|
|
|
|
tabs.forEach(t => t.classList.remove('active'));
|
|
tab.classList.add('active');
|
|
|
|
tabContents.forEach(content => {
|
|
if (content.getAttribute('data-content') === targetTab) {
|
|
content.style.display = 'block';
|
|
|
|
// 용어 사전 탭 열 때 초기 렌더링
|
|
if (targetTab === 'terms' && !content.dataset.rendered) {
|
|
renderTerms(TERMINOLOGY);
|
|
content.dataset.rendered = 'true';
|
|
}
|
|
} else {
|
|
content.style.display = 'none';
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// 사이드 패널 토글 (모바일)
|
|
const toggleBtn = document.getElementById('toggleSidePanel');
|
|
const sidePanel = document.getElementById('sidePanel');
|
|
|
|
if (toggleBtn) {
|
|
toggleBtn.addEventListener('click', () => {
|
|
sidePanel.classList.toggle('open');
|
|
});
|
|
}
|
|
|
|
// 녹음 시간 업데이트
|
|
let seconds = 0;
|
|
const recordingTimeEl = document.getElementById('recordingTime');
|
|
|
|
setInterval(() => {
|
|
seconds++;
|
|
const mins = Math.floor(seconds / 60);
|
|
const secs = seconds % 60;
|
|
recordingTimeEl.textContent = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
|
}, 1000);
|
|
|
|
// 자동 저장 시뮬레이션
|
|
const editorTextarea = document.getElementById('meetingContent');
|
|
let saveTimeout;
|
|
|
|
editorTextarea.addEventListener('input', () => {
|
|
clearTimeout(saveTimeout);
|
|
saveTimeout = setTimeout(() => {
|
|
console.log('자동 저장됨');
|
|
}, 2000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|