AkurAI Build
Menu

Public repository / master

AkurAI-Drive / desktop/ui/index.html

Latest change 2a1ed73acfbc6091a9fcdba5a28f55de9e2d75a4 - feat: native email+password sign-in (no browser) by olibuijr

<!doctype html>
<html lang="en" data-theme="akurai">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AkurAI Drive</title>
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@600;700;800&family=Inter:wght@400;450;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="app.css">
</head>
<body>

<!-- ===== SIGN IN ===== -->
<section id="screen-signin" class="screen center hidden">
  <div class="signin-card">
    <svg class="mark mark-lg" viewBox="0 0 32 32" aria-hidden="true">
      <defs><linearGradient id="gsign" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#5b8cff"/><stop offset="1" stop-color="#7af0d0"/></linearGradient></defs>
      <g fill="url(#gsign)">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M13.38 3.23c1.05-2.23 4.19-2.23 5.24 0l11.05 23.62A2.91 2.91 0 0 1 27.03 31h-3.42c-1.17 0-2.22-.7-2.67-1.78l-2.05-4.93h-5.78l-2.05 4.93A2.9 2.9 0 0 1 8.39 31H4.97a2.91 2.91 0 0 1-2.64-4.15L13.38 3.23ZM16 11.17l-5.13 13.1h10.26L16 11.17Z"/>
        <path d="M10.38 20.54h11.24a2.23 2.23 0 0 1 0 4.46H10.38a2.23 2.23 0 0 1 0-4.46Z"/>
      </g>
    </svg>
    <h1>AkurAI&nbsp;Drive</h1>
    <p class="muted">Your private cloud, hosted in Iceland. Sign in with your AkurAI account to access your files.</p>
    <form id="signin-form" class="signin-form" autocomplete="on">
      <div class="field">
        <label for="signin-email">Email</label>
        <input id="signin-email" type="email" name="email" autocomplete="username" spellcheck="false" placeholder="you@example.com" required>
      </div>
      <div class="field">
        <label for="signin-password">Password</label>
        <input id="signin-password" type="password" name="password" autocomplete="current-password" placeholder="Your password" required>
      </div>
      <p id="signin-error" class="signin-error hidden" role="alert"></p>
      <button id="btn-signin-pw" type="submit" class="btn btn-primary btn-lg">Sign in</button>
    </form>
    <button id="btn-signin" class="link-btn">Sign in with browser instead</button>
    <p id="signin-hint" class="muted small"></p>
  </div>
</section>

<!-- ===== SETUP (pick bucket + folder) ===== -->
<section id="screen-setup" class="screen center hidden">
  <div class="signin-card wide">
    <svg class="mark" viewBox="0 0 32 32" aria-hidden="true">
      <g fill="url(#gsign)">
        <path fill-rule="evenodd" clip-rule="evenodd" d="M13.38 3.23c1.05-2.23 4.19-2.23 5.24 0l11.05 23.62A2.91 2.91 0 0 1 27.03 31h-3.42c-1.17 0-2.22-.7-2.67-1.78l-2.05-4.93h-5.78l-2.05 4.93A2.9 2.9 0 0 1 8.39 31H4.97a2.91 2.91 0 0 1-2.64-4.15L13.38 3.23ZM16 11.17l-5.13 13.1h10.26L16 11.17Z"/>
        <path d="M10.38 20.54h11.24a2.23 2.23 0 0 1 0 4.46H10.38a2.23 2.23 0 0 1 0-4.46Z"/>
      </g>
    </svg>
    <h2>Choose what to sync</h2>
    <p class="muted">Pick a storage bucket and the local folder it mirrors.</p>
    <div class="field">
      <label for="setup-bucket">Bucket</label>
      <select id="setup-bucket"></select>
    </div>
    <div class="field">
      <label for="setup-folder">Local sync folder</label>
      <input id="setup-folder" type="text" spellcheck="false" placeholder="~/AkurAI Drive">
    </div>
    <button id="btn-setup-save" class="btn btn-primary btn-lg">Start syncing</button>
    <button id="btn-setup-signout" class="btn btn-ghost btn-sm">Sign out</button>
  </div>
</section>

