From f7d79809b41fae5008842f67cdd460418231c2e9 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sun, 7 Jun 2026 21:10:58 +0000 Subject: [PATCH] Replace native confirm() dialogs with styled confirm modals. Add shared confirm-dialog component, Alpine ladillConfirm store, and swap browser confirms for consistent bottom-sheet modals across user, admin, and hosting flows. Co-authored-by: Cursor --- deploy/deploy.sh | 8 +- resources/js/app.js | 7 ++ resources/js/ladill-modals.js | 75 +++++++++++++++++++ .../views/components/confirm-dialog.blade.php | 69 +++++++++++++++++ .../views/email/account/developers.blade.php | 16 +++- .../views/email/account/settings.blade.php | 23 ++++-- resources/views/email/account/team.blade.php | 16 +++- resources/views/email/domains/show.blade.php | 17 ++++- .../views/email/mailboxes/show.blade.php | 17 ++++- resources/views/layouts/hosting.blade.php | 1 + resources/views/layouts/user.blade.php | 1 + .../views/partials/confirm-prompt.blade.php | 65 ++++++++++++++++ resources/views/qr-codes/attendees.blade.php | 11 ++- .../views/qr/account/developers.blade.php | 16 +++- resources/views/qr/account/team.blade.php | 16 +++- 15 files changed, 325 insertions(+), 33 deletions(-) create mode 100644 resources/js/ladill-modals.js create mode 100644 resources/views/components/confirm-dialog.blade.php create mode 100644 resources/views/partials/confirm-prompt.blade.php diff --git a/deploy/deploy.sh b/deploy/deploy.sh index dc477e2..a8ab951 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -205,7 +205,13 @@ switch_current_release() { } log "Switching current release" -switch_current_release +if ! switch_current_release; then + echo "Failed to point $CURRENT_LINK at $NEW_RELEASE" >&2 + exit 1 +fi + +LIVE_REV="$(cat "$CURRENT_LINK/REVISION" 2>/dev/null || echo unknown)" +log "Live release: $STAMP (revision $LIVE_REV)" log "Optimizing Laravel" if [ -L "$CURRENT_LINK" ] && [ -f "$CURRENT_LINK/artisan" ]; then diff --git a/resources/js/app.js b/resources/js/app.js index 61cc8be..ad8634c 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1,5 +1,10 @@ import './bootstrap'; +import { registerLadillConfirmStore, registerLadillModalHelpers } from './ladill-modals'; + +registerLadillModalHelpers(); + + import Alpine from 'alpinejs'; import collapse from '@alpinejs/collapse'; import QRCodeStyling from 'qr-code-styling'; @@ -191,4 +196,6 @@ Alpine.data('topbarSearch', (config = {}) => ({ })); window.Alpine = Alpine; +registerLadillConfirmStore(Alpine); + Alpine.start(); diff --git a/resources/js/ladill-modals.js b/resources/js/ladill-modals.js new file mode 100644 index 0000000..eb2bf74 --- /dev/null +++ b/resources/js/ladill-modals.js @@ -0,0 +1,75 @@ +/** + * Lightweight modal dispatch helpers (optional — balanceGate in layout is primary). + */ + +export function openLadillModal(name) { + if (!name) { + return false; + } + + window.dispatchEvent(new CustomEvent('open-modal', { detail: name, bubbles: true })); + + return true; +} + +export function closeLadillModal(name) { + if (!name) { + return false; + } + + window.dispatchEvent(new CustomEvent('close-modal', { detail: name, bubbles: true })); + + return true; +} + +export function ladillNeedsTopup(balance, price) { + const normalizedBalance = Number.parseFloat(balance); + const normalizedPrice = Number.parseFloat(price); + + if (!Number.isFinite(normalizedBalance) || !Number.isFinite(normalizedPrice)) { + return false; + } + + return normalizedBalance <= 0 || normalizedBalance < normalizedPrice; +} + +export function registerLadillConfirmStore(Alpine) { + Alpine.store('ladillConfirm', { + open: false, + title: '', + message: '', + confirmLabel: 'Confirm', + cancelLabel: 'Cancel', + variant: 'danger', + _resolve: null, + + ask(options = {}) { + return new Promise((resolve) => { + this.title = options.title || 'Are you sure?'; + this.message = options.message || ''; + this.confirmLabel = options.confirmLabel || 'Confirm'; + this.cancelLabel = options.cancelLabel || 'Cancel'; + this.variant = options.variant || 'danger'; + this._resolve = resolve; + this.open = true; + }); + }, + + answer(confirmed) { + if (this._resolve) { + this._resolve(confirmed); + } + + this.open = false; + this._resolve = null; + }, + }); + + window.ladillConfirm = (options = {}) => Alpine.store('ladillConfirm').ask(options); +} + +export function registerLadillModalHelpers() { + window.openLadillModal = openLadillModal; + window.closeLadillModal = closeLadillModal; + window.ladillNeedsTopup = ladillNeedsTopup; +} diff --git a/resources/views/components/confirm-dialog.blade.php b/resources/views/components/confirm-dialog.blade.php new file mode 100644 index 0000000..1d0ee69 --- /dev/null +++ b/resources/views/components/confirm-dialog.blade.php @@ -0,0 +1,69 @@ +@props([ + 'name', + 'title', + 'message' => null, + 'action', + 'method' => 'POST', + 'confirmLabel' => 'Confirm', + 'cancelLabel' => 'Cancel', + 'variant' => 'danger', +]) + +@php + $confirmBtnClass = $variant === 'danger' + ? 'bg-red-600 hover:bg-red-700' + : 'bg-violet-600 hover:bg-violet-700'; + $iconWrapClass = $variant === 'danger' + ? 'bg-red-100 text-red-600' + : 'bg-violet-100 text-violet-600'; +@endphp + +@if(isset($trigger)) + + {{ $trigger }} + +@endif + + +
+
+
+ @if($variant === 'danger') + + + + @else + + + + @endif +
+

