apolinario commited on
Commit
6bad670
·
1 Parent(s): a99ebea

Add logout menu under the user pill

Browse files
Files changed (1) hide show
  1. index.html +46 -1
index.html CHANGED
@@ -111,6 +111,7 @@ body {
111
  }
112
 
113
  .user-pill {
 
114
  display: flex;
115
  align-items: center;
116
  gap: 8px;
@@ -120,7 +121,10 @@ body {
120
  border-radius: 20px;
121
  font-size: 13px;
122
  color: var(--text-secondary);
 
 
123
  }
 
124
 
125
  .user-pill img {
126
  width: 24px;
@@ -128,6 +132,22 @@ body {
128
  border-radius: 50%;
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  .sidebar {
132
  background: var(--surface);
133
  border-right: 1px solid var(--border);
@@ -780,9 +800,15 @@ pre {
780
  <button class="theme-btn" onclick="cycleTheme()" title="Toggle theme" id="theme-btn-app">
781
  <svg id="theme-icon-app" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
782
  </button>
783
- <div class="user-pill" id="user-pill">
784
  <img id="user-avatar" src="" alt="">
785
  <span id="user-name"></span>
 
 
 
 
 
 
786
  </div>
787
  </div>
788
  </div>
@@ -2257,6 +2283,25 @@ window.login = async function() {
2257
  window.location.href = await oauthLoginUrl({ scopes: "openid profile read-billing" });
2258
  };
2259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2260
  function showApp() {
2261
  document.getElementById("landing").style.display = "none";
2262
  document.getElementById("app").style.display = "grid";
 
111
  }
112
 
113
  .user-pill {
114
+ position: relative;
115
  display: flex;
116
  align-items: center;
117
  gap: 8px;
 
121
  border-radius: 20px;
122
  font-size: 13px;
123
  color: var(--text-secondary);
124
+ cursor: pointer;
125
+ transition: all 0.1s;
126
  }
127
+ .user-pill:hover { border-color: var(--border-hover); color: var(--text); }
128
 
129
  .user-pill img {
130
  width: 24px;
 
132
  border-radius: 50%;
133
  }
134
 
135
+ .user-menu {
136
+ position: absolute; top: calc(100% + 6px); right: 0;
137
+ min-width: 160px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
138
+ box-shadow: 0 8px 24px var(--shadow-color); padding: 4px; z-index: 50;
139
+ display: none;
140
+ }
141
+ .user-menu.visible { display: block; }
142
+ .user-menu-item {
143
+ display: flex; align-items: center; gap: 8px; width: 100%;
144
+ padding: 8px 10px; border: none; background: transparent;
145
+ font-family: 'Inter', sans-serif; font-size: 13px; color: var(--text);
146
+ text-align: left; border-radius: 6px; cursor: pointer;
147
+ }
148
+ .user-menu-item:hover { background: var(--surface2); }
149
+ .user-menu-item svg { width: 14px; height: 14px; flex-shrink: 0; }
150
+
151
  .sidebar {
152
  background: var(--surface);
153
  border-right: 1px solid var(--border);
 
800
  <button class="theme-btn" onclick="cycleTheme()" title="Toggle theme" id="theme-btn-app">
801
  <svg id="theme-icon-app" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
802
  </button>
803
+ <div class="user-pill" id="user-pill" onclick="toggleUserMenu(event)">
804
  <img id="user-avatar" src="" alt="">
805
  <span id="user-name"></span>
806
+ <div class="user-menu" id="user-menu">
807
+ <button class="user-menu-item" type="button" onclick="event.stopPropagation();logout()">
808
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
809
+ Log out
810
+ </button>
811
+ </div>
812
  </div>
813
  </div>
814
  </div>
 
2283
  window.location.href = await oauthLoginUrl({ scopes: "openid profile read-billing" });
2284
  };
2285
 
2286
+ window.toggleUserMenu = function(e) {
2287
+ e.stopPropagation();
2288
+ document.getElementById("user-menu").classList.toggle("visible");
2289
+ };
2290
+
2291
+ window.logout = function() {
2292
+ sessionStorage.removeItem("zl_token");
2293
+ sessionStorage.removeItem("zl_user");
2294
+ sessionStorage.removeItem("zl_expires");
2295
+ // Clean OAuth params from URL if present, then reload
2296
+ const url = new URL(window.location.href);
2297
+ ["code", "state", "oauth_redirect", "id_token", "access_token"].forEach(k => url.searchParams.delete(k));
2298
+ window.location.replace(url.toString().replace(/\?$/, ""));
2299
+ };
2300
+
2301
+ document.addEventListener("click", () => {
2302
+ document.getElementById("user-menu")?.classList.remove("visible");
2303
+ });
2304
+
2305
  function showApp() {
2306
  document.getElementById("landing").style.display = "none";
2307
  document.getElementById("app").style.display = "grid";