<!-- ===== MAIN APP ===== -->
<section id="screen-app" class="screen hidden">
  <!-- top bar -->
  <header class="topbar">
    <div class="topbar-left">
      <svg class="mark" viewBox="0 0 32 32" aria-hidden="true">
        <g fill="url(#gsign)">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M13.38 3.23c1.05-2.23 4.19-2.23 5.24 0l11.05 23.62A2.91 2.91 0 0 1 27.03 31h-3.42c-1.17 0-2.22-.7-2.67-1.78l-2.05-4.93h-5.78l-2.05 4.93A2.9 2.9 0 0 1 8.39 31H4.97a2.91 2.91 0 0 1-2.64-4.15L13.38 3.23ZM16 11.17l-5.13 13.1h10.26L16 11.17Z"/>
          <path d="M10.38 20.54h11.24a2.23 2.23 0 0 1 0 4.46H10.38a2.23 2.23 0 0 1 0-4.46Z"/>
        </g>
      </svg>
      <nav id="breadcrumb" class="breadcrumb" aria-label="path"></nav>
    </div>
    <div class="topbar-center">
      <div class="search">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="1.8"/><path d="m20 20-3.2-3.2" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
        <input id="search" type="text" placeholder="Search this folder">
      </div>
    </div>
    <div class="topbar-right">
      <span id="sync-dot" class="sync-dot idle" title="idle"></span>
      <div class="account">
        <button id="account-btn" class="account-btn" aria-haspopup="true">
          <span id="account-initial" class="avatar">A</span>
        </button>
        <div id="account-menu" class="menu hidden" role="menu">
          <div class="menu-head">
            <div id="account-email" class="menu-email">—</div>
            <div id="account-sub" class="menu-sub muted small">Signed in</div>
          </div>
          <button class="menu-item" data-act="open-folder" role="menuitem">Open folder</button>
          <button class="menu-item" data-act="copy-log" role="menuitem">Copy log path</button>
          <div class="menu-sep"></div>
          <button class="menu-item danger" data-act="signout" role="menuitem">Sign out</button>
        </div>
      </div>
    </div>
  </header>

  <!-- toolbar -->
  <div class="toolbar">
    <div class="toolbar-left">
      <button id="btn-upload" class="btn btn-primary btn-sm">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M12 16V4m0 0L7 9m5-5 5 5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 17v2a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-2" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
        Upload
      </button>
      <button id="btn-mkdir" class="btn btn-ghost btn-sm">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z" stroke="currentColor" stroke-width="1.7"/><path d="M12 11v4m-2-2h4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
        New folder
      </button>
      <button id="btn-sync" class="btn btn-ghost btn-sm">
        <svg viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M4 11a8 8 0 0 1 14-5m2-2v5h-5M20 13a8 8 0 0 1-14 5m-2 2v-5h5" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/></svg>
        Sync now
      </button>
    </div>
    <div class="toolbar-right">
      <select id="sort" class="mini-select" title="Sort">
        <option value="name">Name</option>
        <option value="size">Size</option>
        <option value="modified">Modified</option>
      </select>
      <div class="view-toggle">
        <button id="view-grid" class="vt active" title="Grid"><svg viewBox="0 0 24 24" fill="none"><rect x="3" y="3" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="14" y="3" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="3" y="14" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8"/><rect x="14" y="14" width="7" height="7" rx="1.5" stroke="currentColor" stroke-width="1.8"/></svg></button>
        <button id="view-list" class="vt" title="List"><svg viewBox="0 0 24 24" fill="none"><path d="M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg></button>
      </div>
    </div>
  </div>

  <!-- main browser -->
  <main id="browser" class="browser">
    <div id="state-loading" class="state hidden"><div class="spinner"></div><p>Loading…</p></div>
    <div id="state-empty" class="state hidden">
      <svg viewBox="0 0 24 24" fill="none" class="state-ico"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z" stroke="currentColor" stroke-width="1.6"/></svg>
      <p>This folder is empty</p>
      <span class="muted small">Drag files here or use Upload</span>
    </div>
    <div id="state-error" class="state hidden">
      <svg viewBox="0 0 24 24" fill="none" class="state-ico"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.6"/><path d="M12 7v6m0 3.5h.01" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/></svg>
      <p id="error-text">Something went wrong</p>
      <button class="btn btn-ghost btn-sm" id="btn-retry">Retry</button>
    </div>
    <div id="grid" class="grid"></div>
  </main>

  <!-- drop overlay -->
  <div id="drop-overlay" class="drop-overlay hidden">
    <div class="drop-inner">
      <svg viewBox="0 0 24 24" fill="none"><path d="M12 16V4m0 0L7 9m5-5 5 5" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
      <p>Drop to upload to this folder</p>
    </div>
  </div>
</section>

<!-- context menu -->
<div id="ctx" class="ctx hidden" role="menu">
  <button class="ctx-item" data-act="download" role="menuitem">Download</button>
  <button class="ctx-item" data-act="rename" role="menuitem">Rename</button>
  <button class="ctx-item danger" data-act="delete" role="menuitem">Delete</button>
</div>

<!-- prompt modal -->
<div id="modal" class="modal hidden" role="dialog" aria-modal="true">
  <div class="sheet">
    <h3 id="modal-title">Title</h3>
    <input id="modal-input" type="text" spellcheck="false">
    <div class="modal-actions">
      <button id="modal-cancel" class="btn btn-ghost btn-sm">Cancel</button>
      <button id="modal-ok" class="btn btn-primary btn-sm">OK</button>
    </div>
  </div>
</div>

<!-- toast host -->
<div id="toasts" class="toasts"></div>

<!-- shared gradient def for inline marks -->
<svg width="0" height="0" style="position:absolute"><defs><linearGradient id="gsign" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#5b8cff"/><stop offset="1" stop-color="#7af0d0"/></linearGradient></defs></svg>

<script src="app.js"></script>
</body>
</html>