Diff -- /var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_sales_reports.html
Diff

/var/www/vhosts/webstls.com/httpdocs/TEMPLATES/webstls_sales_reports.html

added on WebSTLs (webstls.com) at 2026-07-01 22:27:04

Added
+272
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 9818f1257a01
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
1<!-- =====================================================================
2 SALES REPORTS — /sales_reports.cgi
3 Merged dashboard + analytics + audience into one tabbed page.
4
5 Tabs (selected via ?tab=NAME, default 'overview'):
6 overview / channels / buyers / products
7===================================================================== -->
8
9<style>
10 .sr-head { display:flex;align-items:flex-end;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:18px; }
11 .sr-tabs { display:flex;gap:0;border-bottom:1px solid var(--col-border);margin-bottom:24px;flex-wrap:wrap; }
12 .sr-tab { padding:10px 18px;font-size:13px;font-weight:600;color:var(--col-text-2);text-decoration:none;border-bottom:2px solid transparent;letter-spacing:0.3px;transition:all 0.15s; }
13 .sr-tab:hover { color:var(--col-text);background:var(--col-surface-2); }
14 .sr-tab.is-active { color:var(--col-accent-bright);border-bottom-color:var(--col-accent); }
15
16 .sr-kpi-grid { display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-bottom:24px; }
17 .sr-kpi { background:var(--col-surface-1);border:1px solid var(--col-border);border-radius:14px;padding:18px 20px; }
18 .sr-kpi-label { font-size:11px;font-weight:700;color:var(--col-text-3);letter-spacing:1.2px;text-transform:uppercase;margin-bottom:6px; }
19 .sr-kpi-value { font-family:var(--font-display,sans-serif);font-size:30px;color:var(--col-text);line-height:1; }
20 .sr-kpi-sub { font-size:11.5px;color:var(--col-text-3);margin-top:8px; }
21 .sr-kpi-delta { display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:8px;font-size:11px;font-weight:700;margin-top:8px; }
22 .sr-kpi-delta.up { background:rgba(34,197,94,0.15);color:#4ade80;border:1px solid rgba(34,197,94,0.32); }
23 .sr-kpi-delta.down { background:rgba(239,68,68,0.15);color:#f87171;border:1px solid rgba(239,68,68,0.32); }
24
25 .sr-card { background:var(--col-surface-1);border:1px solid var(--col-border);border-radius:14px;padding:22px;margin-bottom:16px; }
26 .sr-card-title { font-family:var(--font-display,sans-serif);font-size:20px;color:var(--col-text);margin:0 0 6px; }
27 .sr-card-sub { font-size:12px;color:var(--col-text-3);margin-bottom:18px; }
28
29 .sr-channel-grid { display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px; }
30 .sr-channel { background:var(--col-surface-2);border:1px solid var(--col-border);border-radius:12px;padding:16px;display:flex;flex-direction:column;gap:8px; }
31 .sr-channel-head { display:flex;align-items:center;gap:10px; }
32 .sr-channel-icon { width:36px;height:36px;border-radius:9px;background:linear-gradient(135deg,var(--col-accent),var(--col-accent-deep));color:#fff;display:flex;align-items:center;justify-content:center;font-family:var(--font-display,sans-serif);font-weight:700;font-size:15px;flex-shrink:0; }
33 .sr-channel-name { font-size:14px;font-weight:700;color:var(--col-text);line-height:1.2; }
34 .sr-channel-meta { font-size:11px;color:var(--col-text-3);margin-top:2px; }
35 .sr-channel-rev { font-family:var(--font-display,sans-serif);font-size:24px;color:var(--col-accent-bright);line-height:1; }
36 .sr-channel-orders { font-size:12px;color:var(--col-text-2); }
37 .sr-pill { display:inline-block;padding:2px 8px;border-radius:10px;font-size:10px;font-weight:700;letter-spacing:0.4px; }
38 .sr-pill.live { background:rgba(34,197,94,0.15);color:#4ade80;border:1px solid rgba(34,197,94,0.32); }
39 .sr-pill.awaiting{ background:rgba(245,158,11,0.13);color:#fbbf24;border:1px solid rgba(245,158,11,0.30); }
40
41 .sr-buyer-grid { display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:18px; }
42 .sr-buyer-stat { background:var(--col-surface-2);border:1px solid var(--col-border);border-radius:11px;padding:14px 16px; }
43 .sr-buyer-stat-num { font-family:var(--font-display,sans-serif);font-size:26px;color:var(--col-text);line-height:1; }
44 .sr-buyer-stat-lbl { font-size:11px;color:var(--col-text-3);letter-spacing:0.8px;text-transform:uppercase;margin-top:4px; }
45
46 table.sr-table { width:100%;border-collapse:collapse; }
47 table.sr-table th { text-align:left;padding:10px 12px;font-size:11px;font-weight:700;color:var(--col-text-3);letter-spacing:1px;text-transform:uppercase;border-bottom:1px solid var(--col-border); }
48 table.sr-table td { padding:12px;font-size:13px;color:var(--col-text-2);border-bottom:1px solid var(--col-border); }
49 table.sr-table tr:last-child td { border-bottom:none; }
50 table.sr-table tr:hover td { background:var(--col-surface-2);color:var(--col-text); }
51 .sr-avatar { width:32px;height:32px;border-radius:50%;background:linear-gradient(135deg,#10b981,#059669);color:#fff;font-weight:700;font-size:12px;display:inline-flex;align-items:center;justify-content:center;margin-right:10px;vertical-align:middle; }
52 .sr-prod-thumb { width:44px;height:44px;border-radius:7px;object-fit:cover;background:var(--col-surface-2);vertical-align:middle;margin-right:10px; }
53
54 .sr-empty { background:var(--col-surface-1);border:1px solid var(--col-border);border-radius:14px;padding:40px;text-align:center;color:var(--col-text-3); }
55 .sr-empty h2 { font-family:var(--font-display,sans-serif);font-size:22px;color:var(--col-text);margin:0 0 8px; }
56 .sr-empty p { margin:0;line-height:1.55;font-size:13.5px; }
57</style>
58
59
60<div class="sr-head">
61 <div>
62 <span class="page-eyebrow"><span class="dot"></span> Reporting</span>
63 <h1 class="page-title">Sales reports</h1>
64 <p class="page-subtitle">Revenue, marketplaces, buyers, and top products &mdash; all in one place.</p>
65 </div>
66</div>
67
68<!-- Tab nav -->
69<div class="sr-tabs">
70 <a class="sr-tab[if:$tab_overview] is-active[/if]" href="/sales_reports.cgi?tab=overview">Overview</a>
71 <a class="sr-tab[if:$tab_channels] is-active[/if]" href="/sales_reports.cgi?tab=channels">Marketplaces</a>
72 <a class="sr-tab[if:$tab_buyers] is-active[/if]" href="/sales_reports.cgi?tab=buyers">Buyers</a>
73 <a class="sr-tab[if:$tab_products] is-active[/if]" href="/sales_reports.cgi?tab=products">Products</a>
74 <a class="sr-tab[if:$tab_tax] is-active[/if]" href="/sales_reports.cgi?tab=tax">Tax</a>
75</div>
76
77
78<!-- ============ OVERVIEW ============ -->
79[if:$tab_overview]
80[if:!$has_storefront]
81<div class="sr-empty">
82 <h2>No storefront yet</h2>
83 <p>Set up your storefront to start tracking sales here.</p>
84</div>
85[/if]
86[if:$has_storefront]
87[if:$has_daily_sales]<script>window.SALES_DAILY_SERIES = $daily_sales_json;</script>[/if]
88<div class="sr-kpi-grid">
89 <div class="sr-kpi" data-kpi-detail='{"eyebrow":"Revenue . today","description":"Total dollar value of every paid order across your storefronts since midnight UTC.","methodology":"<code>SUM(orders.total_amount_cents) WHERE storefront_id IN (your storefronts) AND status=&#39;paid&#39; AND DATE(paid_at) = CURDATE()</code>. Only orders that successfully completed payment are counted -- pending and failed orders are excluded.","interpretation":"Use today vs. the same weekday last week as your comparison, not yesterday. STL sales swing hard by weekday -- a quiet Tuesday after a busy Sunday is normal seasonality, not a slowdown.","seriesGlobal":"SALES_DAILY_SERIES","seriesKey":"revenue","chartColor":"#4ade80","chartLabel":"Revenue ($)","chartTitle":"Daily revenue, last 30 days"}'>
90 <div class="sr-kpi-label">Revenue today</div>
91 <div class="sr-kpi-value">$rev_today</div>
92 <div class="sr-kpi-sub">$orders_today order(s) so far today</div>
93 </div>
94 <div class="sr-kpi" data-kpi-detail='{"eyebrow":"Revenue . month-to-date","description":"Total paid order value across your storefronts since the first of this calendar month.","methodology":"<code>SUM(orders.total_amount_cents) WHERE storefront_id IN (your storefronts) AND status=&#39;paid&#39; AND paid_at &gt;= DATE_FORMAT(CURDATE(), &#39;%Y-%m-01&#39;)</code>.","interpretation":"Pair this with the 30d delta below to see whether the month is pacing ahead of or behind the prior 30-day window. Same-day-of-month comparisons against the previous month are the cleanest signal -- if day 14 this month beats day 14 last, you are growing.","seriesGlobal":"SALES_DAILY_SERIES","seriesKey":"revenue","chartColor":"#22c55e","chartLabel":"Revenue ($)","chartTitle":"Daily revenue, last 30 days"}'>
95 <div class="sr-kpi-label">Revenue MTD</div>
96 <div class="sr-kpi-value">$rev_mtd</div>
97 <div class="sr-kpi-sub">$orders_mtd order(s) this month</div>
98 </div>
99 <div class="sr-kpi" data-kpi-detail='{"eyebrow":"Revenue . rolling 30 days","description":"Total paid order value across your storefronts over the trailing 30-day window, plus the percentage change against the prior 30-day window.","methodology":"<code>SUM(orders.total_amount_cents) WHERE paid_at &gt;= NOW() - INTERVAL 30 DAY</code>. The delta percentage compares this against the same query for the previous 30 days (60-30 days ago).","interpretation":"The most stable headline number -- a rolling window smooths weekday noise. A positive delta is growth, negative is contraction. Big swings usually correlate with marketplace launches, new model releases, or promotional pushes.","seriesGlobal":"SALES_DAILY_SERIES","seriesKey":"revenue","chartColor":"#10b981","chartLabel":"Revenue ($)","chartTitle":"Daily revenue, last 30 days"}'>
100 <div class="sr-kpi-label">Revenue (30d)</div>
101 <div class="sr-kpi-value">$rev_30d</div>
102 [if:$has_delta][if:$delta_dir_up]<div class="sr-kpi-delta up">&uarr; $delta_pct% vs prior 30d</div>[/if][if:$delta_dir_down]<div class="sr-kpi-delta down">&darr; $delta_pct% vs prior 30d</div>[/if][/if]
103 [if:!$has_delta]<div class="sr-kpi-sub">No prior period yet</div>[/if]
104 </div>
105 <div class="sr-kpi" data-kpi-detail='{"eyebrow":"Average order value . last 30 days","description":"Mean dollar amount of each paid order across your storefronts in the trailing 30 days.","methodology":"<code>SUM(orders.total_amount_cents) / COUNT(orders) WHERE paid_at &gt;= NOW() - INTERVAL 30 DAY AND status=&#39;paid&#39;</code>.","interpretation":"Drives pricing strategy. Rising AOV with steady order count = buyers picking premium items or buying bundles. Falling AOV with rising order count = volume is up but on cheaper items, so consider an upsell or bundle promotion. Use the Marketplaces tab to see whether AOV varies by channel.","seriesGlobal":"SALES_DAILY_SERIES","seriesKey":"orders","chartColor":"#3b82f6","chartLabel":"Orders","chartTitle":"Daily order count, last 30 days"}'>
106 <div class="sr-kpi-label">Avg order value</div>
107 <div class="sr-kpi-value">$aov</div>
108 <div class="sr-kpi-sub">Last 30 days &middot; $orders_30d orders</div>
109 </div>
110</div>
111
112<div class="sr-card">
113 <div class="sr-card-title">Recent sales</div>
114 <div class="sr-card-sub">The 30 most recent paid orders across every storefront you own</div>
115 [if:$has_recent_sales]
116 <table class="sr-table">
117 <thead>
118 <tr>
119 <th>Date</th>
120 <th>Buyer</th>
121 <th>What they bought</th>
122 <th style="text-align:right">Amount</th>
123 </tr>
124 </thead>
125 <tbody>
126 [loop:@recent_sales]
127 <tr>
128 <td style="white-space:nowrap;color:var(--col-text-3);font-size:12px">$loop1.date</td>
129 <td><strong style="color:var(--col-text)">$loop1.buyer_safe</strong></td>
130 <td title="$loop1.items_full">$loop1.items_safe</td>
131 <td style="text-align:right;font-family:var(--font-mono,monospace);color:var(--col-accent-bright);font-weight:600">$loop1.amount</td>
132 </tr>
133 [/loop]
134 </tbody>
135 </table>
136 [/if]
137 [if:!$has_recent_sales]
138 <div style="color:var(--col-text-3);padding:30px;text-align:center">No sales yet. Once a buyer checks out, every order will land here in real time.</div>
139 [/if]
140</div>
141[/if]
142[/if]
143
144
145<!-- ============ CHANNELS ============ -->
146[if:$tab_channels]
147[if:$has_daily_sales]<script>window.SALES_DAILY_SERIES = $daily_sales_json;</script>[/if]
148[if:!$has_channels]
149<div class="sr-empty"><h2>No marketplaces yet</h2><p>Your WebSTLs storefront appears here once it&#39;s live, plus every marketplace you connect.</p></div>
150[/if]
151[if:$has_channels]
152<div class="sr-channel-grid">
153 [loop:@channels]
154 <div class="sr-channel" data-kpi-detail='$loop1.kpi_detail'>
155 <div class="sr-channel-head">
156 <div class="sr-channel-icon">$loop1.icon</div>
157 <div style="flex:1;min-width:0">
158 <div class="sr-channel-name">$loop1.name</div>
159 <div class="sr-channel-meta">[if:$loop1.is_live]<span class="sr-pill live">Live</span>[/if][if:$loop1.is_awaiting]<span class="sr-pill awaiting">Awaiting adapter</span>[/if] &middot; $loop1.fee_pct</div>
160 </div>
161 </div>
162 <div class="sr-channel-rev">$loop1.revenue</div>
163 <div class="sr-channel-orders">$loop1.orders order(s) &middot; 30d</div>
164 </div>
165 [/loop]
166</div>
167[/if]
168[/if]
169
170
171<!-- ============ BUYERS ============ -->
172[if:$tab_buyers]
173[if:$has_daily_buyers]<script>window.BUYERS_DAILY_SERIES = $daily_buyers_json;</script>[/if]
174<div class="sr-buyer-grid">
175 <div class="sr-buyer-stat" data-kpi-detail='{"eyebrow":"Total buyers . all-time","description":"Number of distinct buyer email addresses that have ever placed a paid order on any of your storefronts.","methodology":"<code>COUNT(DISTINCT buyer_email) WHERE storefront_id IN (your storefronts) AND status=&#39;paid&#39;</code>. Email is the dedupe key, so the same person buying with two different emails counts twice.","interpretation":"Your reachable audience. Repeat buyers are the leverage -- a 5% retention bump usually outperforms a 5% acquisition bump. Use Top buyers by lifetime value below to identify who to nurture.","seriesGlobal":"BUYERS_DAILY_SERIES","seriesKey":"new_buyers","chartColor":"#a78bfa","chartLabel":"New buyers","chartTitle":"New buyers per day, last 30 days"}'><div class="sr-buyer-stat-num">$total_buyers</div><div class="sr-buyer-stat-lbl">Total buyers</div></div>
176 <div class="sr-buyer-stat" data-kpi-detail='{"eyebrow":"New buyers . last 30 days","description":"Distinct buyer emails that placed their FIRST order on any of your storefronts in the last 30 days.","methodology":"<code>COUNT(DISTINCT buyer_email)</code> for orders in the last 30d where the same buyer_email has no earlier orders. Implemented with a NOT EXISTS subquery against orders older than 30 days.","interpretation":"Top-of-funnel growth signal. Rising new-buyer count means your acquisition channels (storefront SEO, marketplaces, promotions) are working. Compare against the 30d revenue to see whether new buyers are spending at typical AOV or below.","seriesGlobal":"BUYERS_DAILY_SERIES","seriesKey":"new_buyers","chartColor":"#22c55e","chartLabel":"New buyers","chartTitle":"New buyers per day, last 30 days"}'><div class="sr-buyer-stat-num">$new_30d_buyers</div><div class="sr-buyer-stat-lbl">New (30d)</div></div>
177 <div class="sr-buyer-stat" data-kpi-detail='{"eyebrow":"Repeat buyers . 3+ orders","description":"Distinct buyer emails that have placed three or more paid orders in your storefronts, all-time. The 3-order threshold filters out one-time impulse buys and accidental dupes.","methodology":"<code>COUNT(*) FROM (SELECT buyer_email FROM orders WHERE status=&#39;paid&#39; GROUP BY buyer_email HAVING COUNT(*) &gt;= 3) t</code>.","interpretation":"Your loyal base. These are the people most likely to buy your next release without any prompting. Treat repeat-buyer count as a leading indicator of long-term revenue stability.","seriesGlobal":"BUYERS_DAILY_SERIES","seriesKey":"new_buyers","chartColor":"#3b82f6","chartLabel":"New buyers","chartTitle":"New buyers per day, last 30 days (context)"}'><div class="sr-buyer-stat-num">$repeat_buyers</div><div class="sr-buyer-stat-lbl">Repeat (3+ orders)</div></div>
178 <div class="sr-buyer-stat" data-kpi-detail='{"eyebrow":"Recent buyers . active in last 30 days","description":"Distinct buyer emails that have placed at least one paid order in the last 30 days, regardless of whether they are new or returning.","methodology":"<code>COUNT(DISTINCT buyer_email) WHERE paid_at &gt;= NOW() - INTERVAL 30 DAY AND status=&#39;paid&#39;</code>.","interpretation":"This is the right audience for time-sensitive promotions -- they are already in your buying loop. Compare this to Total buyers to see how much of your reachable audience is currently active.","seriesGlobal":"BUYERS_DAILY_SERIES","seriesKey":"new_buyers","chartColor":"#06b6d4","chartLabel":"New buyers","chartTitle":"New buyers per day, last 30 days"}'><div class="sr-buyer-stat-num">$seg_recent</div><div class="sr-buyer-stat-lbl">Recent (30d active)</div></div>
179 <div class="sr-buyer-stat" data-kpi-detail='{"eyebrow":"Lapsed buyers . 90+ days inactive","description":"Buyer emails whose most recent paid order was more than 90 days ago.","methodology":"<code>COUNT(*) FROM (SELECT buyer_email, MAX(paid_at) AS last_seen FROM orders WHERE status=&#39;paid&#39; GROUP BY buyer_email HAVING last_seen &lt; NOW() - INTERVAL 90 DAY) t</code>.","interpretation":"Your win-back list. A targeted email to lapsed buyers with a small discount or a new-release teaser routinely outperforms cold-acquisition spend per dollar. The bigger this number relative to Total buyers, the higher the leverage from a re-engagement push.","seriesGlobal":"BUYERS_DAILY_SERIES","seriesKey":"new_buyers","chartColor":"#f97316","chartLabel":"New buyers","chartTitle":"New buyers per day, last 30 days (context)"}'><div class="sr-buyer-stat-num">$seg_lapsed</div><div class="sr-buyer-stat-lbl">Lapsed (90d+ gone)</div></div>
180</div>
181
182<div class="sr-card">
183 <div class="sr-card-title">Top buyers by lifetime value</div>
184 <div class="sr-card-sub">Highest-LTV customers across every storefront you own</div>
185 [if:$has_top_buyers]
186 <table class="sr-table">
187 <thead><tr><th>Buyer</th><th>Orders</th><th>LTV</th><th>Last seen</th></tr></thead>
188 <tbody>
189 [loop:@top_buyers]
190 <tr>
191 <td><span class="sr-avatar">$loop1.initials</span>$loop1.email_safe</td>
192 <td>$loop1.orders</td>
193 <td><strong style="color:var(--col-accent-bright)">$loop1.ltv</strong></td>
194 <td style="color:var(--col-text-3)">$loop1.last_seen_pretty</td>
195 </tr>
196 [/loop]
197 </tbody>
198 </table>
199 [/if]
200 [if:!$has_top_buyers]<div style="color:var(--col-text-3);padding:30px;text-align:center">No paid orders yet. Top buyers appear here as soon as you have sales.</div>[/if]
201</div>
202[/if]
203
204
205<!-- ============ PRODUCTS ============ -->
206[if:$tab_products]
207<div class="sr-card">
208 <div class="sr-card-title">Top-selling products</div>
209 <div class="sr-card-sub">Ranked by 30-day revenue across every channel</div>
210 [if:$has_top_products]
211 <table class="sr-table">
212 <thead><tr><th></th><th>Title</th><th>Units</th><th>Orders</th><th>Revenue</th></tr></thead>
213 <tbody>
214 [loop:@top_products]
215 <tr>
216 <td><img class="sr-prod-thumb" src="$loop1.hero" alt=""></td>
217 <td><strong style="color:var(--col-text)">$loop1.title_safe</strong></td>
218 <td>$loop1.units</td>
219 <td>$loop1.orders</td>
220 <td><strong style="color:var(--col-accent-bright)">$loop1.revenue</strong></td>
221 </tr>
222 [/loop]
223 </tbody>
224 </table>
225 [/if]
226 [if:!$has_top_products]<div style="color:var(--col-text-3);padding:30px;text-align:center">No sales data yet. Top products will populate once orders come in.</div>[/if]
227</div>
228[/if]
229
230
231<!-- ============ TAX ============ -->
232[if:$tab_tax]
233<div class="sr-card">
234 <div class="sr-card-title">Tax collected on your sales</div>
235 [if:$mode_is_platform]
236 <div class="sr-card-sub" style="color:var(--col-text-2)">
237 Your storefront is on <strong style="color:#4ade80">Platform-collected</strong> mode &mdash; WebSTLs is the legal merchant of record for tax purposes. We calculate the right rate at checkout, collect it from your buyers, and remit to each jurisdiction on your behalf. You don't need to file VAT / sales-tax returns yourself for any jurisdiction below.
238 </div>
239 [/if]
240 [if:$mode_is_self]
241 <div class="sr-card-sub" style="color:var(--col-text-2)">
242 Your storefront is on <strong style="color:#fbbf24">Seller-handled</strong> mode &mdash; you connected your own merchant account and you're the merchant of record. WebSTLs does NOT collect or remit tax on your behalf. The table below is informational only; use it to compare against your own books.
243 </div>
244 [/if]
245
246 <div style="font-size:14px;color:var(--col-text-3);margin:14px 0 12px">
247 Total tax collected (all-time): <strong style="color:var(--col-text);font-size:18px">$tax_total</strong> &middot; across <strong>$tax_total_orders</strong> orders
248 </div>
249 [if:$has_tax_rows]
250 <table class="sr-table">
251 <thead><tr><th>Country</th><th>Region</th><th>Jurisdiction</th><th>Type</th><th style="text-align:right">Rate</th><th style="text-align:right">Orders</th><th style="text-align:right">Taxable</th><th style="text-align:right">Tax</th></tr></thead>
252 <tbody>
253 [loop:@tax_rows]
254 <tr>
255 <td style="font-family:var(--font-mono,monospace)"><strong style="color:var(--col-text)">$loop1.country</strong></td>
256 <td style="font-family:var(--font-mono,monospace);color:var(--col-text-3)">$loop1.region</td>
257 <td>$loop1.label</td>
258 <td>$loop1.type</td>
259 <td style="text-align:right;font-family:var(--font-mono,monospace)">$loop1.rate%</td>
260 <td style="text-align:right">$loop1.orders</td>
261 <td style="text-align:right;font-family:var(--font-mono,monospace)">$loop1.taxable</td>
262 <td style="text-align:right;font-family:var(--font-mono,monospace);font-weight:700;color:var(--col-text)">$loop1.tax</td>
263 </tr>
264 [/loop]
265 </tbody>
266 </table>
267 [/if]
268 [if:!$has_tax_rows]<div style="color:var(--col-text-3);padding:30px;text-align:center">No tax has been collected on your orders yet. Once a buyer in a jurisdiction WebSTLs is registered for completes a sale, the breakdown will appear here.</div>[/if]
269</div>
270[/if]
271
272<div class="sr-foot-spacer" data-end="sales-reports">&nbsp;</div>
Keyboard: j next diff k previous diff g top G bottom r restore c compile-check ? help