diff --git a/server/db.js b/server/db.js index b44229f..84c7414 100644 --- a/server/db.js +++ b/server/db.js @@ -238,6 +238,24 @@ try { db.exec('CREATE INDEX IF NOT EXISTS idx_users_bizgaze_user_id ON users(biz // When two accounts merge (#2), the merged-away row is deleted. This records old_id -> survivor so // any lingering reference to the old id (a cached contact, an in-flight DM) resolves to the survivor // instead of hitting a deleted user (which made messages to merged contacts silently vanish). +// #7: a log of finished CALLS (ad-hoc / group / 1:1). Scheduled meetings already have their own row, so +// they're not duplicated here. `peak` is the most people who were in the room at once โ€” that's what lets +// "Past meetings" show a call that grew past 2 people while hiding plain 1:1s. +db.exec(` +CREATE TABLE IF NOT EXISTS call_history ( + id TEXT PRIMARY KEY, + team_id TEXT NOT NULL, + room TEXT NOT NULL, + group_id TEXT, + kind TEXT, + title TEXT, + peak INTEGER NOT NULL DEFAULT 0, + participants TEXT, + uids TEXT, + started_at INTEGER NOT NULL, + ended_at INTEGER NOT NULL +)`); +try { db.exec('CREATE INDEX IF NOT EXISTS idx_call_history_team ON call_history(team_id, ended_at)'); } catch (e) {} db.exec(` CREATE TABLE IF NOT EXISTS user_aliases ( old_id TEXT PRIMARY KEY, diff --git a/server/public/home.html b/server/public/home.html index f3f3c2a..f3a2ab7 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -820,7 +820,18 @@ .gi-open{cursor:pointer;} .sched-wrap{width:100%;margin:1.2rem 0 0;text-align:left;} .sched-sec{margin-bottom:1.4rem;} - .sched-h{font-size:.74rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:0 0 .55rem;font-weight:700;} + .sched-h{display:flex;align-items:center;gap:.6rem;font-size:.74rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:0 0 .55rem;font-weight:700;} + /* #7: past-meetings date filter + pager */ + .mtg-filter{display:inline-flex;align-items:center;gap:.35rem;margin-left:auto;text-transform:none;letter-spacing:0;} + .mtg-filter svg{color:var(--blue);flex:0 0 auto;} + .mtg-filter input[type=date]{border:1px solid var(--line);border-radius:8px;padding:.25rem .4rem;font:inherit;font-size:.72rem;font-weight:600;background:#fbfcfe;color:var(--ink);} + .mtg-filter input[type=date]:focus{outline:none;border-color:var(--blue);} + .mtg-clear{border:none;background:transparent;color:var(--muted);cursor:pointer;display:grid;place-items:center;padding:.15rem;border-radius:50%;} + .mtg-clear:hover{background:#fee2e2;color:var(--red);} + .mtg-pager{display:flex;align-items:center;justify-content:center;gap:.7rem;margin-top:.7rem;font-size:.76rem;color:var(--muted);} + .mtg-pg{border:1px solid var(--line);background:var(--card);color:var(--blue);border-radius:8px;width:30px;height:28px;display:grid;place-items:center;cursor:pointer;} + .mtg-pg:hover:not(:disabled){background:var(--blue-soft);} + .mtg-pg:disabled{opacity:.4;cursor:default;} .sched-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:.7rem;} .sched-item{display:flex;align-items:flex-start;gap:.6rem;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:.8rem .9rem;} .sched-item.live{border-color:#34d399;background:#f0fdf4;} @@ -1037,7 +1048,7 @@ -