mirror of
https://github.com/System-End/theseus.git
synced 2026-04-19 19:55:10 +00:00
waoaw
This commit is contained in:
parent
8ba8b36e26
commit
df01c91baa
12 changed files with 630 additions and 426 deletions
|
|
@ -53,6 +53,7 @@ class Letter::InstantQueue < Letter::Queue
|
|||
|
||||
# Associations
|
||||
belongs_to :usps_payment_account, class_name: "USPS::PaymentAccount", optional: true
|
||||
belongs_to :hcb_payment_account, class_name: "HCB::PaymentAccount", optional: true
|
||||
|
||||
# Scopes
|
||||
default_scope { where(type: "Letter::InstantQueue") }
|
||||
|
|
@ -104,8 +105,8 @@ class Letter::InstantQueue < Letter::Queue
|
|||
transfer_service = HCB::TransferService.new(
|
||||
hcb_payment_account: hcb_payment_account,
|
||||
amount_cents: cost_cents,
|
||||
name: "Postage for #{letter.public_id} #{indicium.public_id} #{Rails.application.routes.url_helpers.letter_path(letter)}",
|
||||
memo: "[theseus] postage for a #{letter.processing_category}",
|
||||
name: "Postage for #{letter.public_id} #{indicium.public_id} (#{slug}) #{Rails.application.routes.url_helpers.letter_path(letter)}",
|
||||
memo: "[theseus] postage for a #{letter.processing_category} via queue #{name}",
|
||||
)
|
||||
transfer = transfer_service.call
|
||||
unless transfer
|
||||
|
|
|
|||
|
|
@ -1,41 +1,70 @@
|
|||
<% content_for :title do %>
|
||||
HCB Payment Accounts
|
||||
<% end %>
|
||||
<% content_for :title, "HCB Payment Accounts" %>
|
||||
|
||||
<h1>HCB Payment Accounts</h1>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<h1>HCB Payment Accounts</h1>
|
||||
</header>
|
||||
|
||||
<% if current_user.hcb_connected? %>
|
||||
<div class="notice success">
|
||||
✓ HCB account linked
|
||||
</div>
|
||||
<% if current_user.hcb_connected? %>
|
||||
<div class="grid md:grid-cols-12 gap-6">
|
||||
<div class="md:col-span-8">
|
||||
<article>
|
||||
<header class="flex items-center justify-between">
|
||||
<h2>Your Organizations</h2>
|
||||
<%= link_to new_hcb_payment_account_path, class: "btn success btn-small" do %>
|
||||
+ Add Organization
|
||||
<% end %>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<% if @payment_accounts.any? %>
|
||||
<div class="space-y-3">
|
||||
<% @payment_accounts.each do |account| %>
|
||||
<div class="flex items-center justify-between p-3 border rounded hover:bg-gray-50">
|
||||
<div>
|
||||
<div class="font-medium"><%= account.organization_name %></div>
|
||||
<div class="text-sm text-gray-500">Added <%= time_ago_in_words(account.created_at) %> ago</div>
|
||||
</div>
|
||||
<%= link_to "View", hcb_payment_account_path(account), class: "btn btn-small" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p class="text-gray-500">No organizations linked yet. Add one to start paying for postage.</p>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<%= link_to "Add Payment Account", new_hcb_payment_account_path, class: "btn success btn-small" %>
|
||||
</div>
|
||||
|
||||
<% if @payment_accounts.any? %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Organization</th>
|
||||
<th>Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @payment_accounts.each do |account| %>
|
||||
<tr>
|
||||
<td><%= account.organization_name %></td>
|
||||
<td><%= account.created_at.strftime("%Y-%m-%d") %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="md:col-span-4">
|
||||
<article>
|
||||
<header>
|
||||
<h2>Account Status</h2>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<div class="text-green-700 mb-4">
|
||||
<span class="font-medium">✓ HCB Connected</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600">
|
||||
Your account is linked to HCB. You can pay for postage using any of your organizations' funds.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>No payment accounts yet. Add one to start paying for postage.</p>
|
||||
<article class="max-w-xl mx-auto text-center">
|
||||
<header>
|
||||
<h2>Connect to HCB</h2>
|
||||
</header>
|
||||
<div class="p-6">
|
||||
|
||||
<p class="text-gray-600 mb-6">
|
||||
Link your HCB account to pay for postage directly from your organization's funds.
|
||||
</p>
|
||||
<%= link_to new_hcb_oauth_connection_path, class: "btn success" do %>
|
||||
Connect HCB Account
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div class="notice">
|
||||
<p>Link your HCB account to pay for postage from your organization.</p>
|
||||
<%= link_to "Link HCB Account", new_hcb_oauth_connection_path, class: "btn success" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,51 @@
|
|||
<% content_for :title do %>
|
||||
Add HCB Payment Account
|
||||
<% end %>
|
||||
<% content_for :title, "Add HCB Organization" %>
|
||||
|
||||
<h1>Add HCB Payment Account</h1>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", hcb_payment_accounts_path, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<h1>Add Organization</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<p>Select an organization to use for paying postage:</p>
|
||||
<div class="max-w-lg">
|
||||
<% if @organizations.any? %>
|
||||
<article>
|
||||
<header>
|
||||
<h2>Select Organization</h2>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<p class="text-gray-600 mb-4">Choose which HCB organization to use for paying postage.</p>
|
||||
|
||||
<%= form_with url: hcb_payment_accounts_path, method: :post do |f| %>
|
||||
<div class="space-y-3 mb-6">
|
||||
<% @organizations.each do |org| %>
|
||||
<label class="flex items-center p-3 border rounded cursor-pointer hover:bg-gray-50 has-[:checked]:border-green-500 has-[:checked]:bg-green-50">
|
||||
<%= f.radio_button :organization_id, org.id, class: "mr-3" %>
|
||||
<span class="font-medium"><%= org.name %></span>
|
||||
</label>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= form_with url: hcb_payment_accounts_path, method: :post do |f| %>
|
||||
<fieldset>
|
||||
<%= f.label :organization_id, "Organization" %>
|
||||
<%= f.select :organization_id, @organizations.map { |org| [org.name, org.id] }, { prompt: "Select an organization..." } %>
|
||||
</fieldset>
|
||||
|
||||
<%= f.submit "Add Payment Account", class: "btn success btn-small" %>
|
||||
<%= link_to "Cancel", hcb_payment_accounts_path, class: "btn btn-small" %>
|
||||
<% end %>
|
||||
|
||||
<% if @organizations.empty? %>
|
||||
<div class="notice warning">
|
||||
<p>No organizations found. Make sure you have admin access to at least one HCB organization.</p>
|
||||
<div class="flex gap-3">
|
||||
<%= f.submit "Add Organization", class: "btn success" %>
|
||||
<%= link_to "Cancel", hcb_payment_accounts_path, class: "btn btn-small" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
<% else %>
|
||||
<article>
|
||||
<header>
|
||||
<h2>No Organizations Available</h2>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<p class="text-gray-600 mb-4">
|
||||
You don't have admin access to any HCB organizations, or all your organizations are already linked.
|
||||
</p>
|
||||
<%= link_to "← Back", hcb_payment_accounts_path, class: "btn btn-small" %>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
<% content_for :title do %>
|
||||
<%= @payment_account.organization_name %> - HCB Payment Account
|
||||
<% end %>
|
||||
<% content_for :title, "#{@payment_account.organization_name} - HCB" %>
|
||||
|
||||
<h1><%= @payment_account.organization_name %></h1>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", hcb_payment_accounts_path, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<h1><%= @payment_account.organization_name %></h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<dl>
|
||||
<dt>Organization ID</dt>
|
||||
<dd><code><%= @payment_account.organization_id %></code></dd>
|
||||
|
||||
<dt>Created</dt>
|
||||
<dd><%= @payment_account.created_at.strftime("%Y-%m-%d %H:%M") %></dd>
|
||||
</dl>
|
||||
|
||||
<div class="actions">
|
||||
<%= link_to "Back to Payment Accounts", hcb_payment_accounts_path, class: "btn btn-small" %>
|
||||
<div class="max-w-2xl">
|
||||
<article>
|
||||
<header>
|
||||
<h2>Organization Details</h2>
|
||||
</header>
|
||||
<div class="p-4">
|
||||
<dl class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<dt class="text-sm text-gray-500">Organization ID</dt>
|
||||
<dd class="font-mono text-sm"><%= @payment_account.organization_id %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-sm text-gray-500">Added</dt>
|
||||
<dd><%= @payment_account.created_at.strftime("%B %d, %Y") %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
12
app/views/letter/instant_queues/new.html.erb
Normal file
12
app/views/letter/instant_queues/new.html.erb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<% content_for :title, "New Instant Queue" %>
|
||||
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", letter_instant_queues_path, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<h1>New Instant Queue</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<%= render "letter/queues/form", letter_queue: @letter_queue %>
|
||||
</div>
|
||||
|
|
@ -133,10 +133,13 @@
|
|||
function togglePaymentAccount(select) {
|
||||
const paymentAccountField = document.getElementById('paymentAccountField');
|
||||
const hcbPaymentAccountField = document.getElementById('hcbPaymentAccountField');
|
||||
paymentAccountField.style.display = select.value === "indicia" ? "block" : "none";
|
||||
hcbPaymentAccountField.style.display = select.value === "indicia" ? "block" : "none";
|
||||
if (paymentAccountField) paymentAccountField.style.display = select.value === "indicia" ? "block" : "none";
|
||||
if (hcbPaymentAccountField) hcbPaymentAccountField.style.display = select.value === "indicia" ? "block" : "none";
|
||||
}
|
||||
|
||||
toggleQueueType(document.getElementById('letter_queue_type'));
|
||||
togglePaymentAccount(document.getElementById('letter_queue_postage_type'));
|
||||
const typeSelect = document.getElementById('letter_queue_type');
|
||||
if (typeSelect) toggleQueueType(typeSelect);
|
||||
|
||||
const postageSelect = document.getElementById('letter_queue_postage_type') || document.getElementById('letter_instant_queue_postage_type');
|
||||
if (postageSelect) togglePaymentAccount(postageSelect);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,29 +1,32 @@
|
|||
<div class="flex flex-col gap-2">
|
||||
<%= form_with(url: buy_indicia_letter_path(letter), method: :post) do |form| %>
|
||||
<div class="form-group">
|
||||
<label>USPS Payment Account</label>
|
||||
<%= form_with(url: buy_indicia_letter_path(letter), method: :post, class: "space-y-4") do |form| %>
|
||||
<% if current_user.hcb_payment_accounts.any? %>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">Pay with HCB Organization</label>
|
||||
<%= form.collection_select :hcb_payment_account_id,
|
||||
current_user.hcb_payment_accounts,
|
||||
:id,
|
||||
:organization_name,
|
||||
{ prompt: "Select organization..." },
|
||||
{ required: true, class: "w-full" } %>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">USPS Payment Account</label>
|
||||
<%= form.collection_select :usps_payment_account_id,
|
||||
USPS::PaymentAccount.all,
|
||||
:id,
|
||||
:name,
|
||||
{ prompt: "Select a payment account", selected: USPS::PaymentAccount.first&.id },
|
||||
{ required: true } %>
|
||||
{ selected: USPS::PaymentAccount.first&.id },
|
||||
{ required: true, class: "w-full" } %>
|
||||
</div>
|
||||
|
||||
<%= form.submit "Buy Indicia", class: "btn success w-full" %>
|
||||
<% else %>
|
||||
<div class="text-center py-4">
|
||||
<p class="text-sm text-gray-600 mb-3">Connect your HCB account to purchase postage.</p>
|
||||
<%= link_to new_back_office_hcb_oauth_connection_path, class: "btn btn-small" do %>
|
||||
Connect HCB
|
||||
<% end %>
|
||||
</div>
|
||||
<% if current_user.hcb_payment_accounts.any? %>
|
||||
<div class="form-group">
|
||||
<label>Pay with HCB Organization</label>
|
||||
<%= form.collection_select :hcb_payment_account_id,
|
||||
current_user.hcb_payment_accounts,
|
||||
:id,
|
||||
:organization_name,
|
||||
{ prompt: "Select an organization" },
|
||||
{ required: true } %>
|
||||
</div>
|
||||
<% else %>
|
||||
<p class="text-sm text-gray-600">
|
||||
<%= link_to "Connect your HCB account", new_back_office_hcb_oauth_connection_path %> to purchase indicia.
|
||||
</p>
|
||||
<% end %>
|
||||
<%= form.submit "Buy Indicia", class: "primary", disabled: current_user.hcb_payment_accounts.empty? %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,46 +1,79 @@
|
|||
<div class="max-w-2xl mx-auto">
|
||||
<h1 class="text-2xl font-bold mb-6">Buy Indicia for Letter #<%= @letter.id %></h1>
|
||||
<% content_for :title, "Buy Indicia - #{@letter.public_id}" %>
|
||||
|
||||
<div class="card mb-6">
|
||||
<div class="card-body">
|
||||
<div class="grid md:grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<span class="text-gray-500">Recipient:</span>
|
||||
<div class="font-medium"><%= @letter.address.display_name %></div>
|
||||
<div><%= @letter.address.line_1 %></div>
|
||||
<% if @letter.address.line_2.present? %>
|
||||
<div><%= @letter.address.line_2 %></div>
|
||||
<% end %>
|
||||
<div><%= @letter.address.city %>, <%= @letter.address.state %> <%= @letter.address.postal_code %></div>
|
||||
<div><%= @letter.address.country %></div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-gray-500">Dimensions:</span>
|
||||
<div><%= @letter.height %> × <%= @letter.width %> in</div>
|
||||
<span class="text-gray-500">Weight:</span>
|
||||
<div><%= @letter.weight %> oz</div>
|
||||
<% if @letter.non_machinable? %>
|
||||
<div class="text-yellow-600">Non-machinable</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form_with(url: buy_indicia_letter_path(@letter), method: :post, class: "form-container") do |form| %>
|
||||
<div class="form-group">
|
||||
<%= form.label :usps_payment_account_id, "USPS Payment Account", class: "form-label" %>
|
||||
<%= form.collection_select :usps_payment_account_id,
|
||||
USPS::PaymentAccount.all,
|
||||
:id,
|
||||
:name,
|
||||
{ prompt: "Select a payment account", selected: USPS::PaymentAccount.first&.id },
|
||||
{ class: "form-control", required: true } %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions mt-6">
|
||||
<%= form.submit "Buy Indicia", class: "btn btn-primary" %>
|
||||
<%= link_to "Cancel", @letter, class: "btn btn-secondary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", @letter, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<h1>Buy Indicia</h1>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="max-w-lg">
|
||||
<article class="mb-6">
|
||||
<header><h2>Letter Details</h2></header>
|
||||
<div class="p-4">
|
||||
<dl class="grid grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<dt class="text-gray-500">Recipient</dt>
|
||||
<dd class="font-medium"><%= @letter.address.name_line %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Destination</dt>
|
||||
<dd><%= @letter.address.city %>, <%= @letter.address.state %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Dimensions</dt>
|
||||
<dd><%= @letter.height %>" × <%= @letter.width %>"</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Weight</dt>
|
||||
<dd><%= @letter.weight %> oz</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<% if @letter.non_machinable? %>
|
||||
<div class="mt-3 text-sm text-yellow-700 bg-yellow-50 px-3 py-2 rounded">
|
||||
Non-machinable surcharge applies
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article>
|
||||
<header><h2>Purchase Postage</h2></header>
|
||||
<div class="p-4">
|
||||
<%= form_with(url: buy_indicia_letter_path(@letter), method: :post, class: "space-y-4") do |form| %>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">USPS Payment Account</label>
|
||||
<%= form.collection_select :usps_payment_account_id,
|
||||
USPS::PaymentAccount.all,
|
||||
:id,
|
||||
:name,
|
||||
{ prompt: "Select account...", selected: USPS::PaymentAccount.first&.id },
|
||||
{ class: "w-full", required: true } %>
|
||||
</div>
|
||||
|
||||
<% if current_user.hcb_payment_accounts.any? %>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">Pay with HCB Organization</label>
|
||||
<%= form.collection_select :hcb_payment_account_id,
|
||||
current_user.hcb_payment_accounts,
|
||||
:id,
|
||||
:organization_name,
|
||||
{ prompt: "Select organization..." },
|
||||
{ class: "w-full", required: true } %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="text-sm text-gray-600 bg-gray-50 p-3 rounded">
|
||||
<%= link_to "Connect your HCB account", new_hcb_oauth_connection_path %> to pay for postage.
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="flex gap-3 pt-2">
|
||||
<%= form.submit "Buy Indicia", class: "btn success", disabled: current_user.hcb_payment_accounts.empty? %>
|
||||
<%= link_to "Cancel", @letter, class: "btn btn-small" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,244 +1,253 @@
|
|||
<% content_for :title, "#{@letter.user_facing_title || 'Letter'} #{@letter.public_id} - #{@letter.address.name_line}" %>
|
||||
<% content_for :title, "#{@letter.user_facing_title || 'Letter'} #{@letter.public_id}" %>
|
||||
|
||||
<div class="container">
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">
|
||||
<%= @letter.public_id %> – <% if @letter.user_facing_title.present? %>
|
||||
<%= @letter.user_facing_title %>
|
||||
<% else %>
|
||||
Letter to <%= @letter.address.name_line %>
|
||||
<% end %>
|
||||
<sup><%= letter_status_badge(@letter.aasm_state) %></sup>
|
||||
</h1>
|
||||
<div class="actions">
|
||||
<%= secondary_link_to "Back to letters", letters_path do %>
|
||||
<%= back_icon %>Back to letters
|
||||
<% end %>
|
||||
<%= secondary_link_to "Edit this letter", edit_letter_path(@letter) do %>
|
||||
<%= edit_icon %>Edit this letter
|
||||
<% end %>
|
||||
<%= button_to "Delete", letter_path(@letter), method: :delete, data: { confirm: "Are you sure?" }, class: "btn danger btn-small" %>
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", letters_path, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<div>
|
||||
<h1 class="flex items-center gap-3">
|
||||
<% if @letter.user_facing_title.present? %>
|
||||
<%= @letter.user_facing_title %>
|
||||
<% else %>
|
||||
Letter to <%= @letter.address.name_line %>
|
||||
<% end %>
|
||||
<%= letter_status_badge(@letter.aasm_state) %>
|
||||
</h1>
|
||||
<div class="text-sm text-gray-500"><%= @letter.public_id %></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="grid md:grid-cols-12 gap-4">
|
||||
<div class="md:col-span-8">
|
||||
<article>
|
||||
<header class="flex items-center justify-between">
|
||||
<h2>Details</h2>
|
||||
<%= link_to "Show on public page", public_letter_path(@letter), target: "_blank" %>
|
||||
</header>
|
||||
<div class="p-3">
|
||||
<%= render 'shared/tags', tags: @letter.tags %>
|
||||
<div class="grid md:grid-cols-2 gap-4 mb-4">
|
||||
<div>
|
||||
<h3>From</h3>
|
||||
<% if @letter.return_address.present? %>
|
||||
<address class="p-2 border rounded">
|
||||
<div><%= @letter.return_address_name_line %></div>
|
||||
<div><%= @letter.return_address.line_1 %></div>
|
||||
<% if @letter.return_address.line_2.present? %>
|
||||
<div><%= @letter.return_address.line_2 %></div>
|
||||
<% end %>
|
||||
<div><%= @letter.return_address.city %>, <%= @letter.return_address.state %> <%= @letter.return_address.postal_code %></div>
|
||||
<div><%= @letter.return_address.country %></div>
|
||||
</address>
|
||||
<% else %>
|
||||
<p>No return address</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<div>
|
||||
<h3>To</h3>
|
||||
<address class="p-2 border rounded">
|
||||
<div><%= @letter.address.name_line %></div>
|
||||
<div><%= @letter.address.line_1 %></div>
|
||||
<% if @letter.address.line_2.present? %>
|
||||
<div><%= @letter.address.line_2 %></div>
|
||||
<div class="actions flex gap-2">
|
||||
<%= link_to edit_letter_path(@letter), class: "btn btn-small" do %>
|
||||
Edit
|
||||
<% end %>
|
||||
<%= link_to public_letter_path(@letter), target: "_blank", class: "btn btn-small" do %>
|
||||
Public Page
|
||||
<% end %>
|
||||
<%= button_to letter_path(@letter), method: :delete, class: "btn danger btn-small", data: { confirm: "Delete this letter?" } do %>
|
||||
Delete
|
||||
<% end %>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="grid md:grid-cols-12 gap-6">
|
||||
<%# Main content %>
|
||||
<div class="md:col-span-8 space-y-6">
|
||||
<%# Addresses %>
|
||||
<article>
|
||||
<header><h2>Addresses</h2></header>
|
||||
<div class="p-4">
|
||||
<%= render 'shared/tags', tags: @letter.tags %>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<div class="text-sm text-gray-500 mb-1">From</div>
|
||||
<% if @letter.return_address.present? %>
|
||||
<address class="p-3 bg-gray-50 rounded not-italic text-sm">
|
||||
<div class="font-medium"><%= @letter.return_address_name_line %></div>
|
||||
<div><%= @letter.return_address.line_1 %></div>
|
||||
<% if @letter.return_address.line_2.present? %>
|
||||
<div><%= @letter.return_address.line_2 %></div>
|
||||
<% end %>
|
||||
<div><%= @letter.address.city %>, <%= @letter.address.state %> <%= @letter.address.postal_code %></div>
|
||||
<div><%= @letter.address.country %></div>
|
||||
<div><%= @letter.return_address.city %>, <%= @letter.return_address.state %> <%= @letter.return_address.postal_code %></div>
|
||||
<div><%= @letter.return_address.country %></div>
|
||||
</address>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="p-3 bg-gray-50 rounded text-gray-500 text-sm">No return address</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<h3>Specifications</h3>
|
||||
<%= render 'shared/letter_attributes', record: @letter %>
|
||||
<h3>Postage Information</h3>
|
||||
<article>
|
||||
<div class="p-3">
|
||||
<% if @letter.postage_type == "indicia" %>
|
||||
<% if @letter.usps_indicium.present? %>
|
||||
<%= render 'admin_inspector', record: @letter.usps_indicium %>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<strong>Postage Type:</strong>
|
||||
Indicia (Metered)
|
||||
</div>
|
||||
<div>
|
||||
<strong>Cost:</strong>
|
||||
<%= number_to_currency(@letter.usps_indicium.cost) %>
|
||||
(<%= number_to_currency(@letter.usps_indicium.postage) %> postage + <%= number_to_currency(@letter.usps_indicium.fees || 0) %> fees)
|
||||
</div>
|
||||
<div>
|
||||
<strong>Mailing Date:</strong>
|
||||
<%= @letter.usps_indicium.mailing_date %>
|
||||
</div>
|
||||
<div>
|
||||
<strong>USPS SKU:</strong>
|
||||
<%= @letter.usps_indicium.usps_sku %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>
|
||||
<strong>Postage Type:</strong>
|
||||
Indicia (Metered) - Not Purchased Yet
|
||||
</p>
|
||||
<% if @letter.batch_id.nil? %>
|
||||
<%= render 'buy_indicia_form', letter: @letter %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% elsif @letter.postage_type == "international_origin" %>
|
||||
<p>
|
||||
<strong>Postage Type:</strong>
|
||||
International Origin
|
||||
</p>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<div>
|
||||
<strong>Cost:</strong>
|
||||
whatever <%= @letter.return_address.country %> charges to send a letter to <%= @letter.address.country %>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<p>
|
||||
<strong>Postage Type:</strong>
|
||||
Stamps
|
||||
</p>
|
||||
<% if @letter.batch_id.nil? %>
|
||||
<div class="mt-2">
|
||||
<%= button_to "Switch to Indicia", letter_path(@letter), method: :patch, params: { letter: { postage_type: "indicia" } }, class: "primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div>
|
||||
<div class="text-sm text-gray-500 mb-1">To</div>
|
||||
<address class="p-3 bg-gray-50 rounded not-italic text-sm">
|
||||
<div class="font-medium"><%= @letter.address.name_line %></div>
|
||||
<div><%= @letter.address.line_1 %></div>
|
||||
<% if @letter.address.line_2.present? %>
|
||||
<div><%= @letter.address.line_2 %></div>
|
||||
<% end %>
|
||||
<div><%= @letter.address.city %>, <%= @letter.address.state %> <%= @letter.address.postal_code %></div>
|
||||
<div><%= @letter.address.country %></div>
|
||||
</address>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<%# Specifications %>
|
||||
<article>
|
||||
<header><h2>Specifications</h2></header>
|
||||
<div class="p-4">
|
||||
<%= render 'shared/letter_attributes', record: @letter %>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<%# Postage %>
|
||||
<article>
|
||||
<header><h2>Postage</h2></header>
|
||||
<div class="p-4">
|
||||
<% if @letter.postage_type == "indicia" %>
|
||||
<% if @letter.usps_indicium.present? %>
|
||||
<div class="flex items-center gap-2 text-green-700 mb-4">
|
||||
<span class="font-medium">✓ Indicia Purchased</span>
|
||||
</div>
|
||||
</article>
|
||||
<% if @letter.batch.present? %>
|
||||
<%= render 'shared/batch_info', record: @letter %>
|
||||
<% end %>
|
||||
<% if @letter.imb_serial_number.present? && @letter.address.country&.upcase == 'US' %>
|
||||
<h3>IMb Information</h3>
|
||||
<div class="grid md:grid-cols-2 gap-3">
|
||||
<dl class="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<strong>Serial:</strong>
|
||||
<code><%= @letter.imb_serial_number.to_s.rjust(6, '0') %></code>
|
||||
<dt class="text-gray-500">Cost</dt>
|
||||
<dd class="font-medium">
|
||||
<%= number_to_currency(@letter.usps_indicium.cost) %>
|
||||
<span class="text-gray-500 font-normal">(<%= number_to_currency(@letter.usps_indicium.postage) %> + <%= number_to_currency(@letter.usps_indicium.fees || 0) %> fees)</span>
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Epoch:</strong>
|
||||
<%= @letter.imb_rollover_count %>
|
||||
<dt class="text-gray-500">Mailing Date</dt>
|
||||
<dd><%= @letter.usps_indicium.mailing_date %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">USPS SKU</dt>
|
||||
<dd class="font-mono text-xs"><%= @letter.usps_indicium.usps_sku %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Indicium ID</dt>
|
||||
<dd class="font-mono text-xs"><%= @letter.usps_indicium.public_id %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
<%= render 'admin_inspector', record: @letter.usps_indicium %>
|
||||
<% else %>
|
||||
<div class="text-yellow-700 mb-4">
|
||||
<span class="font-medium">Indicia Not Purchased</span>
|
||||
</div>
|
||||
<% if @letter.batch_id.nil? %>
|
||||
<%= render 'buy_indicia_form', letter: @letter %>
|
||||
<% else %>
|
||||
<p class="text-sm text-gray-600">Postage will be purchased when processing the batch.</p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @letter.rubber_stamps.present? %>
|
||||
<article>
|
||||
<header>Rubber Stamps</header>
|
||||
<pre><%= @letter.rubber_stamps %></pre>
|
||||
</article>
|
||||
<% end %>
|
||||
<% elsif @letter.postage_type == "international_origin" %>
|
||||
<p class="text-sm text-gray-600">
|
||||
<strong>International Origin</strong> — Postage paid at origin (<%= @letter.return_address&.country %>)
|
||||
</p>
|
||||
<% else %>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm text-gray-600">Using physical stamps</p>
|
||||
<% if @letter.batch_id.nil? %>
|
||||
<%= button_to letter_path(@letter), method: :patch, params: { letter: { postage_type: "indicia" } }, class: "btn btn-small" do %>
|
||||
Switch to Indicia
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<% if @letter.batch.present? %>
|
||||
<%= render 'shared/batch_info', record: @letter %>
|
||||
<% end %>
|
||||
|
||||
<% if @letter.imb_serial_number.present? && @letter.address.country&.upcase == 'US' %>
|
||||
<article>
|
||||
<header><h2>IMb Tracking</h2></header>
|
||||
<div class="p-4">
|
||||
<dl class="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<dt class="text-gray-500">Serial</dt>
|
||||
<dd class="font-mono"><%= @letter.imb_serial_number.to_s.rjust(6, '0') %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Epoch</dt>
|
||||
<dd><%= @letter.imb_rollover_count %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
<%= render partial: "admin_inspector", locals: {record: @letter} %>
|
||||
</div>
|
||||
<div class="md:col-span-4">
|
||||
<article class="sticky top-4">
|
||||
<header>
|
||||
<h2>Actions</h2>
|
||||
</header>
|
||||
<div class="p-3">
|
||||
<% case @letter.aasm_state %>
|
||||
<% when 'pending' %>
|
||||
<% if @letter.label.attached? %>
|
||||
<div class="mb-4">
|
||||
<h3>Label</h3>
|
||||
<% end %>
|
||||
|
||||
<% if @letter.rubber_stamps.present? %>
|
||||
<article>
|
||||
<header><h2>Rubber Stamps</h2></header>
|
||||
<div class="p-4">
|
||||
<pre class="text-sm bg-gray-50 p-3 rounded overflow-auto"><%= @letter.rubber_stamps %></pre>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
|
||||
<%= render partial: "admin_inspector", locals: { record: @letter } %>
|
||||
</div>
|
||||
|
||||
<%# Sidebar %>
|
||||
<div class="md:col-span-4">
|
||||
<article class="sticky top-4">
|
||||
<header><h2>Actions</h2></header>
|
||||
<div class="p-4 space-y-4">
|
||||
<% case @letter.aasm_state %>
|
||||
<% when 'pending' %>
|
||||
<% if @letter.label.attached? %>
|
||||
<div>
|
||||
<div class="text-sm text-gray-500 mb-2">Label Ready</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<%= link_to rails_blob_path(@letter.label, disposition: 'inline'), class: "btn btn-small success", target: "_blank" do %>
|
||||
View Label
|
||||
<% end %>
|
||||
<%= button_to clear_label_letter_path(@letter), method: :post, class: "btn btn-small", data: { confirm: "Clear this label?" } do %>
|
||||
Clear
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-4">
|
||||
<%= button_to mark_printed_letter_path(@letter), method: :post, class: "btn success w-full" do %>
|
||||
Mark as Printed
|
||||
<% end %>
|
||||
<% elsif @letter.batch.present? %>
|
||||
<%= button_to mark_printed_letter_path(@letter), method: :post, class: "btn success w-full" do %>
|
||||
Mark as Printed
|
||||
<% end %>
|
||||
<% else %>
|
||||
<div>
|
||||
<div class="text-sm text-gray-500 mb-2">Generate Label</div>
|
||||
<%= form_tag(generate_label_letter_path(@letter), method: :post) do %>
|
||||
<div class="mb-3">
|
||||
<%= link_to "View Label", rails_blob_path(@letter.label, disposition: 'inline'), class: "primary", target: "_blank" %>
|
||||
<%= render 'shared/template_picker', multiple: false %>
|
||||
<input type="hidden" name="template" id="selected_template">
|
||||
</div>
|
||||
<div class="flex gap-2 mb-3">
|
||||
<%= button_to "Clear Label", clear_label_letter_path(@letter), method: :post, class: "contrast", data: { confirm: "Are you sure you want to clear this label?" } %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if @letter.batch.present? || @letter.label.attached? %>
|
||||
<div class="mb-4">
|
||||
<h3>Actions</h3>
|
||||
<div class="flex gap-2">
|
||||
<%= button_to mark_printed_letter_path(@letter), method: :post, class: "btn btn-sm success", id: 'mark_printed' do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
|
||||
</svg>
|
||||
mark printed!
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% elsif !@letter.batch.present? %>
|
||||
<div class="mb-4">
|
||||
<h3>Generate Label</h3>
|
||||
<%= form_tag(generate_label_letter_path(@letter), method: :post) do %>
|
||||
<div class="mb-3">
|
||||
<%= render 'shared/template_picker', multiple: false %>
|
||||
<input type="hidden" name="template" id="selected_template">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label>
|
||||
<input type="checkbox" name="qr" value="1" checked>
|
||||
Include QR Code
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-small success">
|
||||
Generate Label
|
||||
</button>
|
||||
<% end %>
|
||||
<% dev_tool do %>
|
||||
<%= link_to "preview label?", preview_template_letter_path(@letter) %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% when 'printed' %>
|
||||
<div class="mb-4">
|
||||
<h3>Label</h3>
|
||||
<%= button_to mark_mailed_letter_path(@letter), method: :post, class: "btn btn-sm success" do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
mark as mailed!
|
||||
<label class="flex items-center gap-2 text-sm mb-3">
|
||||
<input type="checkbox" name="qr" value="1" checked>
|
||||
Include QR Code
|
||||
</label>
|
||||
<button type="submit" class="btn success w-full">Generate Label</button>
|
||||
<% end %>
|
||||
<% dev_tool do %>
|
||||
<%= link_to "preview label?", preview_template_letter_path(@letter), class: "text-sm" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% when 'mailed' %>
|
||||
<div class="mb-4">
|
||||
<h3>Label</h3>
|
||||
<%= button_to "Mark as Received", mark_received_letter_path(@letter), method: :post, class: "success" %>
|
||||
</div>
|
||||
<% when 'received' %>
|
||||
<div class="mb-4">
|
||||
<h3>Label</h3>
|
||||
<p>Letter has been received.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% when 'printed' %>
|
||||
<%= button_to mark_mailed_letter_path(@letter), method: :post, class: "btn success w-full" do %>
|
||||
Mark as Mailed
|
||||
<% end %>
|
||||
<% when 'mailed' %>
|
||||
<%= button_to mark_received_letter_path(@letter), method: :post, class: "btn success w-full" do %>
|
||||
Mark as Received
|
||||
<% end %>
|
||||
<% when 'received' %>
|
||||
<div class="text-center text-green-600 py-4">
|
||||
✓ Letter received
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<% if @letter.label.attached? %>
|
||||
<%= render 'shared/instant_print_window', url: rails_blob_path(@letter.label, disposition: 'inline') %>
|
||||
<article class="mt-4">
|
||||
<header><h2>Label Preview</h2></header>
|
||||
<div class="p-4">
|
||||
<div class="border rounded overflow-hidden" style="height: 250px;">
|
||||
<iframe src="<%= rails_blob_path(@letter.label, disposition: 'inline') %>" class="w-full h-full border-0"></iframe>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<%= link_to rails_blob_path(@letter.label, disposition: "attachment"), class: "text-sm" do %>
|
||||
Download Label
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<% if @letter.label.attached? %>
|
||||
<%= render 'shared/instant_print_window', url: rails_blob_path(@letter.label, disposition: 'inline') %>
|
||||
<article class="mt-4">
|
||||
<header>
|
||||
<h2>Label Preview</h2>
|
||||
</header>
|
||||
<div class="p-3">
|
||||
<div class="mb-3">
|
||||
<%= link_to "Download Label", rails_blob_path(@letter.label, disposition: "attachment"), class: "secondary" %>
|
||||
</div>
|
||||
<div class="border rounded overflow-hidden" style="height: 300px;">
|
||||
<iframe src="<%= rails_blob_path(@letter.label, disposition: 'inline') %>" class="w-full h-full border-0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,52 +1,20 @@
|
|||
<div id="<%= dom_id indicium %>">
|
||||
<p>
|
||||
<strong>Processing category:</strong>
|
||||
<%= indicium.processing_category %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Postage weight:</strong>
|
||||
<%= indicium.postage_weight %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Postage length:</strong>
|
||||
<%= indicium.postage_length %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Postage height:</strong>
|
||||
<%= indicium.postage_height %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Postage thickness:</strong>
|
||||
<%= indicium.postage_thickness %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Nonmachinable:</strong>
|
||||
<%= indicium.nonmachinable %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>USPS sku:</strong>
|
||||
<%= indicium.usps_sku %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Raw USPS response:</strong>
|
||||
<%= indicium.raw_usps_response %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Postage:</strong>
|
||||
<%= indicium.postage %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Mailing date:</strong>
|
||||
<%= indicium.mailing_date %>
|
||||
</p>
|
||||
|
||||
<div id="<%= dom_id indicium %>" class="p-3 border rounded hover:bg-gray-50">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="font-mono text-sm"><%= indicium.public_id %></span>
|
||||
<span class="font-medium"><%= number_to_currency(indicium.postage) %></span>
|
||||
</div>
|
||||
<dl class="grid grid-cols-3 gap-2 text-sm text-gray-600">
|
||||
<div>
|
||||
<dt class="text-gray-400">SKU</dt>
|
||||
<dd class="font-mono text-xs"><%= indicium.usps_sku %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-400">Date</dt>
|
||||
<dd><%= indicium.mailing_date %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-400">Category</dt>
|
||||
<dd><%= indicium.processing_category %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,51 @@
|
|||
<% content_for :title, "Indicia" %>
|
||||
|
||||
<h1>Indicia</h1>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<h1>Indicia</h1>
|
||||
<div class="actions">
|
||||
<%= link_to new_usps_indicium_path, class: "btn success btn-small" do %>
|
||||
+ New Indicium
|
||||
<% end %>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div id="usps_indicia">
|
||||
<% @usps_indicia.each do |usps_indicium| %>
|
||||
<%= render usps_indicium %>
|
||||
<p>
|
||||
<%= link_to "Show this indicium", usps_indicium %>
|
||||
</p>
|
||||
<% if @usps_indicia.any? %>
|
||||
<article>
|
||||
<div class="p-4">
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-left py-2">ID</th>
|
||||
<th class="text-left py-2">SKU</th>
|
||||
<th class="text-left py-2">Postage</th>
|
||||
<th class="text-left py-2">Mailing Date</th>
|
||||
<th class="text-left py-2">Category</th>
|
||||
<th class="text-right py-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @usps_indicia.each do |indicium| %>
|
||||
<tr class="border-t hover:bg-gray-50">
|
||||
<td class="py-3 font-mono text-xs"><%= indicium.public_id %></td>
|
||||
<td class="py-3 font-mono text-xs"><%= indicium.usps_sku %></td>
|
||||
<td class="py-3"><%= number_to_currency(indicium.postage) %></td>
|
||||
<td class="py-3"><%= indicium.mailing_date %></td>
|
||||
<td class="py-3"><%= indicium.processing_category %></td>
|
||||
<td class="py-3 text-right">
|
||||
<%= link_to "View", usps_indicium_path(indicium), class: "text-sm" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</article>
|
||||
<% else %>
|
||||
<article>
|
||||
<div class="p-6 text-center text-gray-500">
|
||||
No indicia purchased yet.
|
||||
</div>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to "New indicium", new_usps_indicium_path %>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,77 @@
|
|||
<%= render @usps_indicium %>
|
||||
<%= render partial: "admin_inspector", locals: { record: @usps_indicium } %>
|
||||
<% content_for :title, "Indicium #{@usps_indicium.public_id}" %>
|
||||
|
||||
<div>
|
||||
<%= link_to "Edit this indicium", edit_usps_indicium_path(@usps_indicium) %> |
|
||||
<%= link_to "Back to indicia", usps_indicia_path %>
|
||||
<div class="container">
|
||||
<header class="page-header mb-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= link_to "← Back", usps_indicia_path, class: "text-gray-500 hover:text-gray-700" %>
|
||||
<div>
|
||||
<h1>Indicium</h1>
|
||||
<div class="text-sm text-gray-500 font-mono"><%= @usps_indicium.public_id %></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions flex gap-2">
|
||||
<%= link_to edit_usps_indicium_path(@usps_indicium), class: "btn btn-small" do %>
|
||||
Edit
|
||||
<% end %>
|
||||
<%= button_to usps_indicium_path(@usps_indicium), method: :delete, class: "btn danger btn-small", data: { confirm: "Delete this indicium?" } do %>
|
||||
Delete
|
||||
<% end %>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<%= button_to "Destroy this indicium", @usps_indicium, method: :delete %>
|
||||
<div class="max-w-2xl">
|
||||
<article>
|
||||
<header><h2>Postage Details</h2></header>
|
||||
<div class="p-4">
|
||||
<dl class="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<dt class="text-gray-500">Postage</dt>
|
||||
<dd class="font-medium text-lg"><%= number_to_currency(@usps_indicium.postage) %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Mailing Date</dt>
|
||||
<dd><%= @usps_indicium.mailing_date %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">USPS SKU</dt>
|
||||
<dd class="font-mono text-xs"><%= @usps_indicium.usps_sku %></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Processing Category</dt>
|
||||
<dd><%= @usps_indicium.processing_category %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="mt-6">
|
||||
<header><h2>Dimensions</h2></header>
|
||||
<div class="p-4">
|
||||
<dl class="grid md:grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<dt class="text-gray-500">Weight</dt>
|
||||
<dd><%= @usps_indicium.postage_weight %> oz</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Length</dt>
|
||||
<dd><%= @usps_indicium.postage_length %>"</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Height</dt>
|
||||
<dd><%= @usps_indicium.postage_height %>"</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Thickness</dt>
|
||||
<dd><%= @usps_indicium.postage_thickness %>"</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="text-gray-500">Non-machinable</dt>
|
||||
<dd><%= @usps_indicium.nonmachinable ? "Yes" : "No" %></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<%= render partial: "admin_inspector", locals: { record: @usps_indicium } %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue