mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 10:16:24 +00:00
Todo 추가기능 추가 & 모달 팝업을 모바일에서 바텀시트로 수정
This commit is contained in:
parent
aa757766cf
commit
0d65be87a2
@ -1129,7 +1129,10 @@
|
|||||||
|
|
||||||
<!-- Todo 단순 조회 (MVP 스코프 축소 v1.5.1) -->
|
<!-- Todo 단순 조회 (MVP 스코프 축소 v1.5.1) -->
|
||||||
<div class="card mb-lg">
|
<div class="card mb-lg">
|
||||||
<h3 class="card-title">📋 Todo 리스트</h3>
|
<div class="section-header">
|
||||||
|
<h3 class="card-title">📋 Todo 리스트</h3>
|
||||||
|
<button class="btn btn-primary btn-sm" onclick="openModal('addTodoModal')">추가</button>
|
||||||
|
</div>
|
||||||
<p style="font-size: var(--font-small); color: var(--gray-600); margin-bottom: var(--space-md);">
|
<p style="font-size: var(--font-small); color: var(--gray-600); margin-bottom: var(--space-md);">
|
||||||
Todo 항목은 조회만 가능합니다. 제목, 담당자, 마감일 정보만 표시됩니다.
|
Todo 항목은 조회만 가능합니다. 제목, 담당자, 마감일 정보만 표시됩니다.
|
||||||
</p>
|
</p>
|
||||||
@ -1139,7 +1142,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">데이터베이스 스키마 설계</div>
|
<div class="simple-todo-title">데이터베이스 스키마 설계</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(1)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(1)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 이준호</span>
|
<span>👤 이준호</span>
|
||||||
@ -1150,7 +1153,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">API 명세서 작성</div>
|
<div class="simple-todo-title">API 명세서 작성</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(2)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(2)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 이준호</span>
|
<span>👤 이준호</span>
|
||||||
@ -1161,7 +1164,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">예산 편성안 검토</div>
|
<div class="simple-todo-title">예산 편성안 검토</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(3)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(3)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 김민준</span>
|
<span>👤 김민준</span>
|
||||||
@ -1172,7 +1175,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">UI 프로토타입 디자인</div>
|
<div class="simple-todo-title">UI 프로토타입 디자인</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(4)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(4)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 최유진</span>
|
<span>👤 최유진</span>
|
||||||
@ -1183,7 +1186,7 @@
|
|||||||
<div class="simple-todo-item">
|
<div class="simple-todo-item">
|
||||||
<div class="simple-todo-header">
|
<div class="simple-todo-header">
|
||||||
<div class="simple-todo-title">사용자 피드백 분석</div>
|
<div class="simple-todo-title">사용자 피드백 분석</div>
|
||||||
<button class="simple-todo-edit-btn" onclick="editTodo(5)" title="수정">✏️</button>
|
<button class="simple-todo-edit-btn creator-only" onclick="editTodo(5)" title="수정">✏️</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="simple-todo-meta">
|
<div class="simple-todo-meta">
|
||||||
<span>👤 김민준</span>
|
<span>👤 김민준</span>
|
||||||
@ -1247,17 +1250,27 @@
|
|||||||
<div class="modal">
|
<div class="modal">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="modal-title">Todo 추가</h3>
|
<h3 class="modal-title">Todo 추가</h3>
|
||||||
<button class="modal-close">×</button>
|
<button class="modal-close" onclick="closeModal('addTodoModal')">×</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">Todo 내용</label>
|
<label class="form-label">Todo 내용 <span class="text-error">*</span></label>
|
||||||
<input type="text" class="form-control" placeholder="할 일을 입력하세요">
|
<input type="text" id="addTodoTitle" class="form-control" placeholder="할 일을 입력하세요">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">마감일</label>
|
<label class="form-label">담당자 <span class="text-error">*</span></label>
|
||||||
|
<select id="addTodoAssignee" class="form-control">
|
||||||
|
<option value="">담당자를 선택하세요</option>
|
||||||
|
<option value="김민준">김민준</option>
|
||||||
|
<option value="이준호">이준호</option>
|
||||||
|
<option value="박서연">박서연</option>
|
||||||
|
<option value="최유진">최유진</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
||||||
<div class="date-input-wrapper">
|
<div class="date-input-wrapper">
|
||||||
<input type="date" class="form-control">
|
<input type="date" id="addTodoDueDate" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1290,22 +1303,12 @@
|
|||||||
<option value="박서연">박서연</option>
|
<option value="박서연">박서연</option>
|
||||||
<option value="최유진">최유진</option>
|
<option value="최유진">최유진</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="form-hint">👤 담당자 변경 시 이전/새 담당자에게 알림이 전송됩니다</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
<label class="form-label">마감일 <span class="text-error">*</span></label>
|
||||||
<div class="date-input-wrapper">
|
<div class="date-input-wrapper">
|
||||||
<input type="date" id="editTodoDueDate" class="form-control">
|
<input type="date" id="editTodoDueDate" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<p class="form-hint">📅 마감일 변경 시 캘린더가 자동 업데이트됩니다</p>
|
|
||||||
</div>
|
|
||||||
<!-- 권한 안내 (동적 메시지) -->
|
|
||||||
<div class="alert alert-info" id="editTodoPermissionInfo">
|
|
||||||
<span class="material-icons" style="font-size: 20px;">info</span>
|
|
||||||
<div>
|
|
||||||
<strong>권한 안내</strong>
|
|
||||||
<p style="margin: 4px 0 0 0; font-size: 14px;" id="editTodoPermissionText">회의 생성자로서 모든 항목을 수정할 수 있습니다.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -1347,95 +1350,39 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo 편집 모달 - 모바일 전체화면 */
|
/* Todo 추가/편집 모달 - 바텀시트 스타일 */
|
||||||
|
#addTodoModal .modal,
|
||||||
#editTodoModal .modal {
|
#editTodoModal .modal {
|
||||||
position: fixed;
|
max-height: 90vh;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
max-width: none;
|
|
||||||
max-height: none;
|
|
||||||
margin: 0;
|
|
||||||
border-radius: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-header {
|
|
||||||
flex-shrink: 0;
|
|
||||||
padding: var(--space-lg) var(--space-md);
|
|
||||||
border-bottom: 1px solid var(--gray-200);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-title {
|
|
||||||
font-size: var(--font-h3);
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-close {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 28px;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--gray-600);
|
|
||||||
border-radius: var(--radius-md);
|
|
||||||
transition: all var(--transition-fast);
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-close:hover {
|
|
||||||
background: var(--gray-100);
|
|
||||||
color: var(--gray-900);
|
|
||||||
}
|
|
||||||
|
|
||||||
#editTodoModal .modal-body {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: var(--space-lg) var(--space-md);
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addTodoModal .modal-footer,
|
||||||
#editTodoModal .modal-footer {
|
#editTodoModal .modal-footer {
|
||||||
flex-shrink: 0;
|
|
||||||
padding: var(--space-md);
|
|
||||||
border-top: 1px solid var(--gray-200);
|
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: var(--space-sm);
|
gap: var(--space-sm);
|
||||||
background: var(--white);
|
justify-content: flex-end;
|
||||||
|
margin-top: var(--space-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addTodoModal .modal-footer .btn,
|
||||||
#editTodoModal .modal-footer .btn {
|
#editTodoModal .modal-footer .btn {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 데스크톱에서는 중앙 모달로 복원 */
|
/* 데스크톱에서는 중앙 모달 */
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
|
#addTodoModal .modal,
|
||||||
#editTodoModal .modal {
|
#editTodoModal .modal {
|
||||||
position: relative;
|
|
||||||
top: auto;
|
|
||||||
left: auto;
|
|
||||||
right: auto;
|
|
||||||
bottom: auto;
|
|
||||||
width: 90%;
|
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
height: auto;
|
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
margin: 0 auto;
|
|
||||||
border-radius: var(--radius-lg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 회의 생성자 전용 요소 숨김 */
|
||||||
|
.creator-only.hidden {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="common.js"></script>
|
<script src="common.js"></script>
|
||||||
@ -1766,18 +1713,12 @@
|
|||||||
const currentUser = '김민준'; // 현재 로그인 사용자
|
const currentUser = '김민준'; // 현재 로그인 사용자
|
||||||
const isCreator = checkIfUserIsCreator(CURRENT_MEETING_ID, currentUser);
|
const isCreator = checkIfUserIsCreator(CURRENT_MEETING_ID, currentUser);
|
||||||
|
|
||||||
// 담당자 필드 표시 여부 결정
|
// 담당자 필드 표시 여부 결정 (회의 생성자만 표시)
|
||||||
const assigneeGroup = document.getElementById('editTodoAssigneeGroup');
|
const assigneeGroup = document.getElementById('editTodoAssigneeGroup');
|
||||||
const permissionText = document.getElementById('editTodoPermissionText');
|
|
||||||
|
|
||||||
if (isCreator) {
|
if (isCreator) {
|
||||||
// 회의 생성자: 담당자 변경 가능
|
|
||||||
assigneeGroup.style.display = 'block';
|
assigneeGroup.style.display = 'block';
|
||||||
permissionText.textContent = '회의 생성자로서 모든 항목을 수정할 수 있습니다.';
|
|
||||||
} else {
|
} else {
|
||||||
// 일반 담당자: 담당자 변경 불가
|
|
||||||
assigneeGroup.style.display = 'none';
|
assigneeGroup.style.display = 'none';
|
||||||
permissionText.textContent = '본인에게 할당된 Todo만 수정할 수 있습니다. 담당자는 변경할 수 없습니다.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 모달 열기
|
// 모달 열기
|
||||||
@ -1852,6 +1793,67 @@
|
|||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo 추가 함수
|
||||||
|
*/
|
||||||
|
function addTodo() {
|
||||||
|
const title = document.getElementById('addTodoTitle').value.trim();
|
||||||
|
const assignee = document.getElementById('addTodoAssignee').value.trim();
|
||||||
|
const dueDate = document.getElementById('addTodoDueDate').value;
|
||||||
|
|
||||||
|
// 유효성 검사
|
||||||
|
if (!title) {
|
||||||
|
showToast('Todo 내용을 입력해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!assignee) {
|
||||||
|
showToast('담당자를 선택해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dueDate) {
|
||||||
|
showToast('마감일을 선택해주세요', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 새 Todo 추가 (실제로는 API 호출)
|
||||||
|
const newTodo = {
|
||||||
|
id: 'todo-' + Date.now(),
|
||||||
|
meetingId: CURRENT_MEETING_ID,
|
||||||
|
title: title,
|
||||||
|
assignee: assignee,
|
||||||
|
dueDate: dueDate,
|
||||||
|
status: 'pending'
|
||||||
|
};
|
||||||
|
|
||||||
|
meetingTodos.push(newTodo);
|
||||||
|
|
||||||
|
showToast('Todo가 추가되었습니다', 'success');
|
||||||
|
|
||||||
|
// 담당자에게 알림 전송
|
||||||
|
setTimeout(() => {
|
||||||
|
showToast(`${assignee}에게 알림이 전송되었습니다`, 'info');
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
// 캘린더 업데이트 알림
|
||||||
|
setTimeout(() => {
|
||||||
|
showToast('캘린더가 업데이트되었습니다', 'info');
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
closeModal('addTodoModal');
|
||||||
|
|
||||||
|
// 입력 필드 초기화
|
||||||
|
document.getElementById('addTodoTitle').value = '';
|
||||||
|
document.getElementById('addTodoAssignee').value = '';
|
||||||
|
document.getElementById('addTodoDueDate').value = '';
|
||||||
|
|
||||||
|
// 페이지 새로고침 (실제로는 Todo 리스트만 업데이트)
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 2500);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 페이지 초기화
|
* 페이지 초기화
|
||||||
*/
|
*/
|
||||||
@ -1868,6 +1870,12 @@
|
|||||||
crownIcon.title = '회의 생성자';
|
crownIcon.title = '회의 생성자';
|
||||||
// 배지 영역에 크라운 추가
|
// 배지 영역에 크라운 추가
|
||||||
badgesContainer.appendChild(crownIcon);
|
badgesContainer.appendChild(crownIcon);
|
||||||
|
} else {
|
||||||
|
// 회의 생성자가 아닐 경우 creator-only 요소 숨김
|
||||||
|
const creatorOnlyElements = document.querySelectorAll('.creator-only');
|
||||||
|
creatorOnlyElements.forEach(element => {
|
||||||
|
element.classList.add('hidden');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTodoProgress();
|
updateTodoProgress();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user