공유하기 기능 제거 및 문서 업데이트

- .gitignore 업데이트
- 대시보드 프로토타입 수정
- 회의록공유 프로토타입 삭제
- 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-23 10:27:44 +09:00
parent 9794926651
commit 4d8878aad3
6 changed files with 316 additions and 716 deletions
+92 -58
View File
@@ -137,11 +137,11 @@
}
}
/* 헤더 */
/* 헤더 - 개선안 A: 간결한 인사 + 실질적 정보 */
.header {
background: var(--white);
border-bottom: 1px solid var(--gray-300);
padding: var(--space-lg) var(--space-md);
padding: var(--space-md) var(--space-md);
}
@media (min-width: 768px) {
@@ -150,16 +150,19 @@
}
}
.header-title {
font-size: var(--font-h2);
.header-greeting {
font-size: var(--font-h3);
font-weight: var(--font-weight-bold);
color: var(--gray-900);
margin-bottom: var(--space-xs);
display: flex;
align-items: center;
gap: var(--space-xs);
}
.header-subtitle {
font-size: var(--font-small);
color: var(--gray-500);
.header-info {
font-size: var(--font-body);
color: var(--gray-600);
}
/* 메인 콘텐츠 */
@@ -176,36 +179,67 @@
}
}
/* 통계 카드 */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: var(--space-md);
margin-bottom: var(--space-xl);
}
.stat-card {
/* 통계 카드 - 개선안 A: 컴팩트 수평 배치 */
.stats-compact {
background: var(--white);
border-radius: var(--radius-lg);
padding: var(--space-lg);
padding: var(--space-md);
margin-bottom: var(--space-lg);
box-shadow: var(--shadow-sm);
}
.stat-icon {
font-size: 32px;
margin-bottom: var(--space-sm);
}
.stat-label {
.stats-compact-title {
font-size: var(--font-small);
color: var(--gray-500);
margin-bottom: var(--space-xs);
font-weight: var(--font-weight-semibold);
color: var(--gray-700);
margin-bottom: var(--space-sm);
display: flex;
align-items: center;
gap: var(--space-xs);
}
.stat-value {
font-size: var(--font-h2);
.stats-compact-items {
display: flex;
justify-content: space-around;
align-items: center;
gap: var(--space-md);
}
.stats-compact-item {
display: flex;
align-items: center;
gap: var(--space-xs);
font-size: var(--font-small);
color: var(--gray-600);
}
.stats-compact-icon {
font-size: 20px;
}
.stats-compact-value {
font-weight: var(--font-weight-bold);
color: var(--gray-900);
margin-left: 2px;
}
@media (min-width: 768px) {
.stats-compact {
padding: var(--space-lg);
}
.stats-compact-items {
justify-content: flex-start;
gap: var(--space-xl);
}
.stats-compact-item {
font-size: var(--font-body);
}
.stats-compact-icon {
font-size: 24px;
}
}
/* 섹션 헤더 */
@@ -528,28 +562,30 @@
<!-- 메인 콘텐츠 -->
<main class="main-content">
<!-- 헤더 -->
<!-- 헤더 - 개선안 A: 간결한 인사 + 실질적 정보 -->
<header class="header">
<h1 class="header-title">안녕하세요, 김민준님!</h1>
<p class="header-subtitle">오늘의 일정을 확인하세요</p>
<h1 class="header-greeting">
안녕하세요 👋
</h1>
<p class="header-info" id="header-meeting-info">오늘 <strong id="header-meeting-count">2</strong>건의 회의가 예정되어 있어요</p>
</header>
<!-- 통계 -->
<section class="stats-grid">
<div class="stat-card">
<div class="stat-icon">📅</div>
<div class="stat-label">예정된 회의</div>
<div class="stat-value" id="stat-scheduled">3</div>
</div>
<div class="stat-card">
<div class="stat-icon"></div>
<div class="stat-label">진행 중 Todo</div>
<div class="stat-value" id="stat-todos">1</div>
</div>
<div class="stat-card">
<div class="stat-icon">📈</div>
<div class="stat-label">Todo 완료율</div>
<div class="stat-value" id="stat-completion">33%</div>
<!-- 통계 - 개선안 A: 컴팩트 수평 배치 -->
<section class="stats-compact">
<div class="stats-compact-title">📊 오늘의 현황</div>
<div class="stats-compact-items">
<div class="stats-compact-item">
<span class="stats-compact-icon">📅</span>
<span>예정 <span class="stats-compact-value" id="stat-scheduled">2</span></span>
</div>
<div class="stats-compact-item">
<span class="stats-compact-icon"></span>
<span>진행 <span class="stats-compact-value" id="stat-todos">1</span></span>
</div>
<div class="stats-compact-item">
<span class="stats-compact-icon">📈</span>
<span>완료 <span class="stats-compact-value" id="stat-completion">0%</span></span>
</div>
</div>
</section>
@@ -585,17 +621,6 @@
<!-- 동적 생성 -->
</div>
</section>
<!-- 공유받은 회의록 -->
<section>
<div class="section-header">
<h2 class="section-title">공유받은 회의록</h2>
<a href="12-회의록목록조회.html" class="section-link">전체 보기 →</a>
</div>
<div class="minutes-list" id="shared-minutes">
<!-- 동적 생성 -->
</div>
</section>
</main>
<!-- 하단 네비게이션 (모바일) -->
@@ -813,7 +838,7 @@
}
/**
* 통계 업데이트
* 통계 업데이트 - 개선안 A: 헤더 정보 포함
*/
function updateStats() {
const scheduled = SAMPLE_MEETINGS.filter(m => m.status === 'scheduled' || m.status === 'ongoing').length;
@@ -822,6 +847,15 @@
const completedTodos = SAMPLE_TODOS.filter(t => t.assignee.id === currentUser.id && t.status === 'completed').length;
const completion = totalTodos > 0 ? Math.round((completedTodos / totalTodos) * 100) : 0;
// 헤더 정보 업데이트
$('#header-meeting-count').textContent = scheduled;
if (scheduled === 0) {
$('#header-meeting-info').innerHTML = '예정된 회의가 없습니다';
} else {
$('#header-meeting-info').innerHTML = `오늘 <strong>${scheduled}</strong>건의 회의가 예정되어 있어요`;
}
// 통계 카드 업데이트
$('#stat-scheduled').textContent = scheduled;
$('#stat-todos').textContent = todos;
$('#stat-completion').textContent = completion + '%';
@@ -1,491 +0,0 @@
<!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 배경 흰색으로 변경 */
body {
background: var(--white);
}
/* 헤더 - 회의록 수정화면과 통일 */
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 64px;
background: var(--white);
border-bottom: 1px solid var(--gray-300);
box-shadow: var(--shadow-sm);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--space-md);
z-index: 100;
}
.header-left {
display: flex;
align-items: center;
gap: var(--space-md);
}
.icon-btn {
background: transparent;
border: none;
font-size: 24px;
color: var(--gray-700);
cursor: pointer;
padding: var(--space-sm);
transition: color var(--transition-fast);
}
.icon-btn:hover {
color: var(--primary);
}
.header-title {
font-size: var(--font-h3);
font-weight: var(--font-weight-bold);
color: var(--gray-900);
}
/* 메인 콘텐츠 */
.main-content {
margin-top: 64px;
padding: var(--space-md);
padding-bottom: 100px;
}
@media (min-width: 768px) {
.main-content {
max-width: 800px;
margin-left: auto;
margin-right: auto;
padding-bottom: var(--space-lg);
}
}
/* 섹션 타이틀 */
.section-title {
font-size: var(--font-h3);
font-weight: var(--font-weight-bold);
color: var(--gray-900);
margin-bottom: var(--space-md);
}
/* 라디오 버튼 그룹 */
.radio-group {
display: flex;
flex-direction: column;
gap: var(--space-sm);
}
.radio-option {
display: flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-md);
border: 2px solid var(--gray-300);
border-radius: var(--radius-md);
cursor: pointer;
transition: all var(--transition-fast);
}
.radio-option:hover {
border-color: var(--primary-light);
background: var(--primary-light);
}
.radio-option.selected {
border-color: var(--primary);
background: var(--primary-light);
}
.radio-option input[type="radio"] {
width: 20px;
height: 20px;
accent-color: var(--primary);
}
.radio-option label {
flex: 1;
cursor: pointer;
font-weight: var(--font-weight-medium);
}
/* 참석자 체크리스트 */
.participant-list {
display: none;
margin-top: var(--space-md);
padding: var(--space-md);
background: var(--gray-100);
border-radius: var(--radius-md);
}
.participant-list.show {
display: block;
}
.participant-item {
display: flex;
align-items: center;
gap: var(--space-md);
padding: var(--space-sm) 0;
}
/* 토글 스위치 */
.toggle-group {
margin-bottom: var(--space-md);
}
.toggle-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--space-md);
background: var(--white);
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
margin-bottom: var(--space-sm);
}
.toggle-label {
font-weight: var(--font-weight-medium);
color: var(--gray-900);
}
.toggle-switch {
position: relative;
width: 48px;
height: 24px;
background: var(--gray-300);
border-radius: 12px;
cursor: pointer;
transition: background var(--transition-normal);
}
.toggle-switch.active {
background: var(--primary);
}
.toggle-switch::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: var(--white);
border-radius: 50%;
transition: transform var(--transition-normal);
}
.toggle-switch.active::after {
transform: translateX(24px);
}
/* 옵션 콘텐츠 */
.toggle-content {
display: none;
margin-top: var(--space-md);
padding: var(--space-md);
background: var(--gray-100);
border-radius: var(--radius-md);
}
.toggle-content.show {
display: block;
}
/* 공유 이력 */
.history-list {
margin-top: var(--space-md);
}
.history-item {
padding: var(--space-md);
background: var(--white);
border-radius: var(--radius-md);
box-shadow: var(--shadow-sm);
margin-bottom: var(--space-sm);
}
.history-header {
display: flex;
justify-content: space-between;
margin-bottom: var(--space-sm);
}
.history-date {
font-size: var(--font-small);
color: var(--gray-500);
}
.history-info {
font-size: var(--font-small);
color: var(--gray-700);
}
/* 하단 버튼 - 회의록 수정화면과 통일 */
.bottom-buttons {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: var(--space-md);
background: var(--white);
border-top: 1px solid var(--gray-300);
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
z-index: 100;
display: flex;
gap: var(--space-md);
}
@media (min-width: 768px) {
.bottom-buttons {
position: static;
margin-top: var(--space-lg);
border-top: none;
box-shadow: none;
padding: 0;
}
}
</style>
</head>
<body>
<!-- Header -->
<header class="header">
<div class="header-left">
<button class="icon-btn" onclick="history.back()"></button>
<h1 class="header-title">회의록 공유</h1>
</div>
</header>
<!-- Main Content -->
<main class="main-content">
<!-- 공유 대상 -->
<section class="mb-lg">
<h3 class="section-title">공유 대상</h3>
<div class="radio-group">
<div class="radio-option selected" id="shareAllOption" onclick="selectShareTarget('all')">
<input type="radio" name="shareTarget" id="shareAll" checked>
<label for="shareAll">참석자 전체</label>
</div>
<div class="radio-option" id="shareSelectedOption" onclick="selectShareTarget('selected')">
<input type="radio" name="shareTarget" id="shareSelected">
<label for="shareSelected">특정 참석자 선택</label>
</div>
</div>
<div class="participant-list" id="participantList">
<div id="participantCheckList"></div>
</div>
</section>
<!-- 공유 권한 -->
<section class="mb-lg">
<h3 class="section-title">공유 권한</h3>
<div class="form-group">
<select class="form-control" id="sharePermission">
<option value="readonly" selected>읽기 전용</option>
<option value="comment">댓글 가능</option>
<option value="edit">편집 가능</option>
</select>
</div>
</section>
<!-- 공유 방식 -->
<section class="mb-lg">
<h3 class="section-title">공유 방식</h3>
<div class="checkbox-wrapper mb-md">
<input type="checkbox" class="checkbox" id="emailShare" checked>
<label for="emailShare">이메일 발송</label>
</div>
<button class="btn btn-secondary" style="width: 100%;" onclick="copyShareLink()">
🔗 링크 복사
</button>
</section>
<!-- 링크 보안 설정 -->
<section class="mb-lg">
<h3 class="section-title">링크 보안 설정 (선택)</h3>
<div class="toggle-group">
<div class="toggle-item">
<span class="toggle-label">유효기간 설정</span>
<div class="toggle-switch" id="expiryToggle" onclick="toggleOption('expiry')"></div>
</div>
<div class="toggle-content" id="expiryContent">
<select class="form-control">
<option value="7">7일</option>
<option value="30" selected>30일</option>
<option value="90">90일</option>
<option value="0">무제한</option>
</select>
</div>
<div class="toggle-item">
<span class="toggle-label">비밀번호 설정</span>
<div class="toggle-switch" id="passwordToggle" onclick="toggleOption('password')"></div>
</div>
<div class="toggle-content" id="passwordContent">
<input type="password" class="form-control" placeholder="비밀번호 입력">
</div>
</div>
</section>
<!-- 공유 이력 -->
<section>
<h3 class="section-title">공유 이력</h3>
<div class="history-list" id="shareHistory"></div>
</section>
</main>
<!-- 하단 버튼 -->
<div class="bottom-buttons">
<button class="btn btn-primary" style="flex: 1;" onclick="shareMinutes()">
공유하기
</button>
</div>
<script src="common.js"></script>
<script>
// 페이지 초기화
function initPage() {
renderParticipantList();
renderShareHistory();
}
// 공유 대상 선택
function selectShareTarget(target) {
const allOption = $('#shareAllOption');
const selectedOption = $('#shareSelectedOption');
const participantList = $('#participantList');
if (target === 'all') {
allOption.classList.add('selected');
selectedOption.classList.remove('selected');
$('#shareAll').checked = true;
participantList.classList.remove('show');
} else {
allOption.classList.remove('selected');
selectedOption.classList.add('selected');
$('#shareSelected').checked = true;
participantList.classList.add('show');
}
}
// 참석자 체크리스트 렌더링
function renderParticipantList() {
const participants = SAMPLE_MEETINGS[0].participants;
const container = $('#participantCheckList');
participants.forEach(participant => {
const item = createElement('div', { className: 'participant-item' }, `
<input type="checkbox" class="checkbox" id="participant-${participant.id}" value="${participant.id}" checked>
${createAvatar(participant, 'sm')}
<label for="participant-${participant.id}">${participant.name}</label>
`);
container.appendChild(item);
});
}
// 토글 옵션
function toggleOption(option) {
const toggle = $(`#${option}Toggle`);
const content = $(`#${option}Content`);
toggle.classList.toggle('active');
content.classList.toggle('show');
}
// 링크 복사
function copyShareLink() {
const link = `https://meeting.example.com/share/meeting-001-${Date.now()}`;
// 클립보드 복사 (실제 구현)
if (navigator.clipboard) {
navigator.clipboard.writeText(link).then(() => {
showToast('링크가 복사되었습니다', 'success');
});
} else {
// Fallback
showToast('링크가 복사되었습니다', 'success');
}
}
// 공유 이력 렌더링
function renderShareHistory() {
const history = [
{ date: '2025-10-20 14:30', targets: '참석자 전체', permission: '읽기 전용' },
{ date: '2025-10-19 16:45', targets: '박서연, 이준호', permission: '편집 가능' }
];
const container = $('#shareHistory');
if (history.length === 0) {
container.innerHTML = '<div class="empty-state"><p>공유 이력이 없습니다</p></div>';
return;
}
history.forEach(item => {
const historyItem = createElement('div', { className: 'history-item' }, `
<div class="history-header">
<span class="history-date">${item.date}</span>
${createBadge(item.permission, 'draft')}
</div>
<div class="history-info">
<strong>대상:</strong> ${item.targets}
</div>
`);
container.appendChild(historyItem);
});
}
// 회의록 공유
function shareMinutes() {
const emailShare = $('#emailShare').checked;
const permission = $('#sharePermission').value;
const shareAll = $('#shareAll').checked;
// 특정 참석자 선택 시 검증
if (!shareAll) {
const selectedParticipants = Array.from($$('#participantCheckList input[type="checkbox"]:checked'));
if (selectedParticipants.length === 0) {
showToast('공유할 참석자를 선택해주세요', 'error');
return;
}
}
// 로딩 시뮬레이션
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = '공유 중...';
btn.disabled = true;
setTimeout(() => {
btn.textContent = originalText;
btn.disabled = false;
showToast('회의록이 공유되었습니다', 'success');
// 캘린더 등록 제안
setTimeout(() => {
if (confirm('다음 회의 일정을 캘린더에 등록하시겠습니까?')) {
showToast('캘린더에 등록되었습니다', 'success');
}
navigateTo('01-대시보드.html');
}, 1500);
}, 2000);
}
// 페이지 로드 시 초기화
initPage();
</script>
</body>
</html>