@@ -123,22 +123,28 @@ export default async function AdminSettings() {
123123 < section id = "section-shipping" className = "scroll-mt-32" >
124124 < SettingsForm action = { updateShippingSettings } title = "Shipping Rate Configuration" iconName = "truck" >
125125 < p className = "text-[11px] text-luxury-subtext leading-relaxed" >
126- Configure the flat-rate shipping prices shown to customers at checkout. Stripe collects the customer address — Shippo is only called by admin at fulfillment .
126+ Configure the weight-based shipping prices shown to customers at checkout. Brackets are evaluated from lowest weight to highest. Set `max_lb` to 999 for the catch-all bracket .
127127 </ p >
128128
129- < div className = "grid grid-cols-1 md:grid-cols-2 gap-8" >
129+ < div className = "grid grid-cols-1 gap-8" >
130130 < div className = "p-6 bg-white/5 rounded-xl border border-white/5 space-y-4" >
131131 < div className = "flex items-center gap-3" >
132132 < Package className = "w-4 h-4 text-white" />
133- < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > Standard</ p >
134- </ div >
135- < div className = "relative" >
136- < span className = "absolute left-4 top-1/2 -translate-y-1/2 text-luxury-subtext text-sm" > $</ span >
137- < input name = "standard_rate" type = "number" step = "0.01" defaultValue = { shipping . standard_rate ?? '7.99' }
138- className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md pl-8 pr-4 py-3 text-sm text-white focus:border-gold/50 outline-none transition-all" />
133+ < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > US Domestic Standard</ p >
139134 </ div >
140- < input name = "standard_label" type = "text" defaultValue = { shipping . standard_label ?? 'Standard Shipping (5-10 Business Days)' }
135+ < input name = "standard_label" type = "text" defaultValue = { shipping . standard_label ?? 'USPS Ground Advantage (3-5 Days)' }
141136 className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-sm text-white focus:border-gold/50 outline-none transition-all" />
137+ < div className = "space-y-1.5" >
138+ < label className = "text-[9px] uppercase tracking-luxury text-luxury-subtext font-medium" > Weight Brackets (JSON) Default: [ { `{"max_lb": 0.5, "rate": 4.99}` } ... ]</ label >
139+ < textarea name = "weight_brackets" defaultValue = { JSON . stringify ( shipping . weight_brackets || [
140+ { max_lb : 0.5 , rate : 4.99 } ,
141+ { max_lb : 1 , rate : 6.99 } ,
142+ { max_lb : 2 , rate : 8.99 } ,
143+ { max_lb : 5 , rate : 12.99 } ,
144+ { max_lb : 999 , rate : 15.99 }
145+ ] , null , 2 ) }
146+ rows = { 5 } className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-xs font-mono text-emerald-400 focus:border-gold/50 outline-none transition-all" />
147+ </ div >
142148 < div className = "space-y-1.5" >
143149 < label className = "text-[9px] uppercase tracking-luxury text-luxury-subtext font-medium" > Free Shipping Threshold</ label >
144150 < input name = "free_shipping_threshold" type = "number" step = "0.01" defaultValue = { shipping . free_shipping_threshold ?? '100' }
@@ -149,22 +155,60 @@ export default async function AdminSettings() {
149155 < div className = "p-6 bg-white/5 rounded-xl border border-white/5 space-y-4" >
150156 < div className = "flex items-center gap-3" >
151157 < Truck className = "w-4 h-4 text-gold" />
152- < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > Express</ p >
153- </ div >
154- < div className = "relative" >
155- < span className = "absolute left-4 top-1/2 -translate-y-1/2 text-luxury-subtext text-sm" > $</ span >
156- < input name = "express_rate" type = "number" step = "0.01" defaultValue = { shipping . express_rate ?? '19.99' }
157- className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md pl-8 pr-4 py-3 text-sm text-white focus:border-gold/50 outline-none transition-all" />
158+ < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > US Domestic Express</ p >
158159 </ div >
159- < input name = "express_label" type = "text" defaultValue = { shipping . express_label ?? 'Express Shipping ' }
160+ < input name = "express_label" type = "text" defaultValue = { shipping . express_label ?? 'USPS Priority Mail (1-3 Days) ' }
160161 className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-sm text-white focus:border-gold/50 outline-none transition-all" />
162+ < div className = "space-y-1.5" >
163+ < label className = "text-[9px] uppercase tracking-luxury text-luxury-subtext font-medium" > Weight Brackets (JSON)</ label >
164+ < textarea name = "express_weight_brackets" defaultValue = { JSON . stringify ( shipping . express_weight_brackets || [
165+ { max_lb : 1 , rate : 9.99 } ,
166+ { max_lb : 3 , rate : 14.99 } ,
167+ { max_lb : 999 , rate : 19.99 }
168+ ] , null , 2 ) }
169+ rows = { 5 } className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-xs font-mono text-emerald-400 focus:border-gold/50 outline-none transition-all" />
170+ </ div >
161171 </ div >
172+
173+ < div className = "p-6 bg-white/5 rounded-xl border border-white/5 space-y-4" >
174+ < div className = "flex items-center gap-3" >
175+ < Globe className = "w-4 h-4 text-white" />
176+ < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > International Standard</ p >
177+ </ div >
178+ < div className = "space-y-1.5" >
179+ < label className = "text-[9px] uppercase tracking-luxury text-luxury-subtext font-medium" > International Std Brackets (JSON)</ label >
180+ < textarea name = "intl_weight_brackets" defaultValue = { JSON . stringify ( shipping . intl_weight_brackets || [
181+ { max_lb : 1 , rate : 19.99 } ,
182+ { max_lb : 3 , rate : 29.99 } ,
183+ { max_lb : 5 , rate : 39.99 } ,
184+ { max_lb : 999 , rate : 59.99 }
185+ ] , null , 2 ) }
186+ rows = { 5 } className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-xs font-mono text-emerald-400 focus:border-gold/50 outline-none transition-all" />
187+ </ div >
188+ </ div >
189+
190+ < div className = "p-6 bg-white/5 rounded-xl border border-white/5 space-y-4" >
191+ < div className = "flex items-center gap-3" >
192+ < Globe className = "w-4 h-4 text-gold" />
193+ < p className = "text-[11px] uppercase tracking-luxury font-bold text-white" > International Express</ p >
194+ </ div >
195+ < div className = "space-y-1.5" >
196+ < label className = "text-[9px] uppercase tracking-luxury text-luxury-subtext font-medium" > International Express Brackets (JSON)</ label >
197+ < textarea name = "intl_express_weight_brackets" defaultValue = { JSON . stringify ( shipping . intl_express_weight_brackets || [
198+ { max_lb : 1 , rate : 49.99 } ,
199+ { max_lb : 3 , rate : 69.99 } ,
200+ { max_lb : 999 , rate : 89.99 }
201+ ] , null , 2 ) }
202+ rows = { 5 } className = "w-full bg-[#0B0B0D] border border-white/10 rounded-md px-4 py-3 text-xs font-mono text-emerald-400 focus:border-gold/50 outline-none transition-all" />
203+ </ div >
204+ </ div >
205+
162206 </ div >
163207
164- < div className = "flex items-start gap-3 p-5 bg-emerald-950/20 border border-emerald-500/20 rounded-xl" >
208+ < div className = "flex items-start gap-3 p-5 bg-emerald-950/20 border border-emerald-500/20 rounded-xl mt-6 " >
165209 < DollarSign className = "w-4 h-4 text-emerald-500 mt-0.5 flex-shrink-0" />
166210 < p className = "text-[11px] text-emerald-400/80 leading-relaxed" >
167- Live Shippo rates are active. The flat rates above are used as fallback if carrier services are unreachable .
211+ Shipping rates are now fully dynamic and calculated live based on cart weight + location when requested at checkout. Admin can adjust these JSON boundaries anytime .
168212 </ p >
169213 </ div >
170214 </ SettingsForm >
0 commit comments