fix batch postage selection

This commit is contained in:
24c02 2025-12-19 14:49:14 -05:00
parent 860e1f46f9
commit b07832adda
4 changed files with 52 additions and 39 deletions

View file

@ -1 +1,5 @@
import '~/js/click-to-copy.js'
import Alpine from 'alpinejs'
import '~/js/click-to-copy.js'
window.Alpine = Alpine
Alpine.start()

View file

@ -60,8 +60,8 @@
<% end %>
</div>
</div>
<%= form_with(model: @batch, url: process_letter_batch_path(@batch), method: :post) do |f| %>
<div>
<%= form_with(model: @batch, url: process_letter_batch_path(@batch), method: :post, data: { controller: "postage-form" }) do |f| %>
<div x-data="{ usPostageType: 'indicia', intlPostageType: 'indicia' }">
<div class="form-group">
<%= f.label :letter_mailing_date, "Mailing Date", class: "form-label" %>
<%= f.date_field :letter_mailing_date,
@ -71,28 +71,28 @@
required: true %>
</div>
<% if @batch.letter_return_address&.us? %>
<div>
<div style="margin-bottom: 1.5rem;">
<h4 class="text-sm font-medium mb-2">US Mail</h4>
<div class="space-y-2">
<div class="form-check">
<%= f.radio_button :us_postage_type, "stamps", class: "form-check-input", checked: true %>
<%= f.radio_button :us_postage_type, "stamps", class: "form-check-input", "@change": "usPostageType = 'stamps'" %>
<%= f.label :us_postage_type_stamps, "Stamps", class: "form-check-label" %>
</div>
<div class="form-check">
<%= f.radio_button :us_postage_type, "indicia", class: "form-check-input" %>
<%= f.radio_button :us_postage_type, "indicia", class: "form-check-input", checked: true, "@change": "usPostageType = 'indicia'" %>
<%= f.label :us_postage_type_indicia, "Indicia (Metered)", class: "form-check-label" %>
</div>
</div>
</div>
<div>
<div style="margin-bottom: 1.5rem;">
<h4 class="text-sm font-medium mb-2">International Mail</h4>
<div class="space-y-2">
<div class="form-check">
<%= f.radio_button :intl_postage_type, "stamps", class: "form-check-input", checked: true %>
<%= f.radio_button :intl_postage_type, "stamps", class: "form-check-input", "@change": "intlPostageType = 'stamps'" %>
<%= f.label :intl_postage_type_stamps, "Stamps", class: "form-check-label" %>
</div>
<div class="form-check">
<%= f.radio_button :intl_postage_type, "indicia", class: "form-check-input" %>
<%= f.radio_button :intl_postage_type, "indicia", class: "form-check-input", checked: true, "@change": "intlPostageType = 'indicia'" %>
<%= f.label :intl_postage_type_indicia, "Indicia (Metered)", class: "form-check-label" %>
</div>
</div>
@ -104,7 +104,7 @@
<%= f.hidden_field :us_postage_type, value: "international_origin" %>
<%= f.hidden_field :intl_postage_type, value: "international_origin" %>
<% end %>
<div class="form-group payment-account-field" style="display: none;">
<div class="form-group" style="margin-top: 1.5rem;" x-show="usPostageType === 'indicia' || intlPostageType === 'indicia'" x-cloak>
<%= f.label :usps_payment_account_id, "USPS Payment Account", class: "form-label" %>
<%= f.collection_select :usps_payment_account_id,
USPS::PaymentAccount.all,
@ -113,7 +113,7 @@
{ selected: USPS::PaymentAccount.first&.id },
{ class: "form-select" } %>
</div>
<div class="form-group hcb-payment-account-field" style="display: none;">
<div class="form-group" style="margin-top: 1.5rem;" x-show="usPostageType === 'indicia' || intlPostageType === 'indicia'" x-cloak>
<%= f.label :hcb_payment_account_id, "Pay with HCB Organization", class: "form-label" %>
<% if current_user.hcb_payment_accounts.any? %>
<%= f.collection_select :hcb_payment_account_id,
@ -155,20 +155,19 @@
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const usPostageSelect = document.querySelector('#batch_us_postage_type');
const intlPostageSelect = document.querySelector('#batch_intl_postage_type');
const paymentAccountField = document.querySelector('.payment-account-field');
const hcbPaymentAccountField = document.querySelector('.hcb-payment-account-field');
const usPostageRadios = document.querySelectorAll('input[name="batch[us_postage_type]"]');
const intlPostageRadios = document.querySelectorAll('input[name="batch[intl_postage_type]"]');
function updatePaymentAccountVisibility() {
const showPaymentAccount = usPostageSelect.value === 'indicia' || intlPostageSelect.value === 'indicia';
paymentAccountField.style.display = showPaymentAccount ? 'block' : 'none';
hcbPaymentAccountField.style.display = showPaymentAccount ? 'block' : 'none';
function getSelectedPostageType(radios) {
for (const radio of radios) {
if (radio.checked) return radio.value;
}
return null;
}
function updatePostageCosts() {
const usPostageType = document.querySelector('#batch_us_postage_type').value;
const intlPostageType = document.querySelector('#batch_intl_postage_type').value;
const usPostageType = getSelectedPostageType(usPostageRadios);
const intlPostageType = getSelectedPostageType(intlPostageRadios);
fetch(`<%= update_costs_letter_batch_path(@batch) %>`, {
method: 'POST',
@ -183,19 +182,16 @@
})
.then(response => response.json())
.then(data => {
// Update costs
document.getElementById('total_postage_cost').textContent = `$${data.total_cost.toFixed(2)}`;
document.getElementById('us_cost_difference').textContent = `$${data.cost_difference.us.toFixed(2)}`;
document.getElementById('intl_cost_difference').textContent = `$${data.cost_difference.intl.toFixed(2)}`;
// Update letter counts
document.getElementById('us_letter_count').textContent = data.us_count;
document.getElementById('intl_letter_count').textContent = data.intl_count;
const usDiffElement = document.getElementById('us_cost_difference');
const intlDiffElement = document.getElementById('intl_cost_difference');
// Update US cost difference styling
if (data.cost_difference.us < 0) {
usDiffElement.classList.remove('text-red-600');
usDiffElement.classList.add('text-green-600');
@ -204,7 +200,6 @@
usDiffElement.classList.add('text-red-600');
}
// Update international cost difference styling
if (data.cost_difference.intl < 0) {
intlDiffElement.classList.remove('text-red-600');
intlDiffElement.classList.add('text-green-600');
@ -215,22 +210,16 @@
});
}
document.querySelector('#batch_us_postage_type').addEventListener('change', () => {
updatePaymentAccountVisibility();
updatePostageCosts();
});
document.querySelector('#batch_intl_postage_type').addEventListener('change', () => {
updatePaymentAccountVisibility();
updatePostageCosts();
});
// Initial check
updatePaymentAccountVisibility();
usPostageRadios.forEach(radio => radio.addEventListener('change', updatePostageCosts));
intlPostageRadios.forEach(radio => radio.addEventListener('change', updatePostageCosts));
updatePostageCosts();
});
</script>
<style>
[x-cloak] {
display: none !important;
}
.container {
max-width: 800px;
margin: 0 auto;

View file

@ -18,12 +18,13 @@
"@picocss/pico": "^2.1.1",
"@selectize/selectize": "^0.15.2",
"@tsparticles/confetti": "^3.8.1",
"alpinejs": "^3.15.3",
"d3": "^7.9.0",
"datamaps": "^0.5.9",
"leaflet": "^1.9.4",
"leaflet-arc": "^1.0.2",
"dreamland": "^0.0.25",
"jquery": "^3.7.1",
"leaflet": "^1.9.4",
"leaflet-arc": "^1.0.2",
"qz-tray": "^2.2.4",
"select2": "^4.1.0-rc.0",
"selectize": "^0.12.6",

View file

@ -639,11 +639,30 @@
resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz"
integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
"@vue/reactivity@~3.1.1":
version "3.1.5"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.1.5.tgz#dbec4d9557f7c8f25c2635db1e23a78a729eb991"
integrity sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==
dependencies:
"@vue/shared" "3.1.5"
"@vue/shared@3.1.5":
version "3.1.5"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.5.tgz#74ee3aad995d0a3996a6bb9533d4d280514ede03"
integrity sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==
acorn@^7.1.1:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
alpinejs@^3.15.3:
version "3.15.3"
resolved "https://registry.yarnpkg.com/alpinejs/-/alpinejs-3.15.3.tgz#667bce66914f8a11a786bffba9081c25ee3692d8"
integrity sha512-fSI6F5213FdpMC4IWaup92KhuH3jBX0VVqajRJ6cOTCy1cL6888KyXdGO+seAAkn+g6fnrxBqQEx6gRpQ5EZoQ==
dependencies:
"@vue/reactivity" "~3.1.1"
ansicolors@~0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz"