Skip to content

Instantly share code, notes, and snippets.

@a70437043b
Created April 8, 2026 03:59
Show Gist options
  • Select an option

  • Save a70437043b/c923689dabb60e50caf8155770a10709 to your computer and use it in GitHub Desktop.

Select an option

Save a70437043b/c923689dabb60e50caf8155770a10709 to your computer and use it in GitHub Desktop.
Notion Calendar Widget
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
:root {
--bg-color: #191919; --card-bg: #252525; --text-main: #ffffff;
--holiday-red: #ff4d4f; --event-green: #52c41a; --vacation-pink: #eb2f96; --task-cyan: #13c2c2;
}
body { font-family: sans-serif; background: var(--bg-color); color: var(--text-main); margin: 0; padding: 10px; display: flex; flex-direction: column; align-items: center; }
.calendar-container { width: 95%; max-width: 350px; background: var(--card-bg); border-radius: 15px; padding: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.3); }
.header { text-align: center; font-size: 1.2em; font-weight: bold; margin-bottom: 15px; color: #ffd666; }
.grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; text-align: center; }
.day-name { font-size: 0.75em; color: #888; font-weight: bold; padding-bottom: 8px; }
.day { aspect-ratio: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 0.9em; border-radius: 8px; position: relative; cursor: pointer; border: 1px solid transparent; }
.day:hover { border-color: #555; }
.today { background: rgba(255,255,255,0.1); border: 1px solid #ffd666; }
.dot-container { display: flex; gap: 2px; position: absolute; bottom: 3px; }
.dot { width: 5px; height: 5px; border-radius: 50%; }
.dot-red { background: var(--holiday-red); } .dot-green { background: var(--event-green); }
.dot-pink { background: var(--vacation-pink); } .dot-cyan { background: var(--task-cyan); }
/* 節日與輸入框樣式 */
.info-panel { width: 100%; margin-top: 15px; font-size: 0.85em; }
.holiday-label { color: var(--holiday-red); margin-bottom: 8px; font-weight: bold; }
.input-group { display: flex; gap: 5px; margin-top: 10px; }
input { flex: 1; background: #333; border: 1px solid #444; color: white; padding: 5px 10px; border-radius: 5px; outline: none; }
button { background: #4d4d4d; border: none; color: white; padding: 5px 10px; border-radius: 5px; cursor: pointer; }
button:hover { background: #666; }
.legend { display: flex; flex-wrap: wrap; gap: 10px; font-size: 0.7em; margin-top: 10px; color: #aaa; }
</style>
</head>
<body>
<div class="calendar-container">
<div class="header" id="monthYear"></div>
<div class="grid" id="calendarGrid"></div>
<div class="info-panel">
<div id="holidayText" class="holiday-label"></div>
<div class="input-group">
<input type="text" id="eventInput" placeholder="輸入今日任務...">
<button onclick="addEvent()">加入</button>
</div>
<div class="legend">
<span><i class="dot dot-red" style="display:inline-block"></i> 節日</span>
<span><i class="dot dot-pink" style="display:inline-block"></i> 假期</span>
<span><i class="dot dot-green" style="display:inline-block"></i> 事件</span>
<span><i class="dot dot-cyan" style="display:inline-block"></i> 任務</span>
</div>
</div>
</div>
<script>
const holidays2026 = {
"01-01": "元旦", "02-16": "春假", "02-17": "除夕", "02-18": "春節", "02-28": "228紀念日",
"04-04": "兒童節/清明節", "05-01": "勞動節", "06-19": "端午節", "09-25": "中秋節", "10-10": "國慶日"
};
const vacations = ["02-16", "02-17", "02-18", "02-19", "02-20"]; // 範例假期
function init() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
render(year, month);
}
function render(year, month) {
const monthNames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
document.getElementById('monthYear').innerText = `${year}年 ${monthNames[month]}`;
const grid = document.getElementById('calendarGrid');
grid.innerHTML = ["日", "一", "二", "三", "四", "五", "六"].map(d => `<div class="day-name">${d}</div>`).join('');
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
const todayStr = new Date().toISOString().split('T')[0];
for (let i = 0; i < firstDay; i++) grid.innerHTML += `<div></div>`;
for (let d = 1; d <= daysInMonth; d++) {
const dateKey = `${String(month+1).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
const fullDate = `${year}-${dateKey}`;
const isToday = fullDate === todayStr ? 'today' : '';
let dots = "";
if (holidays2026[dateKey]) dots += '<div class="dot dot-red"></div>';
if (vacations.includes(dateKey)) dots += '<div class="dot dot-pink"></div>';
// 檢查本地存儲的事件
const savedData = localStorage.getItem('notion_events_' + fullDate);
if (savedData) {
const data = JSON.parse(savedData);
if (data.type === 'event') dots += '<div class="dot dot-green"></div>';
if (data.type === 'task') dots += '<div class="dot dot-cyan"></div>';
}
grid.innerHTML += `
<div class="day ${isToday}" onclick="showInfo('${dateKey}')">
${d}
<div class="dot-container">${dots}</div>
</div>`;
if (fullDate === todayStr && holidays2026[dateKey]) {
document.getElementById('holidayText').innerText = "今日節慶:" + holidays2026[dateKey];
}
}
}
function addEvent() {
const input = document.getElementById('eventInput');
if (!input.value) return;
const today = new Date().toISOString().split('T')[0];
localStorage.setItem('notion_events_' + today, JSON.stringify({ text: input.value, type: 'task' }));
alert("已加入今日任務!重新整理後會顯示青色點點");
input.value = "";
location.reload();
}
function showInfo(key) {
if (holidays2026[key]) document.getElementById('holidayText').innerText = "節日資訊:" + holidays2026[key];
else document.getElementById('holidayText').innerText = "";
}
init();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment