mirror of
https://github.com/hwanny1128/HGZero.git
synced 2026-01-21 14:56:24 +00:00
프로토타입 사용자 관리 및 로그인 시스템 개선
- 8명의 샘플 사용자 데이터 추가 (SAMPLE_USERS) - 8가지 명확한 아바타 색상 스타일 추가 (red, blue, green, yellow, purple, cyan, magenta, orange) - 로그인 시스템 개선: 사번 입력으로 SAMPLE_USERS에서 검색하여 로그인 - 대시보드 사용자 정보 동적 렌더링 (사이드바, 헤더) - 회의예약 참석자 추가 모달에 전체 사용자 목록 표시 - 참석자 검색 기능 개선 (이름/이메일 검색) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e71b5c64d0
commit
d2443f90ad
@ -235,20 +235,20 @@
|
||||
|
||||
// 실제 환경에서는 API 호출
|
||||
setTimeout(() => {
|
||||
// 데모용 로그인 검증
|
||||
if (formData.employeeId === 'user-001' || formData.employeeId === 'demo') {
|
||||
// 데모용 로그인 검증 - SAMPLE_USERS에서 사용자 찾기
|
||||
const user = SAMPLE_USERS.find(u => u.id === formData.employeeId);
|
||||
|
||||
if (user) {
|
||||
// 로그인 성공 - 사용자 정보 저장
|
||||
const user = {
|
||||
id: 'user-001',
|
||||
name: '김민준',
|
||||
email: 'minjun.kim@example.com',
|
||||
const userToSave = {
|
||||
...user,
|
||||
employeeId: formData.employeeId
|
||||
};
|
||||
saveToStorage('currentUser', user);
|
||||
saveToStorage('currentUser', userToSave);
|
||||
saveToStorage('isLoggedIn', true);
|
||||
|
||||
// 대시보드로 이동
|
||||
showToast('로그인 성공!', 'success');
|
||||
showToast(`${user.name}님 로그인 성공!`, 'success');
|
||||
setTimeout(() => {
|
||||
navigateTo('02-대시보드.html');
|
||||
}, 500);
|
||||
@ -308,7 +308,10 @@
|
||||
}
|
||||
|
||||
console.log('01-로그인 화면 초기화 완료');
|
||||
console.log('데모 계정: user-001 또는 demo (비밀번호: 아무거나 8자 이상)');
|
||||
console.log('데모 계정 목록 (비밀번호: 아무거나 8자 이상):');
|
||||
SAMPLE_USERS.forEach(user => {
|
||||
console.log(`- ${user.id}: ${user.name} (${user.email})`);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -525,12 +525,8 @@
|
||||
</nav>
|
||||
|
||||
<!-- 사용자 정보 영역 (Desktop) -->
|
||||
<div class="sidebar-user">
|
||||
<div class="avatar avatar-green">김</div>
|
||||
<div class="sidebar-user-info">
|
||||
<div class="sidebar-user-name">김민준</div>
|
||||
<div class="sidebar-user-email">minjun.kim@company.com</div>
|
||||
</div>
|
||||
<div class="sidebar-user" id="sidebar-user">
|
||||
<!-- 동적으로 생성 -->
|
||||
</div>
|
||||
<button class="btn btn-ghost" style="width: calc(100% - 32px); margin: 0 16px 16px;" onclick="logout()">로그아웃</button>
|
||||
</aside>
|
||||
@ -538,8 +534,8 @@
|
||||
<!-- 헤더 -->
|
||||
<header class="header">
|
||||
<div class="header-left">
|
||||
<h1 class="header-title">김민준님</h1>
|
||||
<p class="header-subtitle">오늘 2건의 회의가 예정되어 있어요</p>
|
||||
<h1 class="header-title" id="header-title"><!-- 동적으로 생성 --></h1>
|
||||
<p class="header-subtitle" id="header-subtitle"><!-- 동적으로 생성 --></p>
|
||||
</div>
|
||||
<!-- Mobile 프로필 아이콘 -->
|
||||
<button class="mobile-profile-btn" onclick="toggleProfileMenu()" title="프로필">
|
||||
@ -652,6 +648,37 @@
|
||||
|
||||
const currentUser = getFromStorage('currentUser') || CURRENT_USER;
|
||||
|
||||
/**
|
||||
* 사이드바 사용자 정보 렌더링
|
||||
*/
|
||||
function renderSidebarUser() {
|
||||
const sidebarUser = $('#sidebar-user');
|
||||
sidebarUser.innerHTML = `
|
||||
${createAvatar(currentUser, 'md')}
|
||||
<div class="sidebar-user-info">
|
||||
<div class="sidebar-user-name">${currentUser.name}</div>
|
||||
<div class="sidebar-user-email">${currentUser.email}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 헤더 정보 렌더링
|
||||
*/
|
||||
function renderHeader() {
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const todayMeetings = SAMPLE_MEETINGS.filter(m =>
|
||||
m.date === today &&
|
||||
(m.status === 'scheduled' || m.status === 'ongoing') &&
|
||||
m.participants.some(p => p.id === currentUser.id)
|
||||
).length;
|
||||
|
||||
$('#header-title').textContent = `${currentUser.name}님`;
|
||||
$('#header-subtitle').textContent = todayMeetings > 0
|
||||
? `오늘 ${todayMeetings}건의 회의가 예정되어 있어요`
|
||||
: '오늘 예정된 회의가 없습니다';
|
||||
}
|
||||
|
||||
/**
|
||||
* 최근 회의 렌더링 (회의록 미생성 먼저, 빠른 일시 순으로 3개)
|
||||
*/
|
||||
@ -877,6 +904,8 @@
|
||||
* 초기화
|
||||
*/
|
||||
function init() {
|
||||
renderSidebarUser();
|
||||
renderHeader();
|
||||
updateStats();
|
||||
renderRecentMeetings();
|
||||
renderMyTodos();
|
||||
|
||||
@ -498,7 +498,12 @@
|
||||
}
|
||||
|
||||
// 현재 사용자 정보
|
||||
const currentUser = getFromStorage('currentUser') || CURRENT_USER;
|
||||
const storedUser = getFromStorage('currentUser');
|
||||
const currentUser = storedUser ? {
|
||||
...storedUser,
|
||||
avatar: storedUser.avatar || CURRENT_USER.avatar,
|
||||
avatarColor: storedUser.avatarColor || CURRENT_USER.avatarColor
|
||||
} : CURRENT_USER;
|
||||
|
||||
// 참석자 목록 (현재 사용자는 기본 포함)
|
||||
let participants = [currentUser];
|
||||
@ -693,17 +698,17 @@
|
||||
* 참석자 검색 결과 렌더링
|
||||
*/
|
||||
function renderSearchResults(query) {
|
||||
// 샘플 사용자 목록 (실제로는 API 호출)
|
||||
const sampleUsers = SAMPLE_MEETINGS[0].participants.filter(p =>
|
||||
!participants.some(participant => participant.id === p.id)
|
||||
// 샘플 사용자 목록에서 이미 추가된 참석자 제외
|
||||
const availableUsers = SAMPLE_USERS.filter(u =>
|
||||
!participants.some(participant => participant.id === u.id)
|
||||
);
|
||||
|
||||
const results = query
|
||||
? sampleUsers.filter(u =>
|
||||
? availableUsers.filter(u =>
|
||||
u.name.toLowerCase().includes(query.toLowerCase()) ||
|
||||
(u.email && u.email.toLowerCase().includes(query.toLowerCase()))
|
||||
)
|
||||
: sampleUsers;
|
||||
: availableUsers;
|
||||
|
||||
if (results.length === 0) {
|
||||
participantSearchResults.innerHTML = `
|
||||
|
||||
@ -764,12 +764,14 @@ input[type="date"]::-webkit-calendar-picker-indicator {
|
||||
}
|
||||
|
||||
/* Avatar Color Variants */
|
||||
.avatar-green { background: #4DD5A7; }
|
||||
.avatar-blue { background: #64B5F6; }
|
||||
.avatar-yellow { background: #FFB74D; }
|
||||
.avatar-pink { background: #F06292; }
|
||||
.avatar-purple { background: #9575CD; }
|
||||
.avatar-orange { background: #FF9800; }
|
||||
.avatar-red { background: #EF5350; color: var(--white); }
|
||||
.avatar-blue { background: #42A5F5; color: var(--white); }
|
||||
.avatar-green { background: #66BB6A; color: var(--white); }
|
||||
.avatar-yellow { background: #FFEE58; color: var(--gray-900); }
|
||||
.avatar-purple { background: #AB47BC; color: var(--white); }
|
||||
.avatar-cyan { background: #26C6DA; color: var(--white); }
|
||||
.avatar-magenta { background: #EC407A; color: var(--white); }
|
||||
.avatar-orange { background: #FF7043; color: var(--white); }
|
||||
|
||||
/* ========================================
|
||||
12. Lists
|
||||
|
||||
22
design/uiux/prototype/common.js
vendored
22
design/uiux/prototype/common.js
vendored
@ -7,14 +7,20 @@
|
||||
// 1. Global State & Sample Data
|
||||
// ========================================
|
||||
|
||||
// 현재 사용자 정보
|
||||
const CURRENT_USER = {
|
||||
id: 'user-001',
|
||||
name: '김민준',
|
||||
email: 'minjun.kim@example.com',
|
||||
avatar: '김',
|
||||
avatarColor: 'green'
|
||||
};
|
||||
// 샘플 사용자 목록
|
||||
const SAMPLE_USERS = [
|
||||
{ id: "user-001", name: "김민준", email: "minjun.kim@example.com", avatar: "김", avatarColor: "red" },
|
||||
{ id: "user-002", name: "박서연", email: "seoyeon.park@example.com", avatar: "박", avatarColor: "blue" },
|
||||
{ id: "user-003", name: "이준호", email: "junho.lee@example.com", avatar: "이", avatarColor: "green" },
|
||||
{ id: "user-004", name: "최유진", email: "yujin.choi@example.com", avatar: "최", avatarColor: "yellow" },
|
||||
{ id: "user-005", name: "정도현", email: "dohyun.jung@example.com", avatar: "정", avatarColor: "purple" },
|
||||
{ id: "user-006", name: "강지수", email: "jisoo.kang@example.com", avatar: "강", avatarColor: "cyan" },
|
||||
{ id: "user-007", name: "송주영", email: "jooyoung.song@example.com", avatar: "송", avatarColor: "magenta" },
|
||||
{ id: "user-008", name: "백현정", email: "hyunjung.baek@example.com", avatar: "백", avatarColor: "orange" }
|
||||
];
|
||||
|
||||
// 현재 사용자 정보 (기본값)
|
||||
const CURRENT_USER = SAMPLE_USERS[0];
|
||||
|
||||
// 샘플 회의 데이터
|
||||
const SAMPLE_MEETINGS = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user