Commit Graph

2210 Commits

Author SHA1 Message Date
Riyadh a69eed4710 Transitioned from Plan to Build mode 2026-05-18 07:48:49 +00:00
riyadhafraa c3bbb7fd15 Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 74809c56-8683-4dea-bc60-c40ad9e206f8
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-18 07:48:49 +00:00
Riyadh 1cef84bc23 Disable unwanted default applications and clean up related scripts
Remove `enable-default-apps.ts` script, add `disable-deprecated-apps.ts`, update seeding logic in `seed.ts` to set `isActive` to false for documents, and modify `DOCKER.md` and `scripts/package.json` accordingly.
2026-05-18 07:18:15 +00:00
riyadhafraa 7d65198298 Disable unwanted default applications and clean up related scripts
Remove `enable-default-apps.ts` script, add `disable-deprecated-apps.ts`, update seeding logic in `seed.ts` to set `isActive` to false for documents, and modify `DOCKER.md` and `scripts/package.json` accordingly.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: ac51f801-911b-4be5-b27c-e3212d5c0c73
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-18 07:18:15 +00:00
Riyadh e44c9a8976 Improve handling of notification permission prompts
Update notification permission logic to differentiate between denied and dismissed states, and adjust locale messages accordingly.
2026-05-17 17:21:18 +00:00
riyadhafraa aba984d238 Improve handling of notification permission prompts
Update notification permission logic to differentiate between denied and dismissed states, and adjust locale messages accordingly.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 02bc349c-c9f1-47f4-967c-cfefeabde8bb
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 17:21:18 +00:00
Riyadh bf5bfa29c4 #576: diagnose push enable + open full edit page from quick actions
Three connected fixes on the Executive Meetings schedule.

1) Push enable diagnostics (use-push-subscription.ts):
   - `enable()` now returns { ok, reason } instead of a bare boolean.
   - Reasons: unsupported, unsupported_ios_safari, permission_denied,
     vapid_unavailable, subscribe_failed, server_rejected.
   - Detects iPhone/iPad Safari not running as a PWA (checks
     navigator.standalone + display-mode media query, with iPadOS
     MacIntel + maxTouchPoints fallback) and short-circuits with
     unsupported_ios_safari so the user gets a concrete
     "open from Home Screen first" message instead of a silent fail.
   - Wrapped VAPID fetch and pushManager.subscribe in their own
     try/catches so each failure mode maps to its own reason.

2) Specific failure toasts (push-enable-prompt.tsx,
   notification-settings.tsx):
   - Both call sites now look up
     `notifSettings.push.errors.<reason>` and fall back to the
     legacy generic copy if the key is missing.
   - Added enableSuccess toast on the toggle path too — previously
     only the prompt-card path showed feedback on success.
   - New AR + EN strings under notifSettings.push.errors.*.

3) Quick-actions row sheet (executive-meetings.tsx):
   - Edit + Postpone buttons now sit SIDE BY SIDE on every viewport
     (flex + flex-1 + min-w-0 instead of flex-wrap + min-w-[11rem]),
     same height, equal width — fixes the stacked / over-sized Edit
     button shown in the user's iPhone screenshot.
   - "Edit" no longer opens the small Meeting edit Dialog. It now
     flips the whole schedule into edit mode (same as the toolbar
     pencil) and paints a transient accent ring on the originating
     row (~1.6s) + smooth-scrolls it into view. Matches image 3 in
     #576 where the user expects to see the full editable list.
   - Added `highlightEdit` prop on MeetingRow that composes an
     extra inset+outer ring on top of the existing quickOpen /
     selection / current / press shadows, plus a soft background
     tint, and clears automatically when ScheduleSection clears
     highlightEditRowId.

Out of scope (left for follow-up tasks): server-side push delivery
(payloads/sounds), the edit-mode UI itself.
2026-05-17 17:19:42 +00:00
riyadhafraa 558d395e0c #576: diagnose push enable + open full edit page from quick actions
Three connected fixes on the Executive Meetings schedule.

1) Push enable diagnostics (use-push-subscription.ts):
   - `enable()` now returns { ok, reason } instead of a bare boolean.
   - Reasons: unsupported, unsupported_ios_safari, permission_denied,
     vapid_unavailable, subscribe_failed, server_rejected.
   - Detects iPhone/iPad Safari not running as a PWA (checks
     navigator.standalone + display-mode media query, with iPadOS
     MacIntel + maxTouchPoints fallback) and short-circuits with
     unsupported_ios_safari so the user gets a concrete
     "open from Home Screen first" message instead of a silent fail.
   - Wrapped VAPID fetch and pushManager.subscribe in their own
     try/catches so each failure mode maps to its own reason.

2) Specific failure toasts (push-enable-prompt.tsx,
   notification-settings.tsx):
   - Both call sites now look up
     `notifSettings.push.errors.<reason>` and fall back to the
     legacy generic copy if the key is missing.
   - Added enableSuccess toast on the toggle path too — previously
     only the prompt-card path showed feedback on success.
   - New AR + EN strings under notifSettings.push.errors.*.

3) Quick-actions row sheet (executive-meetings.tsx):
   - Edit + Postpone buttons now sit SIDE BY SIDE on every viewport
     (flex + flex-1 + min-w-0 instead of flex-wrap + min-w-[11rem]),
     same height, equal width — fixes the stacked / over-sized Edit
     button shown in the user's iPhone screenshot.
   - "Edit" no longer opens the small Meeting edit Dialog. It now
     flips the whole schedule into edit mode (same as the toolbar
     pencil) and paints a transient accent ring on the originating
     row (~1.6s) + smooth-scrolls it into view. Matches image 3 in
     #576 where the user expects to see the full editable list.
   - Added `highlightEdit` prop on MeetingRow that composes an
     extra inset+outer ring on top of the existing quickOpen /
     selection / current / press shadows, plus a soft background
     tint, and clears automatically when ScheduleSection clears
     highlightEditRowId.

