프로토타입 및 UI/UX 설계서 업데이트

- 02-대시보드: 회의 목록 표시 개선
- 05-회의진행: 실시간 협업 기능 반영
- 10-회의록상세조회: 최종 확정 후 조회 화면 업데이트
- 11-회의록수정: 안건 기반 충돌 방지 메커니즘 추가
- design/uiux/uiux.md: 유저스토리 v2.3.0 기준 UI/UX 설계서 업데이트

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yabo0812 2025-10-27 14:50:10 +09:00
parent 6563bd16e6
commit bb91c7d127
5 changed files with 91 additions and 352 deletions

View File

@ -238,7 +238,7 @@
/* Todo 카드 스타일은 common.css에서 공통 관리 */ /* Todo 카드 스타일은 common.css에서 공통 관리 */
/* 통계 영역 - 정보 표시용 (클릭 불가) */ /* 통계 영역 - 정보 표시용 (클릭 불가) - UFR-USER-020: 2개 항목 표시 */
.stats-overview { .stats-overview {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@ -513,15 +513,12 @@
<div class="sidebar-logo-text">회의록 서비스</div> <div class="sidebar-logo-text">회의록 서비스</div>
</a> </a>
<!-- MVP 스코프 축소: Todo 관리 메뉴 제거 -->
<nav class="sidebar-nav"> <nav class="sidebar-nav">
<a href="12-회의록목록조회.html" class="sidebar-nav-item"> <a href="12-회의록목록조회.html" class="sidebar-nav-item">
<span class="sidebar-nav-icon"><img src="img/edit.png" width="32"></span> <span class="sidebar-nav-icon"><img src="img/edit.png" width="32"></span>
<span>회의록</span> <span>회의록</span>
</a> </a>
<a href="09-Todo관리.html" class="sidebar-nav-item">
<span class="sidebar-nav-icon"><img src="img/list.png" width="32"></span>
<span>Todo 관리</span>
</a>
</nav> </nav>
<!-- 사용자 정보 영역 (Desktop) --> <!-- 사용자 정보 영역 (Desktop) -->
@ -559,7 +556,7 @@
<!-- 메인 콘텐츠 --> <!-- 메인 콘텐츠 -->
<main class="main-content"> <main class="main-content">
<!-- 통계 개요 --> <!-- 통계 개요 (UFR-USER-020) -->
<div class="stats-overview"> <div class="stats-overview">
<div class="stat-box stat-meeting"> <div class="stat-box stat-meeting">
<div class="stat-icon">📅</div> <div class="stat-icon">📅</div>
@ -567,9 +564,9 @@
<div class="stat-text">예정된 회의</div> <div class="stat-text">예정된 회의</div>
</div> </div>
<div class="stat-box stat-todo"> <div class="stat-box stat-todo">
<div class="stat-icon"></div> <div class="stat-icon">📝</div>
<div class="stat-number" id="stat-todos">0</div> <div class="stat-number" id="stat-drafts">0</div>
<div class="stat-text">나의 Todo</div> <div class="stat-text">작성중 회의록</div>
</div> </div>
</div> </div>
@ -583,16 +580,7 @@
</div> </div>
</section> </section>
<!-- 나의 Todo --> <!-- MVP 스코프 축소: "나의 Todo" 섹션 제거 -->
<section>
<div class="section-header">
<h2 class="section-title">나의 Todo</h2>
<a href="09-Todo관리.html" class="section-link">전체 보기 →</a>
</div>
<div class="todo-list" id="my-todos">
<!-- 동적 생성 -->
</div>
</section>
<!-- 나의 회의록 --> <!-- 나의 회의록 -->
<section> <section>
@ -607,7 +595,7 @@
</main> </main>
<!-- 하단 네비게이션 (모바일) --> <!-- 하단 네비게이션 (모바일) - MVP 스코프 축소: Todo 관리 메뉴 제거 -->
<nav class="bottom-nav"> <nav class="bottom-nav">
<a href="02-대시보드.html" class="nav-item active"> <a href="02-대시보드.html" class="nav-item active">
<img src="img/home.png" alt="홈" style="width: 45px;"> <img src="img/home.png" alt="홈" style="width: 45px;">
@ -615,9 +603,6 @@
<a href="12-회의록목록조회.html" class="nav-item"> <a href="12-회의록목록조회.html" class="nav-item">
<img src="img/edit.png" alt="회의록" style="width: 45px;"> <img src="img/edit.png" alt="회의록" style="width: 45px;">
</a> </a>
<a href="09-Todo관리.html" class="nav-item">
<img src="img/list.png" alt="Todo" style="width: 45px;">
</a>
</nav> </nav>
<!-- FAB 오버레이 --> <!-- FAB 오버레이 -->
@ -745,104 +730,9 @@
} }
/** /**
* 내 Todo 렌더링 (09-Todo관리.html과 동일한 정렬 기준) * MVP 스코프 축소: renderMyTodos() 함수 제거됨
* 대시보드에서 Todo 위젯이 제거되어 더 이상 사용되지 않음
*/ */
function renderMyTodos() {
const container = $('#my-todos');
const myTodos = SAMPLE_TODOS
.filter(todo => todo.assignee.id === currentUser.id)
.sort((a, b) => {
// 09-Todo관리.html과 동일한 정렬: 완료되지 않은 것 우선, 마감일 순
if (a.status === 'completed' && b.status !== 'completed') return 1;
if (a.status !== 'completed' && b.status === 'completed') return -1;
return new Date(a.dueDate) - new Date(b.dueDate);
})
.slice(0, 3); // 상위 3개만 표시
if (myTodos.length === 0) {
container.innerHTML = '<div class="empty-state"><div class="empty-icon"></div><p>할당된 Todo가 없습니다</p></div>';
return;
}
container.innerHTML = myTodos.map(todo => {
const dday = calculateDday(todo.dueDate);
const isCompleted = todo.status === 'completed';
const isOverdue = dday < 0 && !isCompleted;
// D-day 배지
let ddayBadge = '';
let ddayClass = '';
if (isCompleted) {
ddayBadge = '완료';
ddayClass = 'badge-complete';
} else if (isOverdue) {
ddayBadge = `D+${Math.abs(dday)} (지연)`;
ddayClass = 'badge-overdue';
} else if (dday === 0) {
ddayBadge = 'D-DAY';
ddayClass = 'badge-warning';
} else if (dday <= 3) {
ddayBadge = `D-${dday}`;
ddayClass = 'badge-warning';
} else if (dday <= 7) {
ddayBadge = `D-${dday}`;
ddayClass = 'badge-primary';
} else {
ddayBadge = `D-${dday}`;
ddayClass = 'badge-secondary';
}
// 우선순위 배지
const priorityText = todo.priority === 'high' ? '높음' : todo.priority === 'medium' ? '보통' : '낮음';
const priorityClass = `badge-${todo.priority}`;
return `
<div class="todo-card ${isCompleted ? 'completed' : ''}" data-todo-id="${todo.id}" data-meeting-id="${todo.meetingId}">
<div class="todo-top">
<div class="todo-checkbox-wrapper">
<input type="checkbox" class="todo-checkbox" id="check-${todo.id}"
${isCompleted ? 'checked' : ''}
onchange="toggleTodoComplete('${todo.id}', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge ${ddayClass}">${ddayBadge}</span>
<span class="badge ${priorityClass}">${priorityText}</span>
</div>
<div class="todo-title">${todo.title}</div>
<div class="todo-meta-row">
<a class="todo-meeting-link" onclick="navigateTo('10-회의록상세조회.html'); event.stopPropagation();">
🔗 ${todo.meetingTitle}
</a>
<span>${formatDate(todo.dueDate)}</span>
</div>
</div>
${!isCompleted ? `
<div class="todo-actions">
<button class="icon-btn" onclick="editTodo('${todo.id}')" title="편집">✏️</button>
</div>
` : ''}
</div>
</div>
`;
}).join('');
// Todo 카드 클릭 시 해당 회의록 상세로 이동 (체크박스와 버튼 제외)
$$('.todo-card').forEach(card => {
card.addEventListener('click', (e) => {
// 체크박스나 버튼 클릭은 무시
if (e.target.classList.contains('todo-checkbox') ||
e.target.classList.contains('icon-btn') ||
e.target.closest('.icon-btn')) {
return;
}
const meetingId = card.dataset.meetingId;
const todoId = card.dataset.todoId;
navigateTo(`10-회의록상세조회.html?meetingId=${meetingId}&todoId=${todoId}`);
});
});
}
/** /**
* 나의 회의록 렌더링 (참여자 또는 생성자로 등록된 회의록, 최신순 정렬) * 나의 회의록 렌더링 (참여자 또는 생성자로 등록된 회의록, 최신순 정렬)
@ -887,31 +777,33 @@
} }
/** /**
* 통계 업데이트 * 통계 업데이트 (UFR-USER-020)
*/ */
function updateStats() { function updateStats() {
// 예정된 회의 개수 (예정 + 진행중) // 예정된 회의 개수 (예정 + 진행중)
const scheduled = SAMPLE_MEETINGS.filter(m => m.status === 'scheduled' || m.status === 'ongoing').length; const scheduled = SAMPLE_MEETINGS.filter(m => m.status === 'scheduled' || m.status === 'ongoing').length;
// 나의 Todo 개수 (전체) // 작성중 회의록 개수 (내가 참석한 회의 중 '작성중' 상태)
const myTodos = SAMPLE_TODOS.filter(t => t.assignee.id === currentUser.id).length; const drafts = SAMPLE_MINUTES.filter(m =>
m.status === 'draft' &&
m.participants.some(p => p.id === currentUser.id)
).length;
$('#stat-scheduled').textContent = scheduled; $('#stat-scheduled').textContent = scheduled;
$('#stat-todos').textContent = myTodos; $('#stat-drafts').textContent = drafts;
} }
/** /**
* 초기화 * 초기화 - MVP 스코프 축소: renderMyTodos() 제거
*/ */
function init() { function init() {
renderSidebarUser(); renderSidebarUser();
renderHeader(); renderHeader();
updateStats(); updateStats();
renderRecentMeetings(); renderRecentMeetings();
renderMyTodos();
renderMyMinutes(); renderMyMinutes();
console.log('대시보드 초기화 완료'); console.log('대시보드 초기화 완료 (MVP 스코프 축소)');
} }
/** /**
@ -1002,48 +894,11 @@
} }
/** /**
* Todo 완료 토글 * MVP 스코프 축소: Todo 관련 함수 제거됨
* @param {string} todoId - Todo ID * - toggleTodoComplete()
* @param {boolean} isChecked - 체크박스 상태 * - editTodo()
* 대시보드에서 Todo 위젯이 제거되어 더 이상 사용되지 않음
*/ */
function toggleTodoComplete(todoId, isChecked) {
if (isChecked) {
// 완료 처리
if (confirm('완료 처리하시겠습니까?')) {
const todo = SAMPLE_TODOS.find(t => t.id === todoId);
if (todo) {
todo.status = 'completed';
showToast('Todo가 완료되었습니다', 'success');
updateStats();
renderMyTodos();
}
} else {
event.target.checked = false;
}
} else {
// 미완료로 되돌리기
if (confirm('미완료로 변경하시겠습니까?')) {
const todo = SAMPLE_TODOS.find(t => t.id === todoId);
if (todo) {
todo.status = 'incomplete';
showToast('미완료로 변경되었습니다', 'info');
updateStats();
renderMyTodos();
}
} else {
event.target.checked = true;
}
}
}
/**
* Todo 편집 (간이 버전 - 09-Todo관리.html로 이동)
* @param {string} todoId - Todo ID
*/
function editTodo(todoId) {
// Todo 관리 화면으로 이동하여 편집
navigateTo(`09-Todo관리.html?todoId=${todoId}`);
}
init(); init();
</script> </script>

View File

@ -351,7 +351,7 @@
white-space: nowrap; white-space: nowrap;
} }
/* AI 제안 탭 */ /* AI 기반 메모 탭 - MVP 스코프 축소 v1.5.1 */
.memo-input-section { .memo-input-section {
background: var(--gray-50); background: var(--gray-50);
border-radius: var(--radius-md); border-radius: var(--radius-md);
@ -398,7 +398,7 @@
margin-bottom: var(--space-sm); margin-bottom: var(--space-sm);
} }
/* AI 제안 카드 */ /* AI 주요 내용 카드 */
.ai-suggestion-card { .ai-suggestion-card {
background: #FAFAFA; background: #FAFAFA;
border: 1px dashed #D0D0D0; border: 1px dashed #D0D0D0;
@ -668,7 +668,7 @@
참석자 참석자
</button> </button>
<button class="tab-button" onclick="switchTab('ai-suggestions')"> <button class="tab-button" onclick="switchTab('ai-suggestions')">
AI 제안 AI 기반 메모
</button> </button>
<button class="tab-button" onclick="switchTab('terms')"> <button class="tab-button" onclick="switchTab('terms')">
용어사전 용어사전
@ -732,7 +732,7 @@
</div> </div>
</div> </div>
<!-- AI 제안 탭 --> <!-- AI 기반 메모 탭 (MVP 스코프 축소 v1.5.1) -->
<div class="tab-content" id="tab-ai-suggestions"> <div class="tab-content" id="tab-ai-suggestions">
<div class="memo-input-section"> <div class="memo-input-section">
<label class="memo-input-label">📝 회의 메모</label> <label class="memo-input-label">📝 회의 메모</label>
@ -1053,7 +1053,7 @@
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
} }
// AI 제안을 메모에 추가 // AI가 감지한 주요 내용을 메모에 추가 (MVP 스코프 축소 v1.5.1)
function addToMemo(suggestionText, cardElement) { function addToMemo(suggestionText, cardElement) {
const memoTextarea = document.getElementById('meetingMemo'); const memoTextarea = document.getElementById('meetingMemo');
const currentMemo = memoTextarea.value; const currentMemo = memoTextarea.value;
@ -1062,7 +1062,7 @@
const recordingTime = document.getElementById('recordingTime').textContent; const recordingTime = document.getElementById('recordingTime').textContent;
const timePrefix = '[' + recordingTime.substring(0, 5) + '] '; // HH:MM만 추출 const timePrefix = '[' + recordingTime.substring(0, 5) + '] '; // HH:MM만 추출
// 시간 정보 + 제안 내용 // 시간 정보 + 주요 내용
const memoWithTime = timePrefix + suggestionText; const memoWithTime = timePrefix + suggestionText;
if (currentMemo) { if (currentMemo) {
@ -1071,7 +1071,7 @@
memoTextarea.value = memoWithTime; memoTextarea.value = memoWithTime;
} }
// AI 제안 카드 삭제 // AI 주요 내용 카드 삭제 (선택 후 제거)
if (cardElement) { if (cardElement) {
cardElement.remove(); cardElement.remove();
} }

View File

@ -1042,148 +1042,62 @@
</div> </div>
</div> </div>
<!-- Todo 진행상황 --> <!-- Todo 단순 조회 (MVP 스코프 축소 v1.5.1) -->
<div class="card mb-lg"> <div class="card mb-lg">
<h3 class="card-title">📋 Todo 진행상황</h3> <h3 class="card-title">📋 Todo 진행상황</h3>
<p style="font-size: var(--font-small); color: var(--gray-600); margin-bottom: var(--space-md);">
Todo 항목은 조회만 가능합니다. 제목, 담당자, 마감일 정보만 표시됩니다.
</p>
<!-- 전체 진행률 --> <!-- Todo 단순 조회 리스트 (제목 + 담당자 + 마감일만 표시) -->
<div style="margin-bottom: var(--space-lg);"> <div style="display: flex; flex-direction: column; gap: var(--space-sm);">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-xs);"> <div style="padding: var(--space-md); background: var(--gray-50); border-radius: var(--radius-md); border: 1px solid var(--gray-200);">
<span style="font-size: var(--font-body); font-weight: var(--font-weight-medium); color: var(--gray-900);">전체 진행률</span> <div style="font-weight: var(--font-weight-medium); color: var(--gray-900); margin-bottom: var(--space-xs);">
<span style="font-size: var(--font-body); font-weight: var(--font-weight-bold); color: var(--primary);">40%</span> 데이터베이스 스키마 설계
</div> </div>
<div style="width: 100%; height: 8px; background: var(--gray-200); border: 1px solid var(--gray-300); border-radius: 4px; overflow: hidden;"> <div style="font-size: var(--font-small); color: var(--gray-600);">
<div style="width: 40%; height: 100%; background: var(--primary); transition: width 0.3s ease;"></div> <span>👤 이준호</span>
</div> <span style="margin-left: var(--space-md);">📅 2025-10-20</span>
<div style="font-size: var(--font-caption); color: var(--gray-600); margin-top: var(--space-xs);">
2 / 5 완료
</div> </div>
</div> </div>
<div class="todo-filters"> <div style="padding: var(--space-md); background: var(--gray-50); border-radius: var(--radius-md); border: 1px solid var(--gray-200);">
<button class="filter-btn active" data-filter="all" onclick="filterTodos('all')"> <div style="font-weight: var(--font-weight-medium); color: var(--gray-900); margin-bottom: var(--space-xs);">
전체 (<span id="filterAllCount">5</span>) API 명세서 작성
</button>
<button class="filter-btn" data-filter="overdue" onclick="filterTodos('overdue')">
지연 (<span id="filterOverdueCount">1</span>)
</button>
<button class="filter-btn" data-filter="urgent" onclick="filterTodos('urgent')">
마감 임박 (<span id="filterUrgentCount">2</span>)
</button>
<button class="filter-btn" data-filter="completed" onclick="filterTodos('completed')">
완료 (<span id="filterCompletedCount">2</span>)
</button>
</div>
<!-- Todo 카드 리스트 -->
<div class="todo-card">
<div class="todo-top">
<div class="todo-checkbox-wrapper">
<input type="checkbox" class="todo-checkbox" id="check-todo-002"
onchange="toggleTodoComplete('todo-002', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge badge-overdue">D+1 (지연)</span>
<span class="badge badge-high">높음</span>
</div>
<div class="todo-title">데이터베이스 스키마 설계</div>
<div class="todo-meta-row">
<span>담당자: 이준호</span>
<span>2025-10-20 마감</span>
</div>
</div>
<div class="todo-actions">
<button class="icon-btn" onclick="editTodo('todo-002')" title="편집">✏️</button>
</div> </div>
<div style="font-size: var(--font-small); color: var(--gray-600);">
<span>👤 이준호</span>
<span style="margin-left: var(--space-md);">📅 2025-10-23</span>
</div> </div>
</div> </div>
<div class="todo-card"> <div style="padding: var(--space-md); background: var(--gray-50); border-radius: var(--radius-md); border: 1px solid var(--gray-200);">
<div class="todo-top"> <div style="font-weight: var(--font-weight-medium); color: var(--gray-900); margin-bottom: var(--space-xs);">
<div class="todo-checkbox-wrapper"> 예산 편성안 검토
<input type="checkbox" class="todo-checkbox" id="check-todo-001"
onchange="toggleTodoComplete('todo-001', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge badge-warning">D-2</span>
<span class="badge badge-high">높음</span>
</div>
<div class="todo-title">API 명세서 작성</div>
<div class="todo-meta-row">
<span>담당자: 이준호</span>
<span>2025-10-23 마감</span>
</div>
</div>
<div class="todo-actions">
<button class="icon-btn" onclick="editTodo('todo-001')" title="편집">✏️</button>
</div> </div>
<div style="font-size: var(--font-small); color: var(--gray-600);">
<span>👤 김민준</span>
<span style="margin-left: var(--space-md);">📅 2025-10-22</span>
</div> </div>
</div> </div>
<div class="todo-card"> <div style="padding: var(--space-md); background: var(--gray-50); border-radius: var(--radius-md); border: 1px solid var(--gray-200);">
<div class="todo-top"> <div style="font-weight: var(--font-weight-medium); color: var(--gray-900); margin-bottom: var(--space-xs);">
<div class="todo-checkbox-wrapper"> UI 프로토타입 디자인
<input type="checkbox" class="todo-checkbox" id="check-todo-005"
onchange="toggleTodoComplete('todo-005', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge badge-warning">D-1</span>
<span class="badge badge-high">높음</span>
</div>
<div class="todo-title">예산 편성안 검토</div>
<div class="todo-meta-row">
<span>담당자: 김민준</span>
<span>2025-10-22 마감</span>
</div>
</div>
<div class="todo-actions">
<button class="icon-btn" onclick="editTodo('todo-005')" title="편집">✏️</button>
</div> </div>
<div style="font-size: var(--font-small); color: var(--gray-600);">
<span>👤 최유진</span>
<span style="margin-left: var(--space-md);">📅 2025-10-28</span>
</div> </div>
</div> </div>
<div class="todo-card"> <div style="padding: var(--space-md); background: var(--gray-50); border-radius: var(--radius-md); border: 1px solid var(--gray-200);">
<div class="todo-top"> <div style="font-weight: var(--font-weight-medium); color: var(--gray-900); margin-bottom: var(--space-xs);">
<div class="todo-checkbox-wrapper"> 사용자 피드백 분석
<input type="checkbox" class="todo-checkbox" id="check-todo-003"
onchange="toggleTodoComplete('todo-003', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge badge-primary">D-7</span>
<span class="badge badge-medium">보통</span>
</div>
<div class="todo-title">UI 프로토타입 디자인</div>
<div class="todo-meta-row">
<span>담당자: 최유진</span>
<span>2025-10-28 마감</span>
</div>
</div>
<div class="todo-actions">
<button class="icon-btn" onclick="editTodo('todo-003')" title="편집">✏️</button>
</div>
</div>
</div>
<div class="todo-card completed">
<div class="todo-top">
<div class="todo-checkbox-wrapper">
<input type="checkbox" class="todo-checkbox" id="check-todo-004" checked
onchange="toggleTodoComplete('todo-004', this.checked)">
</div>
<div class="todo-content-wrapper">
<div class="todo-badges">
<span class="badge badge-complete">완료</span>
<span class="badge badge-medium">보통</span>
</div>
<div class="todo-title">사용자 피드백 분석</div>
<div class="todo-meta-row">
<span>담당자: 김민준</span>
<span>2025-10-19 마감</span>
</div> </div>
<div style="font-size: var(--font-small); color: var(--gray-600);">
<span>👤 김민준</span>
<span style="margin-left: var(--space-md);">📅 2025-10-19</span>
</div> </div>
</div> </div>
</div> </div>
@ -1460,24 +1374,17 @@
} }
/** /**
* Todo 필터링 (09-Todo관리와 동일) * MVP 스코프 축소 v1.5.1: Todo 필터링/편집 함수 제거됨
* Todo는 단순 조회만 가능하므로 더 이상 사용되지 않음
*/ */
/*
function filterTodos(filter) { function filterTodos(filter) {
currentFilter = filter; // 제거됨: Todo 필터링 기능
// 탭 활성화
document.querySelectorAll('.filter-btn').forEach(btn => {
btn.classList.remove('active');
});
document.querySelector(`.filter-btn[data-filter="${filter}"]`).classList.add('active');
renderTodoList();
} }
/**
* Todo 편집 모달 열기
* @param {string} todoId - 편집할 Todo ID
*/ */
/*
function editTodo(todoId) { function editTodo(todoId) {
const todo = meetingTodos.find(t => t.id === todoId); const todo = meetingTodos.find(t => t.id === todoId);
if (!todo) return; if (!todo) return;
@ -1610,39 +1517,13 @@
* @param {string} todoId - Todo ID * @param {string} todoId - Todo ID
* @param {boolean} isChecked - 체크박스 상태 * @param {boolean} isChecked - 체크박스 상태
*/ */
/*
function toggleTodoComplete(todoId, isChecked) { function toggleTodoComplete(todoId, isChecked) {
if (isChecked) { // 제거됨: Todo 완료 토글 기능
// 완료 처리
if (confirm('완료 처리하시겠습니까?')) {
const todo = meetingTodos.find(t => t.id === todoId);
if (todo) {
todo.status = 'completed';
showToast('Todo가 완료되었습니다', 'success');
updateTodoProgress();
renderTodoList();
} }
} else {
event.target.checked = false;
}
} else {
// 미완료로 되돌리기
if (confirm('미완료로 변경하시겠습니까?')) {
const todo = meetingTodos.find(t => t.id === todoId);
if (todo) {
todo.status = 'incomplete';
showToast('미완료로 변경되었습니다', 'info');
updateTodoProgress();
renderTodoList();
}
} else {
event.target.checked = true;
}
}
}
/**
* Todo 진행률 업데이트
*/ */
/*
function updateTodoProgress() { function updateTodoProgress() {
const total = meetingTodos.length; const total = meetingTodos.length;
const completed = meetingTodos.filter(t => t.status === 'completed').length; const completed = meetingTodos.filter(t => t.status === 'completed').length;

View File

@ -6,6 +6,15 @@
<title>회의록 수정 - 회의록 서비스</title> <title>회의록 수정 - 회의록 서비스</title>
<link rel="stylesheet" href="common.css"> <link rel="stylesheet" href="common.css">
<style> <style>
/*
MVP 스코프 축소 v1.5.1 적용됨:
- ❌ 실시간 협업 표시 ("편집 중" 표시 제거)
- ❌ Todo 편집 기능 제거 (단순 조회만 가능)
- ❌ 검증률 표시 및 최종 확정 버튼 제거
- ✅ 안건별 검증 완료 체크박스 사용
- ✅ Last Write Wins (LWW) 정책 적용
*/
/* 페이지별 커스텀 스타일만 유지 */ /* 페이지별 커스텀 스타일만 유지 */
/* 공통 스타일(헤더, 메인콘텐츠, 안건, AI요약, 관련회의록, 액션바)은 common.css 사용 */ /* 공통 스타일(헤더, 메인콘텐츠, 안건, AI요약, 관련회의록, 액션바)은 common.css 사용 */

View File

@ -305,22 +305,17 @@ graph TD
- "안녕하세요, {사용자명}님!" (H2) - "안녕하세요, {사용자명}님!" (H2)
- "오늘의 일정을 확인하세요" (부제) - "오늘의 일정을 확인하세요" (부제)
- **통계 카드 그리드** (3개, auto-fit) - **통계 카드 그리드** (2개) - **v1.5.0 변경**
- 예정된 회의 (📅) - 예정된 회의 (📅)
- 진행 중 Todo (✅) - 작성중 회의록 (📝)
- Todo 완료율 (📈)
- **최근 회의 그리드** (2-3컬럼) - **최근 회의 그리드** (2-3컬럼)
- 회의 카드들 (진행중 우선) - 회의 카드들 (진행중 우선)
- 참여하기/수정/보기 버튼 - 참여하기/수정/보기 버튼
- **할당된 Todo 리스트**
- 화이트 카드 배경
- 각 Todo 항목 구분선
- **내 회의록 리스트** - **내 회의록 리스트**
- 화이트 카드 배경 - 화이트 카드 배경
- 전체보기 → 11-회의록목록조회.html - 전체보기 → 12-회의록목록조회.html
- **하단 네비게이션**: 숨김 (데스크톱에서는 사이드바 사용) - **하단 네비게이션**: 숨김 (데스크톱에서는 사이드바 사용)
@ -2108,8 +2103,6 @@ graph TD
| 버전 | 날짜 | 작성자 | 변경 내용 | | 버전 | 날짜 | 작성자 | 변경 내용 |
|------|------|--------|----------| |------|------|--------|----------|
| 1.5.1 | 2025-10-27 | 강지수 | MVP 스코프 축소 v2.4.0 반영 (3개 화면 수정)<br>- **05-회의진행**: "AI 제안" 탭 → "AI 기반 메모" 탭 기능 변경<br> - 메모 입력창 + 저장 버튼 추가<br> - AI가 감지한 주요 내용 리스트 표시 (시간 + 내용)<br> - 각 참석자별 개별 저장, 다른 참석자 메모 볼 수 없음<br> - 메모는 회의 종료 전까지만 표시/편집 가능<br> - 에러 처리: AI 주요 내용 감지 실패, 메모 저장 실패 추가<br>- **10-회의록상세조회**: Todo 단순 조회 기능으로 변경<br> - Todo는 제목 + 담당자 + 마감일만 표시<br> - D-day 라벨, 우선순위 배지, 진행률 바, 상태별 필터 제거<br> - Todo 관리 화면 연동 링크 제거 (화면 자체가 제거됨)<br> - "수정" 버튼을 헤더로 이동<br>- **11-회의록수정**: 실시간 협업 기능 제거, 안건 기반 충돌 방지 강화<br> - "편집 중" 표시 제거 (실시간 협업 기능 제거)<br> - Todo 편집/추가/삭제 기능 전체 제거 (단순 조회만 가능)<br> - AI 한줄 요약 재생성 불가 (회의 종료 시 1회만 생성)<br> - 검증률 표시 및 최종 확정 버튼 제거<br> - 저장 로직 추가: 검증완료 안건 저장 스킵, 저장 결과 알림<br> - 안건별 검증 완료 체크박스로 충돌 방지 (Last Write Wins 적용)<br> - 에러 처리: 충돌 경고 모달 제거 (LWW로 인해) |
| 1.4.20 | 2025-10-25 | 이미준, 강지수 | 유저스토리 v2.3.0 반영<br>- 회의 종료 화면 정책 명확화 (확인 전용, 바로 최종 확정 옵션 상세화)<br>- UFR-MEET-050: 최종 확정 2가지 시나리오 설명 추가<br>- UFR-COLLAB-020: 안건 기반 충돌 해결 메커니즘 상세 추가<br>- 실시간 협업 충돌 방지 정책 강화 |
| 1.0 | 2025-10-21 | 이미준 | 최초 작성 - 11개 화면 설계 완료 | | 1.0 | 2025-10-21 | 이미준 | 최초 작성 - 11개 화면 설계 완료 |
| 1.1 | 2025-10-21 | 이미준 | AI 요약 및 참고자료 기능 추가<br>- 05-회의진행: AI 회의 내용 요약 자동 생성 및 참고자료 자동 연결 추가<br>- 10-회의록상세조회: 섹션별 AI 요약 표시 및 참고자료 영역 추가<br>- 11-회의록수정: AI 요약 수정 및 참고자료 편집 기능 추가<br>- 관련 유저스토리: UFR-AI-040 (관련 회의록 자동 연결) | | 1.1 | 2025-10-21 | 이미준 | AI 요약 및 참고자료 기능 추가<br>- 05-회의진행: AI 회의 내용 요약 자동 생성 및 참고자료 자동 연결 추가<br>- 10-회의록상세조회: 섹션별 AI 요약 표시 및 참고자료 영역 추가<br>- 11-회의록수정: AI 요약 수정 및 참고자료 편집 기능 추가<br>- 관련 유저스토리: UFR-AI-040 (관련 회의록 자동 연결) |
| 1.1.1 | 2025-10-21 | 이미준 | 회의록 상세 화면 구조 개선 (프로토타입 기반)<br>- 10-회의록상세조회: 탭 기반 네비게이션 추가 (회의록/대시보드)<br>- 대시보드 탭 추가: 핵심내용, 결정사항, Todo 진행상황, 참고자료 섹션<br>- 참고자료 관련도 점수 표시 (백분율 + 색상 코딩)<br>- 참고자료 카테고리 탭 (관련 회의록/프로젝트 문서/이슈 트래커/위키 페이지)<br>- 참조: design-gappa/uiux/prototype 파일 (11-회의록대시보드.html, 05-회의진행.html) | | 1.1.1 | 2025-10-21 | 이미준 | 회의록 상세 화면 구조 개선 (프로토타입 기반)<br>- 10-회의록상세조회: 탭 기반 네비게이션 추가 (회의록/대시보드)<br>- 대시보드 탭 추가: 핵심내용, 결정사항, Todo 진행상황, 참고자료 섹션<br>- 참고자료 관련도 점수 표시 (백분율 + 색상 코딩)<br>- 참고자료 카테고리 탭 (관련 회의록/프로젝트 문서/이슈 트래커/위키 페이지)<br>- 참조: design-gappa/uiux/prototype 파일 (11-회의록대시보드.html, 05-회의진행.html) |
@ -2143,7 +2136,8 @@ graph TD
|| 1.4.17 | 2025-10-24 | 강지수 | 07-회의종료 화면 STT 한계 반영 (유저스토리 v2.1.2)<br>- **STT 화자 식별 불가 반영**: STT는 화자를 식별할 수 없으므로 화자 관련 기능 제거<br> - 발언 통계 섹션 삭제<br> - 안건별 "발언자별 의견" 섹션 삭제<br>- **통계 영역 디자인 개선**: 정보성 디자인으로 명확화<br> - 배경색: var(--white) → var(--gray-50)<br> - 숫자 색상: var(--primary) → var(--gray-900)<br> - 라벨 색상: var(--gray-500) → var(--gray-600)<br> - 정보 표시 전용으로 시각적 구분 명확화<br>- **안건 섹션 구분 개선**:<br> - 안건 간 하단 보더 추가 (1px solid var(--gray-200))<br> - 섹션 제목에 primary 색상 세로 바 추가 (::before pseudo-element)<br> - 콘텐츠 영역 좌측 패딩 추가로 계층 구조 명확화<br>- **연관 문서 업데이트**:<br> - 유저스토리 UFR-MEET-040: "발언 횟수 (화자별)" 항목 제거<br> - UI/UX 설계서 07-회의종료: 발언 통계 및 발언자별 의견 항목 제거 | || 1.4.17 | 2025-10-24 | 강지수 | 07-회의종료 화면 STT 한계 반영 (유저스토리 v2.1.2)<br>- **STT 화자 식별 불가 반영**: STT는 화자를 식별할 수 없으므로 화자 관련 기능 제거<br> - 발언 통계 섹션 삭제<br> - 안건별 "발언자별 의견" 섹션 삭제<br>- **통계 영역 디자인 개선**: 정보성 디자인으로 명확화<br> - 배경색: var(--white) → var(--gray-50)<br> - 숫자 색상: var(--primary) → var(--gray-900)<br> - 라벨 색상: var(--gray-500) → var(--gray-600)<br> - 정보 표시 전용으로 시각적 구분 명확화<br>- **안건 섹션 구분 개선**:<br> - 안건 간 하단 보더 추가 (1px solid var(--gray-200))<br> - 섹션 제목에 primary 색상 세로 바 추가 (::before pseudo-element)<br> - 콘텐츠 영역 좌측 패딩 추가로 계층 구조 명확화<br>- **연관 문서 업데이트**:<br> - 유저스토리 UFR-MEET-040: "발언 횟수 (화자별)" 항목 제거<br> - UI/UX 설계서 07-회의종료: 발언 통계 및 발언자별 의견 항목 제거 |
| 1.4.18 | 2025-10-24 | 강지수 | 05-회의진행 실시간 주요 메모 추천 기능 명확화 (유저스토리 v2.1.1)<br>- **AI 제안 탭 기능 상세화**: 실시간 주요 메모 추천 기능 명시 추가<br> - UFR-MEET-030: 실시간 AI 주요 메모 추천<br> - 음성→텍스트 변환 후 AI가 실시간 분석<br> - **중요한 내용으로 판단된 경우에만** 주요 메모 항목 추천<br> - 추천 빈도는 중요 내용 발생에 따라 가변적 (3-5초 고정 간격 아님)<br> - 각 추천 항목에 "주요 메모에 추가" 버튼 제공<br> - 실시간 업데이트: 새로운 추천은 상단에 표시<br>- **프로토타입 확인**: 05-회의진행.html의 AI 제안 탭이 실시간 주요 메모 추천 기능을 포함하고 있음을 확인<br>- **참조**: design/uiux/요구사항설계검토-report-V1.2.md (실시간 주요 메모 추천 명시 부족 개선) | | 1.4.18 | 2025-10-24 | 강지수 | 05-회의진행 실시간 주요 메모 추천 기능 명확화 (유저스토리 v2.1.1)<br>- **AI 제안 탭 기능 상세화**: 실시간 주요 메모 추천 기능 명시 추가<br> - UFR-MEET-030: 실시간 AI 주요 메모 추천<br> - 음성→텍스트 변환 후 AI가 실시간 분석<br> - **중요한 내용으로 판단된 경우에만** 주요 메모 항목 추천<br> - 추천 빈도는 중요 내용 발생에 따라 가변적 (3-5초 고정 간격 아님)<br> - 각 추천 항목에 "주요 메모에 추가" 버튼 제공<br> - 실시간 업데이트: 새로운 추천은 상단에 표시<br>- **프로토타입 확인**: 05-회의진행.html의 AI 제안 탭이 실시간 주요 메모 추천 기능을 포함하고 있음을 확인<br>- **참조**: design/uiux/요구사항설계검토-report-V1.2.md (실시간 주요 메모 추천 명시 부족 개선) |
| 1.4.19 | 2025-10-24 | 강지수 | 05-회의진행 화면 설계서 프로토타입 기준 전면 수정<br>- **레이아웃 구조 변경**: "2열 구조" 표현 제거, "메인 콘텐츠 영역: 정보 패널 (탭 구조)"로 단순화<br> - 텍스트 편집 영역 관련 내용 모두 제거 (왼쪽 영역, 에디터 툴바, contentEditable 등)<br> - 현재 프로토타입은 헤더 + 탭 콘텐츠 구조만 보유<br>- **반응형 디자인 명확화**: Mobile/Desktop 모두 동일한 구조에 너비만 반응형<br> - "2열 구조를 1열로 전환", "바텀시트" 표현 제거<br> - Mobile: 전체 너비 사용, Desktop: 최대 너비 제한 없이 반응형<br>- **AI 제안 탭 기능 명확화**: 논의항목/결정사항 구분 제거<br> - "논의항목/결정사항 등의 구분 없이 중요 내용을 주요 메모로 제안" 명시<br> - AI는 단순히 중요한 내용을 주요 메모 항목으로 제안하는 역할만 수행<br>- **용어 사전 검색 기능 추가**: 검색 입력창 + 검색 버튼<br> - Enter 키 지원, 용어명과 정의 모두 검색<br> - 검색 동작 상세 설명: 일치하는 용어만 표시, 하이라이트 효과, 결과 없으면 전체 목록 표시<br>- **인터랙션 섹션 정리**: 텍스트 편집, 툴바 사용, 충돌 감지 등 편집 관련 내용 모두 제거<br> - 탭 전환, 회의 종료, 실시간 업데이트만 유지<br> - 실시간 업데이트 항목을 현재 화면에 맞게 수정 (AI 제안, 용어 사전, 관련 회의록)<br>- **데이터 요구사항 업데이트**: 사용자 편집 내용 제거, 참석자 초대 이메일 추가<br> - AI 제안을 "주요 메모 항목 제안"으로 명확히 표현<br>- **에러 처리 업데이트**: 편집 충돌 에러 제거, 용어 사전 로드 실패/참석자 초대 실패 추가<br>- **주요 기능 목록 정리**: 실시간 협업/수동 편집 제거, AI 주요 메모 제안/참석자 관리 추가<br>- **권한 항목 수정**: "회의록 편집: 모든 참석자" → "참석자 초대: 모든 참석자"<br>- **프로토타입 기준 반영**: 05-회의진행.html 실제 구현 상태 100% 반영 | | 1.4.19 | 2025-10-24 | 강지수 | 05-회의진행 화면 설계서 프로토타입 기준 전면 수정<br>- **레이아웃 구조 변경**: "2열 구조" 표현 제거, "메인 콘텐츠 영역: 정보 패널 (탭 구조)"로 단순화<br> - 텍스트 편집 영역 관련 내용 모두 제거 (왼쪽 영역, 에디터 툴바, contentEditable 등)<br> - 현재 프로토타입은 헤더 + 탭 콘텐츠 구조만 보유<br>- **반응형 디자인 명확화**: Mobile/Desktop 모두 동일한 구조에 너비만 반응형<br> - "2열 구조를 1열로 전환", "바텀시트" 표현 제거<br> - Mobile: 전체 너비 사용, Desktop: 최대 너비 제한 없이 반응형<br>- **AI 제안 탭 기능 명확화**: 논의항목/결정사항 구분 제거<br> - "논의항목/결정사항 등의 구분 없이 중요 내용을 주요 메모로 제안" 명시<br> - AI는 단순히 중요한 내용을 주요 메모 항목으로 제안하는 역할만 수행<br>- **용어 사전 검색 기능 추가**: 검색 입력창 + 검색 버튼<br> - Enter 키 지원, 용어명과 정의 모두 검색<br> - 검색 동작 상세 설명: 일치하는 용어만 표시, 하이라이트 효과, 결과 없으면 전체 목록 표시<br>- **인터랙션 섹션 정리**: 텍스트 편집, 툴바 사용, 충돌 감지 등 편집 관련 내용 모두 제거<br> - 탭 전환, 회의 종료, 실시간 업데이트만 유지<br> - 실시간 업데이트 항목을 현재 화면에 맞게 수정 (AI 제안, 용어 사전, 관련 회의록)<br>- **데이터 요구사항 업데이트**: 사용자 편집 내용 제거, 참석자 초대 이메일 추가<br> - AI 제안을 "주요 메모 항목 제안"으로 명확히 표현<br>- **에러 처리 업데이트**: 편집 충돌 에러 제거, 용어 사전 로드 실패/참석자 초대 실패 추가<br>- **주요 기능 목록 정리**: 실시간 협업/수동 편집 제거, AI 주요 메모 제안/참석자 관리 추가<br>- **권한 항목 수정**: "회의록 편집: 모든 참석자" → "참석자 초대: 모든 참석자"<br>- **프로토타입 기준 반영**: 05-회의진행.html 실제 구현 상태 100% 반영 |
| 1.4.20 | 2025-10-25 | 이미준, 강지수 | 유저스토리 v2.3.0 반영<br>- 회의 종료 화면 정책 명확화 (확인 전용, 바로 최종 확정 옵션 상세화)<br>- UFR-MEET-050: 최종 확정 2가지 시나리오 설명 추가<br>- UFR-COLLAB-020: 안건 기반 충돌 해결 메커니즘 상세 추가<br>- 실시간 협업 충돌 방지 정책 강화 |
| 1.5.1 | 2025-10-27 | 강지수 | MVP 스코프 축소 v2.4.0 반영 (4개 화면 수정)<br>- **02-대시보드**: Todo 위젯 및 통계 제거 (UFR-USER-020 반영)<br> - Todo 위젯 전체 제거 (나의 Todo 섹션 삭제)<br> - 통계 카드: "나의 Todo" 제거, "작성중 회의록" 유지 (2개 항목)<br> - 네비게이션: 하단 네비게이션 및 사이드바에서 Todo 관리 메뉴 제거<br> - Desktop 통계 그리드: 2개 항목만 표시<br>- **05-회의진행**: "AI 제안" 탭 → "AI 기반 메모" 탭 기능 변경<br> - 메모 입력창 + 저장 버튼 추가<br> - AI가 감지한 주요 내용 리스트 표시 (시간 + 내용)<br> - 각 참석자별 개별 저장, 다른 참석자 메모 볼 수 없음<br> - 메모는 회의 종료 전까지만 표시/편집 가능<br> - 에러 처리: AI 주요 내용 감지 실패, 메모 저장 실패 추가<br>- **10-회의록상세조회**: Todo 단순 조회 기능으로 변경<br> - Todo는 제목 + 담당자 + 마감일만 표시<br> - D-day 라벨, 우선순위 배지, 진행률 바, 상태별 필터 제거<br> - Todo 관리 화면 연동 링크 제거 (화면 자체가 제거됨)<br> - "수정" 버튼을 헤더로 이동<br>- **11-회의록수정**: 실시간 협업 기능 제거, 안건 기반 충돌 방지 강화<br> - "편집 중" 표시 제거 (실시간 협업 기능 제거)<br> - Todo 편집/추가/삭제 기능 전체 제거 (단순 조회만 가능)<br> - AI 한줄 요약 재생성 불가 (회의 종료 시 1회만 생성)<br> - 검증률 표시 및 최종 확정 버튼 제거<br> - 저장 로직 추가: 검증완료 안건 저장 스킵, 저장 결과 알림<br> - 안건별 검증 완료 체크박스로 충돌 방지 (Last Write Wins 적용)<br> - 에러 처리: 충돌 경고 모달 제거 (LWW로 인해) |
--- ---