Files
menav/templates/components/home-dashboard.hbs
2026-01-22 15:08:33 +08:00

211 lines
8.1 KiB
Handlebars
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{!-- home-dashboard.hbs - 首页专用 Dashboard 布局 (Refined Layout) --}}
<div class="dashboard-grid">
{{!-- 左侧:欢迎语 + 时钟 --}}
<div class="dashboard-intro">
<div class="dashboard-welcome">
<h1 class="welcome-title">{{title}}</h1>
<p class="welcome-subtitle">{{subtitle}}</p>
</div>
<div class="dashboard-clock-card">
<div class="clock-header">
<div class="clock-meta">
<div class="clock-greeting" id="dashboard-greeting">Hello</div>
<div class="clock-date" id="dashboard-date">Mon, Jan 01</div>
</div>
<div class="clock-week" id="dashboard-week">Week 1</div>
</div>
<div class="clock-main">
<div class="clock-time" id="dashboard-clock">00:00</div>
</div>
</div>
</div>
{{!-- 右侧Todo 面板 --}}
<div class="dashboard-stats">
<div class="dashboard-panel">
<div class="panel-sidebar">
<div class="panel-static-icon">
<span class="fas fa-bars"></span>
</div>
{{!-- 加号移至底部 --}}
<button class="panel-icon-btn add-btn" title="Add Todo" onclick="window.menavTodoApp.toggleInput()">
<span class="fas fa-plus"></span>
</button>
</div>
<div class="panel-content-wrapper">
<div class="panel-content custom-scrollbar" id="todo-list">
{{!-- Todo items will be rendered here via JS --}}
</div>
{{!-- 输入框默认隐藏 --}}
<div class="todo-input-container" id="todo-input-container"
style="display: none; padding: var(--spacing-md);">
<input type="text" class="todo-input" id="todo-input-field" placeholder="New task..."
onkeypress="window.menavTodoApp.handleInputKey(event)"
onblur="window.menavTodoApp.handleBlur()">
<button class="todo-add-btn-small" onmousedown="window.menavTodoApp.preventBlur(event)"
onclick="window.menavTodoApp.addFromInput()">
<span class="fas fa-arrow-right"></span>
</button>
</div>
</div>
</div>
</div>
</div>
<script>
(function () {
// --- Clock Logic ---
function getWeekNumber(d) {
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
var weekNo = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
return weekNo;
}
function getGreeting(hour) {
if (hour < 5) return "Good Night";
if (hour < 12) return "Good Morning";
if (hour < 18) return "Good Afternoon";
return "Good Evening";
}
function updateDashboardClock() {
const clockEl = document.getElementById('dashboard-clock');
const dateEl = document.getElementById('dashboard-date');
const greetingEl = document.getElementById('dashboard-greeting');
const weekEl = document.getElementById('dashboard-week');
if (!clockEl || !dateEl) return;
const now = new Date();
clockEl.textContent = now.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' });
dateEl.textContent = now.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
if (greetingEl) greetingEl.textContent = getGreeting(now.getHours());
if (weekEl) weekEl.textContent = `Week ${getWeekNumber(now)}`;
}
setInterval(updateDashboardClock, 1000);
updateDashboardClock();
// --- Todo App Logic ---
const TODO_STORAGE_KEY = 'menav_todos_v1';
window.menavTodoApp = {
todos: [],
isIgnoreBlur: false,
init() {
this.load();
this.render();
},
load() {
try {
const raw = localStorage.getItem(TODO_STORAGE_KEY);
this.todos = raw ? JSON.parse(raw) : [
{ text: 'Drink Water', done: false },
{ text: 'Explore MeNav', done: true }
];
} catch (e) { this.todos = []; }
},
save() {
try { localStorage.setItem(TODO_STORAGE_KEY, JSON.stringify(this.todos)); } catch (e) { }
},
toggleInput() {
const container = document.getElementById('todo-input-container');
const field = document.getElementById('todo-input-field');
if (container.style.display === 'none') {
container.style.display = 'flex';
field.focus();
} else {
container.style.display = 'none';
}
},
handleBlur() {
// Delay to allow button click to process first
setTimeout(() => {
if (this.isIgnoreBlur) {
this.isIgnoreBlur = false;
return;
}
const container = document.getElementById('todo-input-container');
if (container) container.style.display = 'none';
}, 200);
},
preventBlur(e) {
// Prevent input blur when clicking the add button
this.isIgnoreBlur = true;
},
addFromInput() {
const input = document.getElementById('todo-input-field');
if (input && input.value.trim()) {
this.todos.push({ text: input.value.trim(), done: false });
input.value = '';
this.save();
this.render();
// 保持底部可见
const list = document.getElementById('todo-list');
list.scrollTop = list.scrollHeight;
// Keep input open and focused
input.focus();
}
},
handleInputKey(e) { if (e.key === 'Enter') this.addFromInput(); },
toggle(index) {
this.todos[index].done = !this.todos[index].done;
this.save(); this.render();
},
remove(index, e) {
if (e) e.stopPropagation();
this.todos.splice(index, 1);
this.save(); this.render();
},
render() {
const container = document.getElementById('todo-list');
if (!container) return;
if (this.todos.length === 0) {
container.innerHTML = '<div class="empty-todo-hint">No tasks.</div>';
return;
}
container.innerHTML = this.todos.map((todo, index) => `
<div class="todo-item ${todo.done ? 'done' : ''}" onclick="window.menavTodoApp.toggle(${index})">
<div class="todo-checkbox ${todo.done ? 'checked' : ''}">
${todo.done ? '<span class="fas fa-check"></span>' : ''}
</div>
<div class="todo-text" title="${this.escapeHtml(todo.text)}">${this.escapeHtml(todo.text)}</div>
<button class="todo-delete-btn" onclick="window.menavTodoApp.remove(${index}, event)" title="Delete">
<span class="fas fa-trash-alt"></span>
</button>
</div>
`).join('');
},
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
};
window.menavTodoApp.init();
})();
</script>