{{ $title }}

+ @if($message) +

{{ $message }}

+ @endif + @isset($details) +
{{ $details }}
+ @endisset +
+ +
+ @csrf + @if(strtoupper($method) !== 'POST') + @method($method) + @endif + @isset($fields) + {{ $fields }} + @endisset + + +
+
+
diff --git a/resources/views/email/account/developers.blade.php b/resources/views/email/account/developers.blade.php index 28d1b4a..ea2649a 100644 --- a/resources/views/email/account/developers.blade.php +++ b/resources/views/email/account/developers.blade.php @@ -46,10 +46,18 @@ {{ $token->last_used_at ? 'last used '.$token->last_used_at->diffForHumans() : 'never used' }}

-
- @csrf @method('DELETE') - -
+ + + + + @empty

No tokens yet.

diff --git a/resources/views/email/account/settings.blade.php b/resources/views/email/account/settings.blade.php index 7ec7bfc..54b854a 100644 --- a/resources/views/email/account/settings.blade.php +++ b/resources/views/email/account/settings.blade.php @@ -22,13 +22,22 @@
Linked mailbox: {{ $linkStatus['linked_mailbox'] }}
-
- @csrf @method('DELETE') - -
+ + + + + @elseif(($linkStatus['stage'] ?? '') === 'needs_domain')

Add and verify an email domain first.

diff --git a/resources/views/email/account/team.blade.php b/resources/views/email/account/team.blade.php index 48793ae..70c9fef 100644 --- a/resources/views/email/account/team.blade.php +++ b/resources/views/email/account/team.blade.php @@ -64,10 +64,18 @@ -
- @csrf @method('DELETE') - -
+ + + + + @else {{ $member->role }} @endif diff --git a/resources/views/email/domains/show.blade.php b/resources/views/email/domains/show.blade.php index 7805fb8..0d4c453 100644 --- a/resources/views/email/domains/show.blade.php +++ b/resources/views/email/domains/show.blade.php @@ -54,9 +54,18 @@ @endunless -
- @csrf @method('DELETE') - -
+ + + + + @endsection diff --git a/resources/views/email/mailboxes/show.blade.php b/resources/views/email/mailboxes/show.blade.php index 79c78f8..e5ee875 100644 --- a/resources/views/email/mailboxes/show.blade.php +++ b/resources/views/email/mailboxes/show.blade.php @@ -74,10 +74,19 @@

Delete mailbox

This permanently removes the mailbox and its email.

-
- @csrf @method('DELETE') - -
+ + + + +
@endsection diff --git a/resources/views/layouts/hosting.blade.php b/resources/views/layouts/hosting.blade.php index 3de0095..d8b409e 100644 --- a/resources/views/layouts/hosting.blade.php +++ b/resources/views/layouts/hosting.blade.php @@ -55,5 +55,6 @@ ]) @include('partials.afia') @endauth +@include('partials.confirm-prompt') diff --git a/resources/views/layouts/user.blade.php b/resources/views/layouts/user.blade.php index d9925d4..789b878 100644 --- a/resources/views/layouts/user.blade.php +++ b/resources/views/layouts/user.blade.php @@ -270,5 +270,6 @@ document.addEventListener('keydown', (e) => { @include('partials.afia') @include('partials.sso-keepalive') +@include('partials.confirm-prompt') diff --git a/resources/views/partials/confirm-prompt.blade.php b/resources/views/partials/confirm-prompt.blade.php new file mode 100644 index 0000000..c519339 --- /dev/null +++ b/resources/views/partials/confirm-prompt.blade.php @@ -0,0 +1,65 @@ +
+
+ +
+
+
+
+ +
+
+
+ + +
+

+

+
+ +
+ + +
+
+
+
diff --git a/resources/views/qr-codes/attendees.blade.php b/resources/views/qr-codes/attendees.blade.php index a246d23..ed3f83f 100644 --- a/resources/views/qr-codes/attendees.blade.php +++ b/resources/views/qr-codes/attendees.blade.php @@ -43,7 +43,16 @@
@csrf -
+ + + + + @empty

No tokens yet.

diff --git a/resources/views/qr/account/team.blade.php b/resources/views/qr/account/team.blade.php index 177392f..b19b907 100644 --- a/resources/views/qr/account/team.blade.php +++ b/resources/views/qr/account/team.blade.php @@ -66,10 +66,18 @@ -
- @csrf @method('DELETE') - -
+ + + + + @else {{ $member->role }} @endif