Out of scope (left for follow-up tasks): server-side push delivery
(payloads/sounds), the edit-mode UI itself.
2026-05-17 17:19:42 +00:00
Riyadh 160c76b2ce Transitioned from Plan to Build mode 2026-05-17 17:16:07 +00:00
riyadhafraa 18b6fb8f7d Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: abb45327-8b86-4838-8f67-8f89ae154fb8
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 17:16:07 +00:00
Riyadh 81acbc2710 #575: IT-P brand icon + login hero image
Replace generic PWA/favicon assets with the IT-P brand image and layer
the same image over the login page's AnimatedArt panel.

- Generated icon-192/512, maskable-512, and apple-touch-icon (180) from
  the attached IT-P photo via ImageMagick (center crop 1110x1110, then
  resize). Maskable has #0B1E3F padding so the safe zone is respected
  on Android adaptive icons.
- Copied source as public/brand-itp.jpg for the login hero.
- index.html: replaced the generic favicon.svg link with a full
  favicon set built from IT-P (favicon.ico + 16/32/48/192/512 PNG),
  all cache-busted with ?v=itp1. Deleted public/favicon.svg so no
  browser can fall back to the old generic mark.
- Cache-busted apple-touch-icon link the same way so iPad PWA
  re-installs pick up the new artwork.
- manifest.webmanifest: same ?v=itp1 cache-bust on all icon entries.
- login.tsx: layered IT-P image over AnimatedArt with mix-blend-screen
  (opacity 90%) plus top/bottom and right-edge dark gradients so the
  composition reads as one piece and the right edge fades cleanly into
  the form panel. Still hidden on < lg per scope.

Did not change favicon.svg itself (kept as last-resort vector
fallback). Mobile (< lg) shows no hero — explicit choice per plan
("إخفاؤها بشكل مدروس").
2026-05-17 16:09:24 +00:00
riyadhafraa 039e251c6a #575: IT-P brand icon + login hero image
Replace generic PWA/favicon assets with the IT-P brand image and layer
the same image over the login page's AnimatedArt panel.

- Generated icon-192/512, maskable-512, and apple-touch-icon (180) from
  the attached IT-P photo via ImageMagick (center crop 1110x1110, then
  resize). Maskable has #0B1E3F padding so the safe zone is respected
  on Android adaptive icons.
- Copied source as public/brand-itp.jpg for the login hero.
- index.html: replaced the generic favicon.svg link with a full
  favicon set built from IT-P (favicon.ico + 16/32/48/192/512 PNG),
  all cache-busted with ?v=itp1. Deleted public/favicon.svg so no
  browser can fall back to the old generic mark.
- Cache-busted apple-touch-icon link the same way so iPad PWA
  re-installs pick up the new artwork.
- manifest.webmanifest: same ?v=itp1 cache-bust on all icon entries.
- login.tsx: layered IT-P image over AnimatedArt with mix-blend-screen
  (opacity 90%) plus top/bottom and right-edge dark gradients so the
  composition reads as one piece and the right edge fades cleanly into
  the form panel. Still hidden on < lg per scope.

Did not change favicon.svg itself (kept as last-resort vector
fallback). Mobile (< lg) shows no hero — explicit choice per plan
("إخفاؤها بشكل مدروس").
2026-05-17 16:09:24 +00:00
Riyadh 425e09a20d #575: IT-P brand icon + login hero image
Replace generic PWA/favicon assets with the IT-P brand image and layer
the same image over the login page's AnimatedArt panel.

- Generated icon-192/512, maskable-512, and apple-touch-icon (180) from
  the attached IT-P photo via ImageMagick (center crop 1110x1110, then
  resize). Maskable has #0B1E3F padding so the safe zone is respected
  on Android adaptive icons.
- Copied source as public/brand-itp.jpg for the login hero.
- index.html: added explicit PNG icon links (192, 512) before the
  existing favicon.svg fallback, plus cache-bust query (?v=itp1) on
  apple-touch-icon so iPad PWA re-installs pick up the new artwork.
- manifest.webmanifest: same ?v=itp1 cache-bust on all icon entries.
- login.tsx: layered IT-P image over AnimatedArt with mix-blend-screen
  (opacity 90%) plus top/bottom and right-edge dark gradients so the
  composition reads as one piece and the right edge fades cleanly into
  the form panel. Still hidden on < lg per scope.

Did not change favicon.svg itself (kept as last-resort vector
fallback). Mobile (< lg) shows no hero — explicit choice per plan
("إخفاؤها بشكل مدروس").
2026-05-17 16:08:28 +00:00
riyadhafraa 192f412f2a #575: IT-P brand icon + login hero image
Replace generic PWA/favicon assets with the IT-P brand image and layer
the same image over the login page's AnimatedArt panel.

- Generated icon-192/512, maskable-512, and apple-touch-icon (180) from
  the attached IT-P photo via ImageMagick (center crop 1110x1110, then
  resize). Maskable has #0B1E3F padding so the safe zone is respected
  on Android adaptive icons.
- Copied source as public/brand-itp.jpg for the login hero.
- index.html: added explicit PNG icon links (192, 512) before the
  existing favicon.svg fallback, plus cache-bust query (?v=itp1) on
  apple-touch-icon so iPad PWA re-installs pick up the new artwork.
- manifest.webmanifest: same ?v=itp1 cache-bust on all icon entries.
- login.tsx: layered IT-P image over AnimatedArt with mix-blend-screen
  (opacity 90%) plus top/bottom and right-edge dark gradients so the
  composition reads as one piece and the right edge fades cleanly into
  the form panel. Still hidden on < lg per scope.

Did not change favicon.svg itself (kept as last-resort vector
fallback). Mobile (< lg) shows no hero — explicit choice per plan
("إخفاؤها بشكل مدروس").
2026-05-17 16:08:28 +00:00
Riyadh dd2259777f Transitioned from Plan to Build mode 2026-05-17 16:07:02 +00:00
riyadhafraa 56335c73ec Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 333e3e6c-f47d-4a12-94e6-39f2ada21f94
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 16:07:02 +00:00
Riyadh 3d06ceef4d Show the notifications app on the main page again
Remove hardcoded exclusion for the notifications app in the home page component.
2026-05-17 15:42:29 +00:00
riyadhafraa 2f591a6ba8 Show the notifications app on the main page again
Remove hardcoded exclusion for the notifications app in the home page component.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 58af0916-ab79-457c-868e-3b72336f6067
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 15:42:29 +00:00
Riyadh 61701b422c Enable calendar and notification apps by default
Add a new script to enable the calendar and notification applications by default, along with documentation updates.
2026-05-17 15:19:51 +00:00
riyadhafraa bc7938e002 Enable calendar and notification apps by default
Add a new script to enable the calendar and notification applications by default, along with documentation updates.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 1fea5b6b-097a-4339-854f-f1a5d338a14c
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 15:19:51 +00:00
Riyadh cb894f7baa Add automatic build version generation from git
Implement a script to automatically generate build version information from git commit hash and date, updating version.json and creating latest.json.
2026-05-17 15:16:02 +00:00
riyadhafraa 80429920b9 Add automatic build version generation from git
Implement a script to automatically generate build version information from git commit hash and date, updating version.json and creating latest.json.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: ab5429c1-7925-4a30-a964-b3db9c5772da
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 15:16:02 +00:00
Riyadh 8a5bd5db51 Add system updates page to admin section
Add a new API endpoint and UI section for checking system updates, including internationalized locale strings and necessary dependency updates.
2026-05-17 14:59:36 +00:00
riyadhafraa b5efd9eb12 Add system updates page to admin section
Add a new API endpoint and UI section for checking system updates, including internationalized locale strings and necessary dependency updates.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 1e6de894-7c78-4557-b01a-a2c1c01f4155
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
2026-05-17 14:59:36 +00:00
Riyadh 0e423a047f #571: ship Calendar/Notifications disabled by default + drop Notifications tile from home
Task: on fresh installs the Calendar and Notifications apps were
appearing enabled by default, and the home screen showed a
Notifications tile that was redundant with the bell icon already in
the top bar. User wanted both apps disabled by default and the home
tile gone (bell stays).

Changes:
- scripts/src/seed.ts: flip the seed `isActive` for `notifications`
  and `calendar` from true → false. The seed inserts apps with
  `db.insert(appsTable).values(apps).onConflictDoNothing()`, so this
  is fully idempotent: existing environments (where the row already
  exists with isActive=true) are NOT changed; only fresh inserts on
  new installs pick up the disabled default. Admins can enable
  either app from app settings when they want it.
- artifacts/tx-os/src/pages/home.tsx: remove "notifications" from
  the `dockApps` filter so the bottom dock no longer renders a
  Notifications tile. Filter becomes `["services", "admin"]`. The
  top-bar bell icon (and its unread badge) was untouched and still
  routes to `/notifications`.

Out of scope (per spec): no migration to disable existing prod
rows; no role/permission changes; bell icon in the top bar stays.

Files:
- scripts/src/seed.ts (notifications block ~L229, calendar block ~L275)
- artifacts/tx-os/src/pages/home.tsx:532
2026-05-17 14:43:54 +00:00
riyadhafraa 191e072353 #571: ship Calendar/Notifications disabled by default + drop Notifications tile from home
Task: on fresh installs the Calendar and Notifications apps were
appearing enabled by default, and the home screen showed a
Notifications tile that was redundant with the bell icon already in
the top bar. User wanted both apps disabled by default and the home
tile gone (bell stays).

Changes:
- scripts/src/seed.ts: flip the seed `isActive` for `notifications`
  and `calendar` from true → false. The seed inserts apps with
  `db.insert(appsTable).values(apps).onConflictDoNothing()`, so this
  is fully idempotent: existing environments (where the row already
  exists with isActive=true) are NOT changed; only fresh inserts on
  new installs pick up the disabled default. Admins can enable
  either app from app settings when they want it.
- artifacts/tx-os/src/pages/home.tsx: remove "notifications" from
  the `dockApps` filter so the bottom dock no longer renders a
  Notifications tile. Filter becomes `["services", "admin"]`. The
  top-bar bell icon (and its unread badge) was untouched and still
  routes to `/notifications`.

Out of scope (per spec): no migration to disable existing prod
rows; no role/permission changes; bell icon in the top bar stays.

Files:
- scripts/src/seed.ts (notifications block ~L229, calendar block ~L275)
- artifacts/tx-os/src/pages/home.tsx:532
2026-05-17 14:43:54 +00:00
Riyadh 8a629007e8 #571: ship Calendar/Notifications disabled by default + drop Notifications tile from home
Task: on fresh installs the Calendar and Notifications apps were
appearing enabled by default, and the home screen showed a
Notifications tile that was redundant with the bell icon already in
the top bar. User wanted both apps disabled by default and the home
tile gone (bell stays).

Changes:
- scripts/src/seed.ts: flip the seed `isActive` for `notifications`
  and `calendar` from true → false. The seed inserts apps with
  `db.insert(appsTable).values(apps).onConflictDoNothing()`, so this
  is fully idempotent: existing environments (where the row already
  exists with isActive=true) are NOT changed; only fresh inserts on
  new installs pick up the disabled default. Admins can enable
  either app from app settings when they want it.
- artifacts/tx-os/src/pages/home.tsx: remove "notifications" from
  the `dockApps` filter so the bottom dock no longer renders a
  Notifications tile. Filter becomes `["services", "admin"]`. The
  top-bar bell icon (and its unread badge) was untouched and still
  routes to `/notifications`.

Out of scope (per spec): no migration to disable existing prod
rows; no role/permission changes; bell icon in the top bar stays.

Files:
- scripts/src/seed.ts (notifications block ~L229, calendar block ~L275)
- artifacts/tx-os/src/pages/home.tsx:532
2026-05-17 14:42:48 +00:00
riyadhafraa 2aa4a12ddc #571: ship Calendar/Notifications disabled by default + drop Notifications tile from home
Task: on fresh installs the Calendar and Notifications apps were
appearing enabled by default, and the home screen showed a
Notifications tile that was redundant with the bell icon already in
the top bar. User wanted both apps disabled by default and the home
tile gone (bell stays).

Changes:
- scripts/src/seed.ts: flip the seed `isActive` for `notifications`
  and `calendar` from true → false. The seed inserts apps with
  `db.insert(appsTable).values(apps).onConflictDoNothing()`, so this
  is fully idempotent: existing environments (where the row already
  exists with isActive=true) are NOT changed; only fresh inserts on
  new installs pick up the disabled default. Admins can enable
  either app from app settings when they want it.
- artifacts/tx-os/src/pages/home.tsx: remove "notifications" from
  the `dockApps` filter so the bottom dock no longer renders a
  Notifications tile. Filter becomes `["services", "admin"]`. The
  top-bar bell icon (and its unread badge) was untouched and still
  routes to `/notifications`.

Out of scope (per spec): no migration to disable existing prod
rows; no role/permission changes; bell icon in the top bar stays.

Files:
- scripts/src/seed.ts (notifications block ~L229, calendar block ~L275)
- artifacts/tx-os/src/pages/home.tsx:532
2026-05-17 14:42:48 +00:00
Riyadh e79a8dee41 #570: stronger selected-row highlight + Edit button in Quick Actions
Task: on iPad the bulk-selected row was nearly invisible (only a 2px
inset navy ring), and the row-tap Quick Actions dialog had only a
Postpone button — user asked for a real visible selection fill and
an Edit (pencil) action wired to the existing edit-meeting flow.

Changes (artifacts/tx-os/src/pages/executive-meetings.tsx):
- MeetingRow: add `selectionBg = rgba(11,30,63,0.18)` painted on the
  row's `<tr>` backgroundColor in addition to the existing
  `selectionShadow` 2px navy ring. Composition order in trStyle is
  `quickOpenBg ?? selectionBg ?? baseBg` so an open quick-actions
  surface still wins (transient action state), user-picked row
  colours still show when nothing is selected, and the navy tint
  reads clearly on iPad against the table grid.
- MeetingRow: new optional `onQuickEdit?: () => void` prop. Quick
  Actions Dialog gains a pencil-icon "Edit" button before the
  existing Postpone button, wrapped in `flex flex-wrap gap-2` so the
  two buttons sit side-by-side on iPad/desktop and stack on narrow
  viewports. Button only renders when a handler is wired
  (defensive — `quickActionsCanMutate` already gates the surface).
- ScheduleSection: host a local `editingMeeting` + `editingSaving`
  state plus a `MeetingFormDialog` mount, with a save handler whose
  body mirrors ManageSection's `save()` exactly (same PATCH payload
  projection, same `wrapAsParagraph` / attendee shaping, same
  toast/error translation). Edit button on a row opens this in-place
  dialog instead of switching the user to the Manage tab.
- Locale: add `executiveMeetings.quickActions.edit` = "تعديل" / "Edit".

Notes:
- No new icon import needed — `Pencil` was already in the lucide
  import group.
- Selection ring (`#0B1E3F`) and tint use the same navy so they
  read as one cohesive selected state, not competing layers.
- Pre-existing `use-push-subscription.ts` TS noise unchanged.
2026-05-17 14:40:34 +00:00
riyadhafraa c40384b0d9 #570: stronger selected-row highlight + Edit button in Quick Actions
Task: on iPad the bulk-selected row was nearly invisible (only a 2px
inset navy ring), and the row-tap Quick Actions dialog had only a
Postpone button — user asked for a real visible selection fill and
an Edit (pencil) action wired to the existing edit-meeting flow.

Changes (artifacts/tx-os/src/pages/executive-meetings.tsx):
- MeetingRow: add `selectionBg = rgba(11,30,63,0.18)` painted on the
  row's `<tr>` backgroundColor in addition to the existing
  `selectionShadow` 2px navy ring. Composition order in trStyle is
  `quickOpenBg ?? selectionBg ?? baseBg` so an open quick-actions
  surface still wins (transient action state), user-picked row
  colours still show when nothing is selected, and the navy tint
  reads clearly on iPad against the table grid.
- MeetingRow: new optional `onQuickEdit?: () => void` prop. Quick
  Actions Dialog gains a pencil-icon "Edit" button before the
  existing Postpone button, wrapped in `flex flex-wrap gap-2` so the
  two buttons sit side-by-side on iPad/desktop and stack on narrow
  viewports. Button only renders when a handler is wired
  (defensive — `quickActionsCanMutate` already gates the surface).
- ScheduleSection: host a local `editingMeeting` + `editingSaving`
  state plus a `MeetingFormDialog` mount, with a save handler whose
  body mirrors ManageSection's `save()` exactly (same PATCH payload
  projection, same `wrapAsParagraph` / attendee shaping, same
  toast/error translation). Edit button on a row opens this in-place
  dialog instead of switching the user to the Manage tab.
- Locale: add `executiveMeetings.quickActions.edit` = "تعديل" / "Edit".

Notes:
- No new icon import needed — `Pencil` was already in the lucide
  import group.
- Selection ring (`#0B1E3F`) and tint use the same navy so they
  read as one cohesive selected state, not competing layers.
- Pre-existing `use-push-subscription.ts` TS noise unchanged.
2026-05-17 14:40:34 +00:00
Riyadh ca77ad1790 Hide redundant clock and navigation elements for president view
Modify executive-meetings.tsx to conditionally hide the HeaderClock and section navigation when isPresidentView is true.
2026-05-17 14:34:59 +00:00
riyadhafraa dc30d75e11 Hide redundant clock and navigation elements for president view
Modify executive-meetings.tsx to conditionally hide the HeaderClock and section navigation when isPresidentView is true.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: e1c6509c-638c-4c43-8d4f-4b4a5910fc4a
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/fNoqq4C
Replit-Helium-Checkpoint-Created: true
2026-05-17 14:34:59 +00:00
Riyadh ae3e17a97e #572 president-only focused view for executive meetings
User asked that when the President (`executive_ceo` role) logs into
the Meetings page he sees a clean "presentation" layout: just the
schedule table, an analog clock plus the weekday/date of the
schedule, and nothing else. The Manage / Notifications / Audit /
PDF tabs and the PDF-export shortcut button are noisy for him and
must disappear — but his backend permissions stay intact.

Changes (frontend only — backend role gates untouched):
- New component `components/executive-meetings/analog-clock.tsx`:
  small SVG analog clock (hour/minute/second hands, navy + gold),
  ticks every second, ~44px default.
- New inner `PresidentClockBar` component in `executive-meetings.tsx`:
  renders the analog clock + weekday + **digital time** (ticking
  per second, localized) + selected schedule date in one block.
- `pages/executive-meetings.tsx`:
  - Derived `isPresidentView` from the `/me` roles: true iff
    `executive_ceo` is present AND the user is NOT also `admin`
    or `executive_office_manager` (admins keep full UI).
  - Effect forces `section = "schedule"` whenever
    `isPresidentView` becomes true, so the president can never
    land on a now-hidden tab.
  - Hides the header PDF-shortcut button and the entire SECTIONS
    tab list when `isPresidentView`. The `#em-toolbar-portal` is
    kept so the date picker still mounts.
  - `ScheduleSection` accepts two new optional props:
    `isPresidentView` and `lang`. When `isPresidentView` is on,
    the toolbar renders the AnalogClock next to a label showing
    `formatWeekday(date, lang, "long")` and `formatDate(date, lang)`
    (e.g. "Sunday · May 17, 2026" / "الأحد · 17 مايو 2026"). The
    label updates immediately when the date input changes.
  - Edit-mode toggle stays gated on `canMutate`, so the president
    (who has canMutate) still gets the inline-edit pencil if he
    wants it.

Out of scope: backend role changes, applying the focused view to
other roles, manual presentation-mode toggle. Verified via tsc
(only the pre-existing `use-push-subscription` error remains).
2026-05-17 14:34:12 +00:00
riyadhafraa 21dda3d372 #572 president-only focused view for executive meetings
User asked that when the President (`executive_ceo` role) logs into
the Meetings page he sees a clean "presentation" layout: just the
schedule table, an analog clock plus the weekday/date of the
schedule, and nothing else. The Manage / Notifications / Audit /
PDF tabs and the PDF-export shortcut button are noisy for him and
must disappear — but his backend permissions stay intact.

Changes (frontend only — backend role gates untouched):
- New component `components/executive-meetings/analog-clock.tsx`:
  small SVG analog clock (hour/minute/second hands, navy + gold),
  ticks every second, ~44px default.
- New inner `PresidentClockBar` component in `executive-meetings.tsx`:
  renders the analog clock + weekday + **digital time** (ticking
  per second, localized) + selected schedule date in one block.
- `pages/executive-meetings.tsx`:
  - Derived `isPresidentView` from the `/me` roles: true iff
    `executive_ceo` is present AND the user is NOT also `admin`
    or `executive_office_manager` (admins keep full UI).
  - Effect forces `section = "schedule"` whenever
    `isPresidentView` becomes true, so the president can never
    land on a now-hidden tab.
  - Hides the header PDF-shortcut button and the entire SECTIONS
    tab list when `isPresidentView`. The `#em-toolbar-portal` is
    kept so the date picker still mounts.
  - `ScheduleSection` accepts two new optional props:
    `isPresidentView` and `lang`. When `isPresidentView` is on,
    the toolbar renders the AnalogClock next to a label showing
    `formatWeekday(date, lang, "long")` and `formatDate(date, lang)`
    (e.g. "Sunday · May 17, 2026" / "الأحد · 17 مايو 2026"). The
    label updates immediately when the date input changes.
  - Edit-mode toggle stays gated on `canMutate`, so the president
    (who has canMutate) still gets the inline-edit pencil if he
    wants it.

Out of scope: backend role changes, applying the focused view to
other roles, manual presentation-mode toggle. Verified via tsc
(only the pre-existing `use-push-subscription` error remains).
2026-05-17 14:34:12 +00:00
Riyadh b52c54eefe #572 president-only focused view for executive meetings
User asked that when the President (`executive_ceo` role) logs into
the Meetings page he sees a clean "presentation" layout: just the
schedule table, an analog clock plus the weekday/date of the
schedule, and nothing else. The Manage / Notifications / Audit /
PDF tabs and the PDF-export shortcut button are noisy for him and
must disappear — but his backend permissions stay intact.

Changes (frontend only — backend role gates untouched):
- New component `components/executive-meetings/analog-clock.tsx`:
  small SVG analog clock (hour/minute/second hands, navy + gold),
  ticks every second, ~44px default.
- `pages/executive-meetings.tsx`:
  - Derived `isPresidentView` from the `/me` roles: true iff
    `executive_ceo` is present AND the user is NOT also `admin`
    or `executive_office_manager` (admins keep full UI).
  - Effect forces `section = "schedule"` whenever
    `isPresidentView` becomes true, so the president can never
    land on a now-hidden tab.
  - Hides the header PDF-shortcut button and the entire SECTIONS
    tab list when `isPresidentView`. The `#em-toolbar-portal` is
    kept so the date picker still mounts.
  - `ScheduleSection` accepts two new optional props:
    `isPresidentView` and `lang`. When `isPresidentView` is on,
    the toolbar renders the AnalogClock next to a label showing
    `formatWeekday(date, lang, "long")` and `formatDate(date, lang)`
    (e.g. "Sunday · May 17, 2026" / "الأحد · 17 مايو 2026"). The
    label updates immediately when the date input changes.
  - Edit-mode toggle stays gated on `canMutate`, so the president
    (who has canMutate) still gets the inline-edit pencil if he
    wants it.

