Items can now be marked as "requires delivery" in admin — these items cannot be picked up and must be delivered (and struck). - Admin item editor: "Requires delivery" checkbox + custom base/per-mile rate fields that appear when the toggle is on - ProductCard: "Delivery & setup required" note on the card - CartDrawer: pickup toggle is hidden and replaced with an explanation when any cart item requires delivery; the quote call passes the item's custom rate override (highest base + highest per-mile wins when multiple requires-delivery items are in the cart) - delivery-quote API: accepts optional rateOverride to apply per-item pricing on top of the inferred tier Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import { geocode, calcDelivery, inferTier } from '@/lib/delivery'
|
|
import { readDeliveryRates } from '@/lib/delivery-rates'
|
|
|
|
export async function POST(request: Request) {
|
|
const { address, itemNames, rateOverride } = await request.json() as {
|
|
address: string
|
|
itemNames: string[]
|
|
rateOverride?: { base: number; perMile: number }
|
|
}
|
|
|
|
if (!address?.trim()) {
|
|
return NextResponse.json({ error: 'Address required' }, { status: 400 })
|
|
}
|
|
|
|
const coords = await geocode(address)
|
|
if (!coords) {
|
|
return NextResponse.json({ error: 'Address not found — please try a more specific address.' }, { status: 422 })
|
|
}
|
|
|
|
const tier = inferTier(itemNames ?? [])
|
|
const rates = readDeliveryRates()
|
|
|
|
// Apply per-item rate override if provided (overrides just base and perMile for the inferred tier)
|
|
if (rateOverride) {
|
|
rates[tier] = {
|
|
...rates[tier],
|
|
base: rateOverride.base,
|
|
perMile: rateOverride.perMile,
|
|
}
|
|
}
|
|
|
|
const quote = await calcDelivery(coords.lat, coords.lng, tier, rates)
|
|
|
|
if (quote.miles > 40) {
|
|
return NextResponse.json(
|
|
{
|
|
error: `This address is ${quote.miles.toFixed(1)} miles away — online scheduling is available within 40 miles. Please contact us directly to arrange delivery.`,
|
|
tooFar: true,
|
|
},
|
|
{ status: 422 }
|
|
)
|
|
}
|
|
|
|
return NextResponse.json(quote)
|
|
}
|