dfe246b7ca
- outlook-auth.js: one-time device-code flow against Microsoft login; stores the refresh token in the outlook-tokens compose volume - update-outlook.js: per-minute cron fetching the unread count and the latest unread messages via Microsoft Graph; caches access tokens and persists rotated refresh tokens - Widget is hidden until the mailbox is actually authorized, so it stays out of sight while (admin) consent is pending - New external card for Outlook (Office 365) with the official icon - compose: pass OUTLOOK_CLIENT_ID/OUTLOOK_TENANT/GITEA_TOKEN from .env - README: Entra ID app registration steps and the tenant-ID hint for directories not resolvable via the organizations endpoint
125 lines
4.1 KiB
HTML
125 lines
4.1 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<meta name="color-scheme" content="dark" />
|
|
<title>GG36</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
<link rel="stylesheet" href="style.css" />
|
|
</head>
|
|
<body>
|
|
<div class="bg-glow" aria-hidden="true"></div>
|
|
|
|
<div class="shell">
|
|
<header class="topbar">
|
|
<div class="brand">
|
|
<div class="logo-dot" aria-hidden="true"></div>
|
|
<div class="brand-text">
|
|
<h1>GG36</h1>
|
|
</div>
|
|
</div>
|
|
<div class="top-right">
|
|
<div class="search">
|
|
<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
|
|
<path
|
|
fill="none"
|
|
stroke="currentColor"
|
|
stroke-width="2"
|
|
stroke-linecap="round"
|
|
d="M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16Zm10 2-4.35-4.35"
|
|
/>
|
|
</svg>
|
|
<input
|
|
id="search"
|
|
type="search"
|
|
placeholder="Search services…"
|
|
autocomplete="off"
|
|
spellcheck="false"
|
|
/>
|
|
</div>
|
|
<div class="clock" id="clock" title="Local time">
|
|
<span id="clock-time">--:--:--</span>
|
|
<span id="clock-date">—</span>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<section class="widgets" id="widgets" aria-label="Live widgets">
|
|
<article class="widget widget-calendar" id="widget-calendar">
|
|
<div class="widget-head">
|
|
<div class="widget-icon" aria-hidden="true">📅</div>
|
|
<span class="widget-title">Today</span>
|
|
</div>
|
|
<div class="widget-body" id="today-events">
|
|
<p class="widget-loading">Loading…</p>
|
|
</div>
|
|
</article>
|
|
|
|
<article class="widget widget-outlook" id="widget-outlook" hidden>
|
|
<div class="widget-head">
|
|
<div class="widget-icon" aria-hidden="true">✉️</div>
|
|
<span class="widget-title">Outlook</span>
|
|
</div>
|
|
<div class="widget-body" id="outlook-mail">
|
|
<p class="widget-loading">Loading…</p>
|
|
</div>
|
|
</article>
|
|
|
|
<article class="widget widget-git" id="widget-git">
|
|
<div class="widget-head">
|
|
<div class="widget-icon" aria-hidden="true">🐙</div>
|
|
<span class="widget-title">Git activity</span>
|
|
</div>
|
|
<div class="widget-body" id="git-stats">
|
|
<p class="widget-loading">Loading…</p>
|
|
</div>
|
|
</article>
|
|
|
|
<article class="widget widget-gpu" id="widget-gpu">
|
|
<div class="widget-head">
|
|
<div class="widget-icon" aria-hidden="true">🖥️</div>
|
|
<span class="widget-title">GPU</span>
|
|
</div>
|
|
<div class="widget-body">
|
|
<div id="gpu-stats">
|
|
<p class="widget-loading">Loading…</p>
|
|
</div>
|
|
<div class="ollama-block">
|
|
<div class="ollama-label">Ollama</div>
|
|
<div id="ollama-stats">
|
|
<p class="widget-loading">Loading…</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</section>
|
|
|
|
<main id="app">
|
|
<!-- sections rendered by script.js -->
|
|
</main>
|
|
|
|
<section class="calendar-section" aria-labelledby="calendar-title">
|
|
<h2 id="calendar-title" class="section-title">
|
|
Calendar
|
|
<span class="count" id="calendar-count">0</span>
|
|
</h2>
|
|
<div id="calendar" class="calendar">
|
|
<p class="calendar-loading">Loading calendar…</p>
|
|
</div>
|
|
</section>
|
|
|
|
<footer class="footer">
|
|
<span id="stats"></span>
|
|
</footer>
|
|
</div>
|
|
|
|
<script src="script.js"></script>
|
|
</body>
|
|
</html>
|