Out of scope: backend role changes, applying the focused view to
other roles, manual presentation-mode toggle. Verified via tsc
(only the pre-existing `use-push-subscription` error remains).
2026-05-17 14:32:19 +00:00
riyadhafraa 27384d019a #572 president-only focused view for executive meetings
User asked that when the President (`executive_ceo` role) logs into
the Meetings page he sees a clean "presentation" layout: just the
schedule table, an analog clock plus the weekday/date of the
schedule, and nothing else. The Manage / Notifications / Audit /
PDF tabs and the PDF-export shortcut button are noisy for him and
must disappear — but his backend permissions stay intact.

Changes (frontend only — backend role gates untouched):
- New component `components/executive-meetings/analog-clock.tsx`:
  small SVG analog clock (hour/minute/second hands, navy + gold),
  ticks every second, ~44px default.
- `pages/executive-meetings.tsx`:
  - Derived `isPresidentView` from the `/me` roles: true iff
    `executive_ceo` is present AND the user is NOT also `admin`
    or `executive_office_manager` (admins keep full UI).
  - Effect forces `section = "schedule"` whenever
    `isPresidentView` becomes true, so the president can never
    land on a now-hidden tab.
  - Hides the header PDF-shortcut button and the entire SECTIONS
    tab list when `isPresidentView`. The `#em-toolbar-portal` is
    kept so the date picker still mounts.
  - `ScheduleSection` accepts two new optional props:
    `isPresidentView` and `lang`. When `isPresidentView` is on,
    the toolbar renders the AnalogClock next to a label showing
    `formatWeekday(date, lang, "long")` and `formatDate(date, lang)`
    (e.g. "Sunday · May 17, 2026" / "الأحد · 17 مايو 2026"). The
    label updates immediately when the date input changes.
  - Edit-mode toggle stays gated on `canMutate`, so the president
    (who has canMutate) still gets the inline-edit pencil if he
    wants it.

Out of scope: backend role changes, applying the focused view to
other roles, manual presentation-mode toggle. Verified via tsc
(only the pre-existing `use-push-subscription` error remains).
2026-05-17 14:32:19 +00:00
Riyadh 1b88991746 Transitioned from Plan to Build mode 2026-05-17 14:30:14 +00:00
riyadhafraa d002670e4e Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: e893067e-041e-43bd-ab08-84a6e721b22f
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/fNoqq4C
Replit-Helium-Checkpoint-Created: true
2026-05-17 14:30:14 +00:00
Riyadh 46414ec4bd #568 silent delete for finished orders
User requested that deleting a finished order from My Orders happen
silently — one click on the trash icon, no confirmation dialog, no
success toast. Just click and the card disappears.

Changes:
- Removed the delete-confirm AlertDialog from OrderCard along with
  its `confirmDeleteOpen` state. The trash icon now calls
  `handleDelete` directly.
- Removed `toast({ title: t("myOrders.deleted") })` from
  `scheduleDelete`. The 7-second soft-delete grace window stays in
  place (pendingDeleteIds filter + setTimeout) so the API DELETE
  still fires after the window. The `deleteFailed` error toast is
  preserved so silent API failures don't lose orders.
- Dropped the now-unused locale keys from ar.json and en.json:
  `deleteConfirmTitle`, `deleteConfirmBody`, `deleteConfirm`,
  `deleted`.
- Removed the unused `AlertDialogDescription` import (the remaining
  cancel-confirm dialog uses only the title).

