Просмотр исходного кода

vendor view: sidebar messages, shorter action buttons

Move the vendor schedule's message thread into a sticky sidebar so the
jobs list gets the full page height. Shrink and shorten the Finished/
Shipped/Partial Ship buttons to free up horizontal space in the
action column. Also set synchronous=NORMAL alongside WAL mode in
db.php, which cuts write latency by skipping the fsync on every
commit (still crash-safe against corruption).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bernn 1 месяц назад
Родитель
Сommit
2c229885f1
4 измененных файлов с 68 добавлено и 22 удалено
  1. 41 2
      assets/app.css
  2. 5 0
      lib/db.php
  3. 3 3
      lib/render.php
  4. 19 17
      vendor.php

+ 41 - 2
assets/app.css

@@ -119,9 +119,9 @@ input.inline-edit {
     margin: 0 0.15rem;
 }
 .btn-ack    { background: var(--c-warn); color: #000; }
-.btn-finish { background: var(--c-ok); }
+.btn-finish { background: var(--c-ok); padding: 0.25rem 0.55rem; font-size: 0.8rem; }
 .btn-ship   { background: var(--c-info); }
-.btn-partial{ background: #ff9800; }
+.btn-partial{ background: #ff9800; padding: 0.25rem 0.55rem; font-size: 0.8rem; }
 .btn-undo   { background: #757575; padding: 0.25rem 0.55rem; font-size: 0.8rem; }
 .btn-delete { background: transparent; color: var(--c-danger); border: 1px solid transparent; padding: 0.1rem 0.45rem; font-size: 1.1rem; line-height: 1; }
 .btn-delete:hover { background: var(--c-danger); color: #fff; border-color: var(--c-danger); }
@@ -131,6 +131,45 @@ input.inline-edit {
 .btn:hover  { opacity: 0.9; }
 .received   { color: var(--c-muted); font-style: italic; }
 
+/* ----- vendor view: jobs left, messages sidebar right ----- */
+.vendor-layout {
+    display: flex;
+    align-items: flex-start;
+    gap: 1.5rem;
+}
+.vendor-layout .jobs-wrap {
+    flex: 1 1 auto;
+    min-width: 0;
+    margin-bottom: 0;
+}
+.vendor-layout .thread {
+    flex: 0 0 360px;
+    width: 360px;
+    margin-bottom: 0;
+    position: sticky;
+    top: 1rem;
+    max-height: calc(100vh - 2rem);
+    display: flex;
+    flex-direction: column;
+}
+.vendor-layout .thread-list {
+    flex: 1 1 auto;
+    max-height: none;
+}
+@media (max-width: 900px) {
+    .vendor-layout {
+        flex-direction: column;
+    }
+    .vendor-layout .thread {
+        width: 100%;
+        position: static;
+        max-height: none;
+    }
+    .vendor-layout .thread-list {
+        max-height: 280px;
+    }
+}
+
 /* ----- messages ----- */
 .threads-container {
     display: flex;

+ 5 - 0
lib/db.php

@@ -23,6 +23,11 @@ function db(): PDO {
     $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
     $pdo->exec('PRAGMA foreign_keys = ON');
     $pdo->exec('PRAGMA journal_mode = WAL');
+    // FULL (the default) fsyncs on every commit and checkpoint, which is
+    // slow on this host's storage. NORMAL is the combination SQLite's own
+    // docs recommend with WAL: still crash-safe against corruption, it just
+    // means a hard power-loss/OS-crash could lose the last commit or two.
+    $pdo->exec('PRAGMA synchronous = NORMAL');
 
     db_migrate($pdo);
     return $pdo;

+ 3 - 3
lib/render.php

@@ -146,12 +146,12 @@ function render_actions(array $r, string $audience): string {
             $btns[] = '<button class="btn btn-ack" data-action="acknowledge">Acknowledge</button>';
         }
         if ($r['status'] === '') {
-            $btns[] = '<button class="btn btn-finish" data-action="mark_finished">Mark Finished</button>';
+            $btns[] = '<button class="btn btn-finish" data-action="mark_finished">Fin</button>';
         } elseif ($r['status'] === 'Finished') {
-            $btns[] = '<button class="btn btn-ship" data-action="mark_shipped">Mark Shipped</button>';
+            $btns[] = '<button class="btn btn-ship" data-action="mark_shipped">Shipd</button>';
         }
         if (in_array($r['status'], ['', 'Finished'], true) && (int) $r['qty'] > 1) {
-            $btns[] = '<button class="btn btn-partial" data-action="partial_ship" data-qty="' . (int) $r['qty'] . '">Partial Ship</button>';
+            $btns[] = '<button class="btn btn-partial" data-action="partial_ship" data-qty="' . (int) $r['qty'] . '">Parial</button>';
         }
         if (in_array($r['status'], ['Finished', 'Shipped'], true)) {
             $btns[] = '<button class="btn btn-undo" data-action="undo">Undo</button>';

+ 19 - 17
vendor.php

@@ -22,30 +22,32 @@ window.PDQ = {
 </script>
 <script src="assets/app.js" defer></script>
 </head>
-<body>
+<body class="vendor-page">
 
 <div class="topbar">
     <h1><?= h($vendor['name']) ?>'s Schedule</h1>
     <span class="who">Signed in as <strong><?= h($vendor['name']) ?></strong> &middot; <span id="sync-time">Loading…</span></span>
 </div>
 
-<div class="jobs-wrap">
-    <div id="jobs-table"><?= render_jobs_table('vendor', $vid) ?></div>
-</div>
-
-<section class="thread" data-vendor="<?= h($vendor['slug']) ?>">
-    <h2>Messages with ICG</h2>
-    <div class="thread-list" data-max-id="<?= $maxId ?>">
-        <?php
-        $rendered = render_messages($vid);
-        echo $rendered !== '' ? $rendered : '<div class="msg-empty">No messages yet.</div>';
-        ?>
+<div class="vendor-layout">
+    <div class="jobs-wrap">
+        <div id="jobs-table"><?= render_jobs_table('vendor', $vid) ?></div>
     </div>
-    <form class="thread-compose" autocomplete="off">
-        <input type="text" name="body" placeholder="Message ICG…" maxlength="4000" required>
-        <button type="submit" class="btn btn-post">Post</button>
-    </form>
-</section>
+
+    <section class="thread" data-vendor="<?= h($vendor['slug']) ?>">
+        <h2>Messages with ICG</h2>
+        <div class="thread-list" data-max-id="<?= $maxId ?>">
+            <?php
+            $rendered = render_messages($vid);
+            echo $rendered !== '' ? $rendered : '<div class="msg-empty">No messages yet.</div>';
+            ?>
+        </div>
+        <form class="thread-compose" autocomplete="off">
+            <input type="text" name="body" placeholder="Message ICG…" maxlength="4000" required>
+            <button type="submit" class="btn btn-post">Post</button>
+        </form>
+    </section>
+</div>
 
 </body>
 </html>