diff --git a/app/assets/stylesheets/components/_sweetalert.scss b/app/assets/stylesheets/components/_sweetalert.scss index e864621094..7ef8274f57 100644 --- a/app/assets/stylesheets/components/_sweetalert.scss +++ b/app/assets/stylesheets/components/_sweetalert.scss @@ -48,6 +48,17 @@ background-color: transparent; } + .swal-content { + input { + color: inherit; + background: transparent; + border: 1px solid rgba(150, 150, 150, 0.4); + border-radius: var(--radius-md, 6px); + padding: 8px 12px; + width: 100%; + } + } + .swal-button { @extend .btn; } diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 4f6308e7e9..a894009ce3 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -55,6 +55,17 @@ def transaction elsif @canonical_transaction.amount_cents.abs >= 5_000_00 # $5k "Are you really really sure you want to map this transaction? 🤔 it seems like a big one :)" end + + # If this transaction was already mapped a while ago, remapping it annoys Sierra's accounting system. + + if @canonical_transaction.canonical_event_mapping.present? && + @canonical_transaction.canonical_event_mapping.created_at < 12.hours.ago + @stale_remap = true + @remap_confirm_msg = "⚠️ This transaction was already mapped to \"#{@canonical_transaction.event&.name}\" #{helpers.time_ago_in_words(@canonical_transaction.canonical_event_mapping.created_at)} ago. Remapping it now may disrupt our accounting. Are you absolutely sure you want to remap this transaction?" + @remap_confirm_phrase = "REMAP #{@canonical_transaction.id}" + @remap_after_message = "Please contact Sierra and the HCB Ops team right away to let them know you remapped transaction ##{@canonical_transaction.id}." + @remap_warning_tooltip = "This transaction was already mapped #{helpers.time_ago_in_words(@canonical_transaction.canonical_event_mapping.created_at)} ago — remapping it requires extra confirmation." + end end def events diff --git a/app/javascript/confirm.js b/app/javascript/confirm.js index c412cb7f18..0f534e3393 100644 --- a/app/javascript/confirm.js +++ b/app/javascript/confirm.js @@ -13,14 +13,69 @@ function showConfirm( }).then(v => !!v) } +async function showTypeToConfirm( + message, + phrase, + { title = 'Are you sure?', afterMessage = null } = {} +) { + const warned = await swal({ + title, + text: message, + icon: 'warning', + buttons: ['Cancel', "Yes, I'm sure"], + dangerMode: true, + }) + if (!warned) return false + + const typed = await swal({ + title: 'Confirm by typing', + text: `Type "${phrase}" below to confirm:`, + content: { + element: 'input', + attributes: { + placeholder: phrase, + type: 'text', + }, + }, + buttons: ['Cancel', 'Confirm'], + dangerMode: true, + }) + if (typed?.trim() !== phrase) { + if (typed !== null) { + await swal('Not confirmed', 'What you typed did not match.', 'error') + } + return false + } + + if (afterMessage) { + await swal('One more thing', afterMessage, 'info') + } + + return true +} + Turbo.config.forms.confirm = (message, formElement, submitter) => { const dangerMode = Boolean( submitter?.hasAttribute('data-turbo-confirm-danger') || formElement?.hasAttribute('data-turbo-confirm-danger') ) + + const phrase = + submitter?.getAttribute('data-turbo-confirm-type-phrase') || + formElement?.getAttribute('data-turbo-confirm-type-phrase') + + if (phrase) { + const afterMessage = + submitter?.getAttribute('data-turbo-confirm-after-message') || + formElement?.getAttribute('data-turbo-confirm-after-message') + + return showTypeToConfirm(message, phrase, { afterMessage }) + } + return showConfirm(message, { dangerMode }) } window.showConfirm = showConfirm +window.showTypeToConfirm = showTypeToConfirm window.swal = swal export default showConfirm diff --git a/app/views/admin/transaction.html.erb b/app/views/admin/transaction.html.erb index cbfdb4b96c..03544470fb 100644 --- a/app/views/admin/transaction.html.erb +++ b/app/views/admin/transaction.html.erb @@ -2,6 +2,13 @@