Cancel-order flow remains untouched (still shows confirm dialog and
undo toast as in #566).
2026-05-17 14:13:42 +00:00
riyadhafraa 4b151c50a8 #568 silent delete for finished orders
User requested that deleting a finished order from My Orders happen
silently — one click on the trash icon, no confirmation dialog, no
success toast. Just click and the card disappears.

Changes:
- Removed the delete-confirm AlertDialog from OrderCard along with
  its `confirmDeleteOpen` state. The trash icon now calls
  `handleDelete` directly.
- Removed `toast({ title: t("myOrders.deleted") })` from
  `scheduleDelete`. The 7-second soft-delete grace window stays in
  place (pendingDeleteIds filter + setTimeout) so the API DELETE
  still fires after the window. The `deleteFailed` error toast is
  preserved so silent API failures don't lose orders.
- Dropped the now-unused locale keys from ar.json and en.json:
  `deleteConfirmTitle`, `deleteConfirmBody`, `deleteConfirm`,
  `deleted`.
- Removed the unused `AlertDialogDescription` import (the remaining
  cancel-confirm dialog uses only the title).

Cancel-order flow remains untouched (still shows confirm dialog and
undo toast as in #566).
2026-05-17 14:13:42 +00:00
Riyadh e487c879f0 Transitioned from Plan to Build mode 2026-05-17 14:12:17 +00:00
riyadhafraa d64a035cc3 Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 8a46f213-adbc-4743-8448-2dfa8e134a76
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/fNoqq4C
Replit-Helium-Checkpoint-Created: true
2026-05-17 14:12:17 +00:00
Riyadh 54dc04f12d #566 clean up My Orders page (3 removals)
Per user request on the طلباتي page:

1. Removed the "Clear finished orders" bulk button entirely. The button
   was showing as a raw i18n key (myOrder c...) for the user and they
   asked for it gone. Dropped the related AlertDialog, confirmClearOpen
   state, handleClearFinished handler, and the locale keys
   clearFinished_*, clearConfirmTitle/Body_*, clearConfirm,
   clearedCount_*, and clearedPartial in both ar.json and en.json.

2. Removed the "تراجع / Undo" ToastAction shown after deleting an
   order. The toast now displays only the "Order deleted" title; the
   7-second timer + pendingDeleteIds soft-delete window is preserved
   so the actual DELETE still fires after the grace period. The undo
   closure was deleted since nothing references it anymore. Single-id
   call site stays untouched (scheduleDelete still receives [id]).

3. Removed the "ستتاح لك ثوانٍ قليلة للتراجع" description from the
   cancel-order confirmation dialog. The cancelConfirmBody key was
   dropped from both locales. The AlertDialog now shows only the
   title + the two action buttons.

Out of scope (kept as-is):
- The undo ToastAction after CANCEL (user only asked about delete).
- Incoming-orders page.

Notes:
- ToastAction import is still used by the cancel-undo path.
- Trash2 import still used by the per-card delete button.
- Pre-existing TS error in use-push-subscription.ts is unrelated.
2026-05-17 14:07:23 +00:00
riyadhafraa 4c57c58f8c #566 clean up My Orders page (3 removals)
Per user request on the طلباتي page:

1. Removed the "Clear finished orders" bulk button entirely. The button
   was showing as a raw i18n key (myOrder c...) for the user and they
   asked for it gone. Dropped the related AlertDialog, confirmClearOpen
   state, handleClearFinished handler, and the locale keys
   clearFinished_*, clearConfirmTitle/Body_*, clearConfirm,
   clearedCount_*, and clearedPartial in both ar.json and en.json.

2. Removed the "تراجع / Undo" ToastAction shown after deleting an
   order. The toast now displays only the "Order deleted" title; the
   7-second timer + pendingDeleteIds soft-delete window is preserved
   so the actual DELETE still fires after the grace period. The undo
   closure was deleted since nothing references it anymore. Single-id
   call site stays untouched (scheduleDelete still receives [id]).

3. Removed the "ستتاح لك ثوانٍ قليلة للتراجع" description from the
   cancel-order confirmation dialog. The cancelConfirmBody key was
   dropped from both locales. The AlertDialog now shows only the
   title + the two action buttons.

Out of scope (kept as-is):
- The undo ToastAction after CANCEL (user only asked about delete).
- Incoming-orders page.

Notes:
- ToastAction import is still used by the cancel-undo path.
- Trash2 import still used by the per-card delete button.
- Pre-existing TS error in use-push-subscription.ts is unrelated.
2026-05-17 14:07:23 +00:00
Riyadh 367daa444b Transitioned from Plan to Build mode 2026-05-17 14:05:04 +00:00
riyadhafraa c3e42fd73e Transitioned from Plan to Build mode
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: b23cd3bb-c384-46bc-ba75-e5b7d4b6af8c
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/fNoqq4C
Replit-Helium-Checkpoint-Created: true
2026-05-17 14:05:04 +00:00
Riyadh 203312abe4 fix(executive-meetings): quick-actions UX + reschedule/cancel polish (Task #563)
User-reported polish on the executive-meetings quick-actions flow on
iPad/mobile. Six fixes, all client-side:

1. Quick-actions surface now opens from ANY click on a meeting row
   (was: only the attendees cell). Root cause: handleRowClick guard
   skipped any `em-edit-*`, `em-merge-edit-*`, and `em-time-*`
   descendants. Those affordances only do anything in edit mode, but
   handleRowClick already early-returns when edit mode is on, so the
   testid guard was always over-aggressive. Dropped those guards plus
   the `[role='button']` rule from the interactive selector, kept the
   real `button`/`input`/`textarea`/`a`/`menuitem`/`checkbox`/etc.
   guards and the `em-row-actions-*` / `em-row-select-*` testid
   guards (those affordances are visible outside edit mode and must
   not trigger the surface).
   File: artifacts/tx-os/src/pages/executive-meetings.tsx (~L4350).

2. Originating row is now unmistakable on iPad: quickOpenShadow is
   `inset 0 0 0 4px highlight, 0 0 0 2px highlight` (was a single
   3px inset) and the row background tints to
   `rgba(highlight, 0.08)` while quick-actions is open.
   File: artifacts/tx-os/src/pages/executive-meetings.tsx
   (~L4287, L4344).

3. Postpone dialog header was overlapping the Radix close X in RTL.
   Added `pr-8` on the DialogHeader (same pattern already used for
   the row-quick mini-dialog).
   File: artifacts/tx-os/src/components/executive-meetings/
   upcoming-meeting-alert.tsx (~L1447).

4. Reschedule tab: date / start / end inputs collided on iPad
   portrait. Grid is now `grid-cols-1 md:grid-cols-3` (single column
   through iPad portrait, three across on landscape/desktop), with
   `min-w-0` on each cell and `w-full` on every Input so Safari's
   native date/time pickers stop overflowing.
   Same file (~L1761).

5. Cancel tab X overlap is resolved by the same DialogHeader fix in
   step 3 (one Dialog wraps all three tabs).

6. Removed the `cancelHint` paragraph + the `cancelHint` translation
   keys in ar.json (L1252) and en.json (L1164) — fully unused now.

NOT pushed to Gitea (Tailscale to desktop-11cj93j still flaky).
Pending pushes: #560 (VAPID), #561 (CEO roles), #563 (this).
2026-05-17 10:19:16 +00:00
riyadhafraa 4e5bed602e fix(executive-meetings): quick-actions UX + reschedule/cancel polish (Task #563)
User-reported polish on the executive-meetings quick-actions flow on
iPad/mobile. Six fixes, all client-side:

1. Quick-actions surface now opens from ANY click on a meeting row
   (was: only the attendees cell). Root cause: handleRowClick guard
   skipped any `em-edit-*`, `em-merge-edit-*`, and `em-time-*`
   descendants. Those affordances only do anything in edit mode, but
   handleRowClick already early-returns when edit mode is on, so the
   testid guard was always over-aggressive. Dropped those guards plus
   the `[role='button']` rule from the interactive selector, kept the
   real `button`/`input`/`textarea`/`a`/`menuitem`/`checkbox`/etc.
   guards and the `em-row-actions-*` / `em-row-select-*` testid
   guards (those affordances are visible outside edit mode and must
   not trigger the surface).
   File: artifacts/tx-os/src/pages/executive-meetings.tsx (~L4350).

2. Originating row is now unmistakable on iPad: quickOpenShadow is
   `inset 0 0 0 4px highlight, 0 0 0 2px highlight` (was a single
   3px inset) and the row background tints to
   `rgba(highlight, 0.08)` while quick-actions is open.
   File: artifacts/tx-os/src/pages/executive-meetings.tsx
   (~L4287, L4344).

3. Postpone dialog header was overlapping the Radix close X in RTL.
   Added `pr-8` on the DialogHeader (same pattern already used for
   the row-quick mini-dialog).
   File: artifacts/tx-os/src/components/executive-meetings/
   upcoming-meeting-alert.tsx (~L1447).

4. Reschedule tab: date / start / end inputs collided on iPad
   portrait. Grid is now `grid-cols-1 md:grid-cols-3` (single column
   through iPad portrait, three across on landscape/desktop), with
   `min-w-0` on each cell and `w-full` on every Input so Safari's
   native date/time pickers stop overflowing.
   Same file (~L1761).

5. Cancel tab X overlap is resolved by the same DialogHeader fix in
   step 3 (one Dialog wraps all three tabs).

6. Removed the `cancelHint` paragraph + the `cancelHint` translation
   keys in ar.json (L1252) and en.json (L1164) — fully unused now.

NOT pushed to Gitea (Tailscale to desktop-11cj93j still flaky).
Pending pushes: #560 (VAPID), #561 (CEO roles), #563 (this).
2026-05-17 10:19:16 +00:00
Riyadh 55d6e65456 fix(executive-meetings): quick-actions UX + reschedule/cancel polish (Task #563)
User-reported polish on the executive-meetings quick-actions flow on
iPad/mobile. Six fixes, all client-side:

1. Quick-actions surface now opens from ANY click on a meeting row
   (was: only the attendees cell). Root cause: handleRowClick guard
   skipped any `em-edit-*`, `em-merge-edit-*`, and `em-time-*`
   descendants. Those affordances only do anything in edit mode, but
   handleRowClick already early-returns when edit mode is on, so the
   testid guard was always over-aggressive. Dropped those guards plus
   the `[role='button']` rule from the interactive selector, kept the
   real `button`/`input`/`textarea`/`a`/`menuitem`/`checkbox`/etc.
   guards and the `em-row-actions-*` / `em-row-select-*` testid
   guards (those affordances are visible outside edit mode and must
   not trigger the surface).
   File: artifacts/tx-os/src/pages/executive-meetings.tsx (~L4350).

2. Originating row is now unmistakable on iPad: quickOpenShadow is
   `inset 0 0 0 4px highlight, 0 0 0 2px highlight` (was a single
   3px inset) and the row background tints to
   `rgba(highlight, 0.08)` while quick-actions is open.
   File: artifacts/tx-os/src/pages/executive-meetings.tsx
   (~L4287, L4344).

3. Postpone dialog header was overlapping the Radix close X in RTL.
   Added `pr-8` on the DialogHeader (same pattern already used for
   the row-quick mini-dialog).
   File: artifacts/tx-os/src/components/executive-meetings/
   upcoming-meeting-alert.tsx (~L1447).

4. Reschedule tab: date / start / end inputs collided on iPad
   portrait. Grid is now `grid-cols-1 md:grid-cols-3` (single column
   through iPad portrait, three across on landscape/desktop), with
   `min-w-0` on each cell and `w-full` on every Input so Safari's
   native date/time pickers stop overflowing.
   Same file (~L1761).

5. Cancel tab X overlap is resolved by the same DialogHeader fix in
   step 3 (one Dialog wraps all three tabs).

6. Removed the `cancelHint` paragraph + the `cancelHint` translation
   keys in ar.json (L1252) and en.json (L1164) — fully unused now.

NOT pushed to Gitea (Tailscale to desktop-11cj93j still flaky).
Pending pushes: #560 (VAPID), #561 (CEO roles), #563 (this).
2026-05-17 10:18:13 +00:00
riyadhafraa 620ab284e2 fix(executive-meetings): quick-actions UX + reschedule/cancel polish (Task #563)
User-reported polish on the executive-meetings quick-actions flow on
iPad/mobile. Six fixes, all client-side:

1. Quick-actions surface now opens from ANY click on a meeting row
   (was: only the attendees cell). Root cause: handleRowClick guard
   skipped any `em-edit-*`, `em-merge-edit-*`, and `em-time-*`
   descendants. Those affordances only do anything in edit mode, but
   handleRowClick already early-returns when edit mode is on, so the
   testid guard was always over-aggressive. Dropped those guards plus
   the `[role='button']` rule from the interactive selector, kept the
   real `button`/`input`/`textarea`/`a`/`menuitem`/`checkbox`/etc.
   guards and the `em-row-actions-*` / `em-row-select-*` testid
   guards (those affordances are visible outside edit mode and must
   not trigger the surface).
   File: artifacts/tx-os/src/pages/executive-meetings.tsx (~L4350).

2. Originating row is now unmistakable on iPad: quickOpenShadow is
   `inset 0 0 0 4px highlight, 0 0 0 2px highlight` (was a single
   3px inset) and the row background tints to
   `rgba(highlight, 0.08)` while quick-actions is open.
   File: artifacts/tx-os/src/pages/executive-meetings.tsx
   (~L4287, L4344).

3. Postpone dialog header was overlapping the Radix close X in RTL.
   Added `pr-8` on the DialogHeader (same pattern already used for
   the row-quick mini-dialog).
   File: artifacts/tx-os/src/components/executive-meetings/
   upcoming-meeting-alert.tsx (~L1447).

4. Reschedule tab: date / start / end inputs collided on iPad
   portrait. Grid is now `grid-cols-1 md:grid-cols-3` (single column
   through iPad portrait, three across on landscape/desktop), with
   `min-w-0` on each cell and `w-full` on every Input so Safari's
   native date/time pickers stop overflowing.
   Same file (~L1761).

5. Cancel tab X overlap is resolved by the same DialogHeader fix in
   step 3 (one Dialog wraps all three tabs).

6. Removed the `cancelHint` paragraph + the `cancelHint` translation
   keys in ar.json (L1252) and en.json (L1164) — fully unused now.

NOT pushed to Gitea (Tailscale to desktop-11cj93j still flaky).
Pending pushes: #560 (VAPID), #561 (CEO roles), #563 (this).
2026-05-17 10:18:13 +00:00