Fix "$652.89/hr" on Variable-rate meters (display only)
Waterfront zones (BS/WB/RV/PB/CB) use RateType "Variable" with a placeholder
Rate 652.89 ("Variable Rate - See signs"), not an hourly price. Only render $/hr
for the real "Hour" rate type; show "Variable — see signs" otherwise, and derive
the headline Rate from the current policy instead of the raw zone Rate ("NA"/652.89).
Actual quoting is unaffected — the estimate ladder returns sane per-duration prices.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d1473f9776
commit
a5bfec894e
1 changed files with 26 additions and 4 deletions
|
|
@ -17,10 +17,28 @@ function fmtMaxTime(m?: number): string {
|
|||
return `${m} min`;
|
||||
}
|
||||
|
||||
/** Zone rate comes as a string that sometimes already includes a '$' and spaces. */
|
||||
/** Zone rate is a string that may include '$'/spaces, or be "NA" / a placeholder. */
|
||||
function fmtRate(r?: string): string | undefined {
|
||||
if (r == null) return undefined;
|
||||
return '$' + String(r).replace(/^\$\s*/, '').trim();
|
||||
const n = Number(String(r).replace(/^\$\s*/, '').trim());
|
||||
return Number.isFinite(n) ? `$${n.toFixed(2)}` : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* A human rate label from the CURRENTLY-active policy. Only "Hour" is a real
|
||||
* hourly price; "Variable" carries a placeholder number (see-signs), so never
|
||||
* render it as $/hr.
|
||||
*/
|
||||
function currentRateLabel(policy: SpacePolicy | undefined, zoneRate?: string): string {
|
||||
const t = (policy?.RateType ?? '').toLowerCase();
|
||||
if (t === 'hour' && typeof policy?.Rate === 'number' && policy.Rate > 0) {
|
||||
return `$${policy.Rate}/hr`;
|
||||
}
|
||||
if (t.includes('variable')) return 'Variable — see signs';
|
||||
if (t.includes('free')) return 'Free now';
|
||||
if (t.includes('no parking')) return 'No parking now';
|
||||
if (t.includes('prepay')) return 'Prepay';
|
||||
return fmtRate(zoneRate) ?? '—';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -36,7 +54,10 @@ function policyMeta(p: SpacePolicy): { title: string; rate?: string; color?: str
|
|||
? '#2e7d32'
|
||||
: undefined;
|
||||
const title = p.DisplayString || p.MessageHeader || p.RateType || 'Rate policy';
|
||||
const rate = typeof p.Rate === 'number' && p.Rate > 0 ? `$${p.Rate}/hr` : undefined;
|
||||
// Only a true "Hour" policy is an hourly price; "Variable" etc. carry a
|
||||
// placeholder number, so don't render those as $/hr.
|
||||
const rate =
|
||||
rt === 'hour' && typeof p.Rate === 'number' && p.Rate > 0 ? `$${p.Rate}/hr` : undefined;
|
||||
return { title, rate, color };
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +77,7 @@ export function MeterDetailScreen() {
|
|||
};
|
||||
|
||||
const firstSpace = z.Spaces?.[0];
|
||||
const currentPolicy = firstSpace?.Policies?.find((p) => p.CurrentSlot);
|
||||
|
||||
const Field = ({ label, value }: { label: string; value?: string }) => (
|
||||
<View style={[styles.field, { backgroundColor: colors.card }]}>
|
||||
|
|
@ -81,7 +103,7 @@ export function MeterDetailScreen() {
|
|||
<Field label="Serial" value={z.TerminalSerNo} />
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Field label="Rate" value={fmtRate(z.Rate)} />
|
||||
<Field label="Rate" value={currentRateLabel(currentPolicy, z.Rate)} />
|
||||
<Field label="Max time" value={fmtMaxTime(z.MaxTime)} />
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue