corrections updated

This commit is contained in:
Selvi 2025-09-11 17:50:27 +05:30
parent 33ae4560cd
commit 41ec9f91d1
15 changed files with 500 additions and 45 deletions

View File

@ -35,7 +35,7 @@ export default function MobileMenu({ handleMobileMenu, isMobileMenu }) {
<Link href="/contact" className="theme_btn tp_one">Contact</Link>
</div>
<div className="single-mobile-header-info">
<Link href="/contact" className="theme_btn">Service</Link>
<Link href="/zipvan-quote" className="theme_btn">Service</Link>
</div>
</div>
</nav>

View File

@ -34,7 +34,7 @@ export default function StickyHeader({ scroll, handleSearch, handleOptionalPanel
</div>
{/*menu icon*/}
<div className="button">
<Link href="/contact" className="theme_btn">
<Link href="/zipvan-quote" className="theme_btn">
Get A Quote
<svg width={12} height={12} viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H3.5M11 1V8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />

View File

@ -15,11 +15,11 @@ export default function Footer2({ }) {
<div className="row">
<div className="col-lg-4 col-md-6 col-sm-6 col-xs-12 pd_right_70">
<div className="footer_widgets_box pd_bottom_30">
<div className="fwidget_title">
<div className="fwidget_title">
<h2 className="title color_white"> Move your stuff in a ZIP </h2>
</div>
<div className="logo_box">
<Link href="/" className="logo navbar-brand">
@ -53,7 +53,12 @@ export default function Footer2({ }) {
</Link>
</li> */}
<li>
<Link href="#" className="m_icon">
<Link
href="https://www.instagram.com/zipvan.ca?igsh=aTRvdXhhOHk4cXM0"
className="m_icon"
target="_blank"
rel="noopener noreferrer"
>
<i className="fab fa-instagram" />
</Link>
</li>
@ -79,7 +84,7 @@ export default function Footer2({ }) {
<i className="fi-rr-arrow-small-right color_white" />
</div>
{/* <Link className="links color_white" href="#"> */}
Greater Toronto Area
Greater Toronto Area
{/* </Link> */}
</div>
</li>
@ -89,7 +94,7 @@ export default function Footer2({ }) {
<i className="fi-rr-arrow-small-right color_white" />
</div>
{/* <Link className="links color_white" href="#"> */}
Greater Hamilton Area
Greater Hamilton Area
{/* </Link> */}
</div>
</li>
@ -99,8 +104,8 @@ export default function Footer2({ }) {
<i className="fi-rr-arrow-small-right color_white" />
</div>
{/* <Link className="links color_white" href="#"> */}
Kitchener-Waterloo-
Cambridge Area
Kitchener-Waterloo-
Cambridge Area
{/* </Link> */}
</div>
</li>
@ -202,7 +207,7 @@ export default function Footer2({ }) {
<li>
<div className="d-flex align-items-center">
<div className="icon trans me-2">
<img src="/assets/images/shield.svg" className="img-fluid" alt="img" />
<img src="/assets/images/shield.svg" className="img-fluid" alt="img" />
</div>
<span className="links color_white mb-0">
Copyright 2025 © ZipVan. Powered by{" "}
@ -223,7 +228,7 @@ export default function Footer2({ }) {
<div className="icon trans">
<i className=" fi-rr-clock" />
</div>
Working Hours : 24/7 365 Days a Year
Working Hours : 24/7 365 Days a Year
</div>
</li>
</ul>

View File

@ -104,7 +104,7 @@ export default function Header1({ handleSearch, handleOptionalPanel, handleMobil
</div>
{/*menu icon*/}
<div className="button">
<Link href="/contact" className="theme_btn">
<Link href="/zipvan-quote" className="theme_btn">
Get A Quote
<svg width={12} height={12} viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H3.5M11 1V8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />

View File

@ -105,7 +105,7 @@ export default function Header2({ handleSearch, handleOptionalPanel, handleMobil
<span className="line" />
</div>
<div className="button">
<Link href="/contact" className="theme_btn">
<Link href="/zipvan-quote" className="theme_btn">
Get A Quote
<svg width={12} height={12} viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H3.5M11 1V8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />

View File

@ -34,7 +34,7 @@ export default function Header4({ handleSearch, handleOptionalPanel, handleMobil
</div>
{/*menu icon*/}
<div className="button">
<Link href="/contact" className="theme_btn">
<Link href="/zipvan-quote" className="theme_btn">
Get A Quote
<svg width={12} height={12} viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1 11L11 1M11 1H3.5M11 1V8.5" stroke="white" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />

View File

@ -22,7 +22,7 @@ export default function Banner1() {
<section className="single_banner style_one">
<div className="image_bg">
<img
src="/assets/images/home/banner/map-orange.webp"
src="/assets/images/slider/banner-single-4-bg.png"
className="img-fluid"
alt="img"
/>
@ -72,7 +72,7 @@ export default function Banner1() {
<section className="single_banner style_one">
<div className="image_bg">
<img
src="/assets/images/home/banner/map-blue.webp"
src="/assets/images/slider/banner-single-4-bg.png"
className="img-fluid"
alt="img"
/>

View File

@ -12,9 +12,9 @@ export default function Contact() {
<div className="row">
<div className="col-lg-12">
<div className="section_title text-center type_five">
<h4 className="sm_title">Areas we serve</h4>
<h4 className="sm_title">Areas We Serve</h4>
<div className="title_whole">
<h2 className="title">Serving Cities Across Ontario</h2>
<h2 className="title">Serving Cities Across Southern Ontario</h2>
</div>
</div>
</div>

View File

@ -319,7 +319,7 @@ export default function ZipvanQuote() {
--zip-orange:#ff6500; --zip-black:#0a0a0a; --ink:#0f1720; --muted:#6b7280;
--surface:#ffffff; --border:#e6e8eb; --radius:16px;
}
.zip-wrap{max-width:1100px;margin:0 auto;padding:28px}
.zip-wrap{max-width:1100px;margin:0 auto;}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
box-shadow:0 10px 28px rgba(15,23,32,.07);overflow:hidden}
.card-head{padding:20px 22px;background:var(--zip-black);color:#fff;display:flex;justify-content:space-between;align-items:center}

View File

@ -106,7 +106,7 @@ export default function AboutUs() {
<div className="position-relative">
<ul className="list_box list color_two">
<li>
<div className="d-flex align-items-center">
<div className="d-flex align-items-start">
<div className="icon trans">
<i aria-hidden="false" className="fas fa-check-circle" /></div>
<p>
@ -114,7 +114,7 @@ export default function AboutUs() {
</div>
</li>
<li>
<div className="d-flex align-items-center">
<div className="d-flex align-items-start">
<div className="icon trans">
<i aria-hidden="false" className="fas fa-check-circle" /></div>
<p>
@ -132,10 +132,9 @@ export default function AboutUs() {
{/*-============spacing==========-*/}
<div className="pd_bottom_30" />
{/*-============spacing==========-*/}
<div className="theme_btn_all">
<Link href="/contact" className="theme_btn">
More About Us
<span> <i className=" fi-rr-arrow-small-up" /></span>
<div className="theme_btn_all">
<Link href="/contact" className="theme_btn big rotate">
More About Us <span> <i className=" fi-rr-arrow-small-up" /></span>
</Link>
</div>
</div>
@ -169,7 +168,7 @@ export default function AboutUs() {
<div className="position-relative">
<ul className="list_box list color_two">
<li>
<div className="d-flex align-items-center">
<div className="d-flex align-items-start">
<div className="icon trans">
<i aria-hidden="false" className="fas fa-check-circle" /></div>
<p>
@ -340,8 +339,8 @@ export default function AboutUs() {
<div className="pd_bottom_40" />
{/*-============spacing==========-*/}
<div className="theme_btn_all">
<Link href="/contact" className="theme_btn">
Learn More <span><i className=" fi-rr-arrow-small-up" /></span>
<Link href="/contact" className="theme_btn big rotate">
Learn More <span> <i className=" fi-rr-arrow-small-up" /></span>
</Link>
</div>
{/*-============spacing==========-*/}

View File

@ -99,7 +99,7 @@ export default function Contact() {
<div className="pd_top_90" />
</section>
<section className="content-section bg_op_4 theme_alter-bg" style={{ backgroundImage: 'url(assets/images/wave-pat-1.png)' }}>
<section className="content-section bg_op_4 theme_alter-bg" style={{ backgroundImage: 'url(/assets/images/wave-pat-1.png)' }}>
{/*-============spacing==========-*/}
<div className="pd_top_90" />
{/*-============spacing==========-*/}
@ -113,7 +113,7 @@ export default function Contact() {
<div className="section_title medium type_one">
<h4 className="sm_title"> Special Deals</h4>
<div className="title_whole">
<h2 className="title">Reasons to Choose Zip Van</h2>
<h2 className="title text-white">Reasons to Choose Zip Van</h2>
</div>
</div>
{/*-============spacing==========-*/}
@ -284,7 +284,7 @@ export default function Contact() {
{/*-============spacing==========-*/}
</section>
<section className="call-to-action-section position-relative bg_op_1" style={{ backgroundImage: 'url(assets/images/call-bg-h4-min.jpg)' }}>
<section className="call-to-action-section position-relative bg_op_1" style={{ backgroundImage: 'url(/assets/images/call-bg-h4-min.jpg)' }}>
<div className="background_overlay bg_11 z_0" />
{/*-============spacing==========-*/}
<div className="pd_top_50" />

View File

@ -102,7 +102,7 @@ export default function Contact() {
</div>
<div className="contact-infor">
<h6 className="title_no_a_24">Location</h6>
<span>55 Main Street, 2nd Block melbourne, Australia</span>
<span>Southern Ontario, Canada</span>
</div>
</div>
</div>
@ -155,7 +155,12 @@ export default function Contact() {
<div className="social-icons">
<ul>
<li>
<Link href="#" className="m_icon">
<Link
href="https://www.instagram.com/zipvan.ca?igsh=aTRvdXhhOHk4cXM0"
className="m_icon"
target="_blank"
rel="noopener noreferrer"
>
<i className="fab fa-instagram" />
</Link>
</li>
@ -256,9 +261,9 @@ export default function Contact() {
</div>
</div>
</div>
<div className="ab_img_left_bottom z_0 mr_top_minus_150">
{/* <div className="ab_img_left_bottom z_0 mr_top_minus_150">
<img src="/assets/images/bg-1.png" className="img-fluid" alt="img" />
</div>
</div> */}
<div className="pd_bottom_90" />
</section>
@ -269,7 +274,7 @@ export default function Contact() {
<section className="map-section">
<div className="map-outer">
<iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2643.6895046810805!2d-122.52642526124438!3d38.00014098339506!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8085976736097a2f%3A0xbe014d20e6e22654!2sSan%20Rafael%2C%20California!5e0!3m2!1sen!2s!4v1678975266976!5m2!1sen!2s"
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d7330270.013314212!2d-90.91912208724011!3d43.44971233982256!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x882b5e9a9f7337f5%3A0x37ce96e31b509179!2sSouthern%20Ontario%2C%20ON!5e0!3m2!1sen!2sca!4v1694464454895!5m2!1sen!2sca"
height={570}
style={{ border: 0, width: "100%" }}
allowFullScreen

430
pages/zipvan-quote.js Normal file
View File

@ -0,0 +1,430 @@
import Layout from "@/components/layout/Layout"
import dynamic from 'next/dynamic'
import Link from "next/link"
import React, { useEffect, useRef, useState } from "react";
const CounterUp = dynamic(() => import('@/components/elements/CounterUp'), {
ssr: false,
})
export default function ZipvanQuote() {
const CONFIG = {
GOOGLE_MAPS_API_KEY:
process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY ||
"AIzaSyAxWCXjM3_iYRKdWPUceRo79DlvIU9xnZQ",
CALENDLY_EVENT_URL: "https://calendly.com/zipvan/new-meeting",
PUBLIC_RATES: { booking_flat: 25, km_rate_under_equal_15: 3, km_rate_over_15: 2 },
TAX_RATE: 0.13,
BOUNDS: { SW: { lat: 42.8, lng: -81.0 }, NE: { lat: 44.3, lng: -78.5 } },
};
const pickupRef = useRef(null);
const dropoffRef = useRef(null);
const mapRef = useRef(null);
const schedRef = useRef(null);
const mapObj = useRef(null);
const dirSvc = useRef(null);
const dirRenderer = useRef(null);
const geocoder = useRef(null);
const markerP = useRef(null);
const markerD = useRef(null);
const routeToken = useRef(0);
const [quote, setQuote] = useState({
km: 0,
min: 0,
subtotal: 0,
tax: 0,
grand: 0,
});
const [mapsReady, setMapsReady] = useState(false);
const [mapsError, setMapsError] = useState(null);
const money = (n) => "$" + Number(n).toFixed(2);
const q = (p) =>
Object.entries(p)
.filter(([, v]) => v !== "" && v != null)
.map(([k, v]) => encodeURIComponent(k) + "=" + encodeURIComponent(v))
.join("&");
const showMapStatus = (m) => {
const el = document.getElementById("mapStatus");
if (el) {
el.style.display = "block";
el.textContent = m;
}
};
const debounce = (fn, wait = 700) => {
let t;
return (...a) => {
clearTimeout(t);
t = setTimeout(() => fn(...a), wait);
};
};
function loadGoogleMaps() {
return new Promise((resolve, reject) => {
if (window.google && window.google.maps && window.google.maps.places) {
resolve(window.google);
return;
}
if (document.getElementById("zipvan-google-maps")) {
const existing = document.getElementById("zipvan-google-maps");
existing.addEventListener("load", () => {
if (window.google) resolve(window.google);
else reject(new Error("Google loaded but window.google missing"));
});
existing.addEventListener("error", () => reject(new Error("Google Maps script error")));
return;
}
const s = document.createElement("script");
s.id = "zipvan-google-maps";
s.src =
"https://maps.googleapis.com/maps/api/js?key=" +
encodeURIComponent(CONFIG.GOOGLE_MAPS_API_KEY) +
"&libraries=places&v=weekly";
s.async = true;
s.defer = true;
s.onload = () => {
if (window.google) resolve(window.google);
else reject(new Error("Google Maps loaded but window.google missing"));
};
s.onerror = () => reject(new Error("Google Maps failed to load (network or invalid key)"));
document.head.appendChild(s);
});
}
function calcAndSetTotals({ km, min }) {
const rate = km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15;
const distanceCost = km * rate;
const subtotal = CONFIG.PUBLIC_RATES.booking_flat + distanceCost;
const tax = +(subtotal * CONFIG.TAX_RATE).toFixed(2);
const grand = +(subtotal + tax).toFixed(2);
setQuote({
km: +km.toFixed(2),
min: Math.round(min),
subtotal: +subtotal.toFixed(2),
tax,
grand,
});
}
function openCalendly() {
const url =
CONFIG.CALENDLY_EVENT_URL +
"?" +
q({
hide_event_type_details: 1,
background_color: "ffffff",
text_color: "0a0a0a",
a1: pickupRef.current ? pickupRef.current.value : "",
a2: dropoffRef.current ? dropoffRef.current.value : "",
a3: quote.km ? quote.km.toFixed(1) + " km" : "",
a4: money(quote.subtotal),
a5: money(quote.grand),
_cb: Date.now(),
});
const holder = schedRef.current ?? document.getElementById("sched");
if (!holder) return;
const existing = document.getElementById("calendly-embed-iframe");
if (existing) existing.src = url;
else {
const ifr = document.createElement("iframe");
ifr.id = "calendly-embed-iframe";
ifr.src = url;
ifr.allow = "payment *; clipboard-write *";
ifr.style.width = "100%";
ifr.style.minHeight = "980px";
ifr.style.border = "0";
holder.appendChild(ifr);
}
holder.scrollIntoView({ behavior: "smooth" });
}
function initMap() {
if (!window.google) {
setMapsError("Google Maps not available.");
return;
}
if (!mapRef.current) {
setMapsError("Map container not found.");
return;
}
mapObj.current = new window.google.maps.Map(mapRef.current, {
center: { lat: 43.65, lng: -79.38 },
zoom: 10,
gestureHandling: "greedy",
});
dirSvc.current = new window.google.maps.DirectionsService();
dirRenderer.current = new window.google.maps.DirectionsRenderer({ suppressMarkers: true, preserveViewport: false });
geocoder.current = new window.google.maps.Geocoder();
dirRenderer.current.setMap(mapObj.current);
const biasBounds = new window.google.maps.LatLngBounds(CONFIG.BOUNDS.SW, CONFIG.BOUNDS.NE);
const acOpts = {
types: ["address"],
componentRestrictions: { country: "ca" },
bounds: biasBounds,
strictBounds: false,
fields: ["formatted_address", "geometry"],
};
if (pickupRef.current) {
const acP = new window.google.maps.places.Autocomplete(pickupRef.current, acOpts);
acP.addListener("place_changed", () => handlePlace(acP, "pickup"));
}
if (dropoffRef.current) {
const acD = new window.google.maps.places.Autocomplete(dropoffRef.current, acOpts);
acD.addListener("place_changed", () => handlePlace(acD, "dropoff"));
}
const onBlurPick = () => geocodeManual("pickup");
const onBlurDrop = () => geocodeManual("dropoff");
pickupRef.current && pickupRef.current.addEventListener("blur", onBlurPick);
dropoffRef.current && dropoffRef.current.addEventListener("blur", onBlurDrop);
const geocodeDebounced = debounce((which) => {
const el = which === "pickup" ? pickupRef.current : dropoffRef.current;
const val = el ? el.value.trim() : "";
if (!val) return;
geocoder.current.geocode({ address: val, componentRestrictions: { country: "CA" }, bounds: biasBounds }, (res, st) => {
if (st === "OK" && res && res[0]) {
dropMarker(which, res[0].geometry.location, res[0].formatted_address);
requestRoute();
}
});
}, 400);
function geocodeManual(which) {
geocodeDebounced(which);
}
function handlePlace(ac, which) {
const p = ac.getPlace();
if (!p || !p.geometry) {
geocodeManual(which);
return;
}
dropMarker(which, p.geometry.location, p.formatted_address || (which === "pickup" ? pickupRef.current.value : dropoffRef.current.value));
requestRoute();
}
function dropMarker(which, latlng, label) {
const L = which === "pickup" ? "P" : "D";
const opts = {
position: latlng,
map: mapObj.current,
label: { text: L, color: "#fff", fontWeight: "700" },
title: (which === "pickup" ? "Pick up" : "Drop off") + ": " + label,
};
if (which === "pickup") {
if (markerP.current) markerP.current.setMap(null);
markerP.current = new window.google.maps.Marker(opts);
} else {
if (markerD.current) markerD.current.setMap(null);
markerD.current = new window.google.maps.Marker(opts);
}
}
function requestRoute() {
if (!markerP.current || !markerD.current) return;
const my = ++routeToken.current;
dirSvc.current.route(
{
origin: markerP.current.getPosition(),
destination: markerD.current.getPosition(),
travelMode: window.google.maps.TravelMode.DRIVING,
},
(res, st) => {
if (my !== routeToken.current) return;
if (st === "OK" && res?.routes?.[0]?.legs?.[0]) {
dirRenderer.current.setDirections(res);
const leg = res.routes[0].legs[0];
const km = +(leg.distance.value / 1000).toFixed(2);
const mins = Math.round(leg.duration.value / 60);
const mapStatusEl = document.getElementById("mapStatus");
if (mapStatusEl) mapStatusEl.style.display = "none";
const b = new window.google.maps.LatLngBounds();
b.extend(markerP.current.getPosition());
b.extend(markerD.current.getPosition());
mapObj.current.fitBounds(b);
calcAndSetTotals({ km, min: mins });
} else {
showMapStatus("Couldn't compute the driving route. Check Ontario addresses.");
}
}
);
}
if (!document.getElementById("zipvan-calendly-script")) {
const cs = document.createElement("script");
cs.id = "zipvan-calendly-script";
cs.src = "https://assets.calendly.com/assets/external/widget.js";
cs.async = true;
document.head.appendChild(cs);
}
setMapsReady(true);
initMap._cleanup = () => {
pickupRef.current && pickupRef.current.removeEventListener("blur", onBlurPick);
dropoffRef.current && dropoffRef.current.removeEventListener("blur", onBlurDrop);
};
}
useEffect(() => {
let mounted = true;
if (!CONFIG.GOOGLE_MAPS_API_KEY) {
setMapsError("Google Maps API key missing. Put it into CONFIG or NEXT_PUBLIC_GOOGLE_MAPS_KEY.");
return;
}
loadGoogleMaps()
.then(() => {
if (!mounted) return;
initMap();
})
.catch((err) => {
console.error("Google Maps load failed:", err);
setMapsError("Google Maps failed to load. Check API key, billing and allowed referrers.");
showMapStatus("Google Maps failed to load. See console for details.");
});
return () => {
mounted = false;
try {
if (initMap._cleanup) initMap._cleanup();
if (markerP.current) markerP.current.setMap(null);
if (markerD.current) markerD.current.setMap(null);
if (dirRenderer.current) dirRenderer.current.setMap(null);
} catch (e) { }
};
}, []);
const canBook = Boolean(quote.km && quote.min);
return (
<>
<Layout breadcrumbTitle="Get A Quote" footerStyle={2} background="/assets/images/contact/quote-banner.webp">
<div className="zip-wrap" style={{ maxWidth: 1100, margin: "0 auto" }}>
<div className="pd_top_90" />
<div className="section_title type_four text-center">
<h4 className="sm_title">Fast Checkout</h4>
<div className="title_whole">
<h2 className="title">See Your All-In Price in 10 Seconds</h2>
<p>Enter pickup & drop-off. Your price is lockedno fuel or weekend fees.</p>
</div>
<div className="pd_bottom_40" />
</div>
<style>{`
:root{
--zip-orange:#ff6500; --zip-black:#0a0a0a; --ink:#0f1720; --muted:#6b7280;
--surface:#ffffff; --border:#e6e8eb; --radius:16px;
}
.zip-wrap{max-width:1100px;margin:0 auto;}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
box-shadow:0 10px 28px rgba(15,23,32,.07);overflow:hidden}
.card-head{padding:20px 22px;background:var(--zip-black);color:#fff;display:flex;justify-content:space-between;align-items:center}
.card-head h2{margin:0;font-size:22px}
.card-body{padding:22px}
.addr-row{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
@media(max-width:760px){ .addr-row{grid-template-columns:1fr} }
.input{width:100%;padding:12px 14px;border:1px solid var(--border);border-radius:12px;
font-size:16px;background:#fff;color:var(--ink);min-height:46px;box-sizing:border-box}
.input:focus{outline:0;border-color:#cfd3d8;box-shadow:0 0 0 3px rgba(255,101,0,.12)}
.map{height:390px;border-radius:12px;overflow:hidden;border:1px solid var(--border);
background:#f6f7f8;display:flex;align-items:center;justify-content:center;margin-top:14px}
.map .err{color:var(--muted);font-size:14px}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
.stat{border:1px solid var(--border);border-radius:12px;background:#fff;padding:12px 14px}
.stat label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}
.stat .value{font-size:16px;font-weight:750;color:var(--ink)}
.totalbar{display:flex;align-items:center;gap:18px;margin-top:16px}
.grand{margin-left:auto;font-size:22px;font-weight:850}
.breakdown{margin-top:12px;border:1px solid var(--border);border-radius:12px;overflow:hidden}
.brow{display:flex;justify-content:space-between;padding:10px 12px;font-size:14px;background:#fff}
.brow:nth-child(odd){background:#fbfbfc}
.brow .lbl{color:#6b7280}
.brow.total{font-weight:800;border-top:1px solid var(--border)}
.hint{font-size:12px;color:#6b7280;margin-top:8px}
.cta{display:flex;justify-content:flex-end;margin-top:16px}
.btn{appearance:none;border:0;background:var(--zip-orange);color:#fff;font-weight:850;letter-spacing:.2px;
padding:12px 18px;border-radius:999px;font-size:16px;cursor:pointer;transition:.15s transform,.2s opacity}
.btn[disabled]{background:#c9ccd1;cursor:not-allowed;opacity:.85}
.btn:active{transform:translateY(1px)}
#sched{margin-top:26px}
#calendly-embed-iframe{width:100%;min-height:980px;border:0}
`}</style>
<div className="card">
<div className="card-head">
<h2 className="text-white">Book a Pickup</h2>
<div style={{ opacity: ".9", fontSize: 13 }}>Transparent pricing distance + booking</div>
</div>
<div className="card-body">
<div className="addr-row">
<input id="pickup" ref={pickupRef} className="input" type="text" placeholder="Pick up address (Canada)" aria-label="Pick up" autoComplete="off" />
<input id="dropoff" ref={dropoffRef} className="input" type="text" placeholder="Drop off address (Canada)" aria-label="Drop off" autoComplete="off" />
</div>
<div id="map" ref={mapRef} className="map">
<div className="err" id="mapStatus">Enter Pick up and Drop off to see your route, distance, and price.</div>
</div>
<div className="stats">
<div className="stat">
<label>Service</label>
<div className="value">Curbside</div>
</div>
<div className="stat">
<label>Crew</label>
<div className="value">1 mover</div>
</div>
<div className="stat">
<label>Distance & Time</label>
<div className="value">
<span id="distanceKm">{quote.km ? quote.km.toFixed(1) : "—"}</span> km <span id="driveMin">{quote.min ? Math.round(quote.min) : ""}</span> min
</div>
</div>
</div>
<div className="totalbar">
<div className="grand">Grand total: <span id="grandTotal">{quote.km ? money(quote.grand) : "—"}</span></div>
</div>
<div className="breakdown" id="breakdownBox" style={{ display: quote.km ? "block" : "none" }}>
<div className="brow"><div className="lbl">Booking fee</div><div id="bkFee">{money(CONFIG.PUBLIC_RATES.booking_flat)}</div></div>
<div className="brow"><div className="lbl">Distance (<span id="rateLabel">${quote.km && quote.km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15}</span>/km)</div><div id="distAmt">{quote.km ? money((quote.km) * (quote.km <= 15 ? CONFIG.PUBLIC_RATES.km_rate_under_equal_15 : CONFIG.PUBLIC_RATES.km_rate_over_15)) : money(0)}</div></div>
<div className="brow"><div className="lbl">Subtotal</div><div id="subAmt">{quote.km ? money(quote.subtotal) : money(0)}</div></div>
<div className="brow"><div className="lbl">HST (13%)</div><div id="taxAmt">{quote.km ? money(quote.tax) : money(0)}</div></div>
<div className="brow total"><div>Grand total</div><div id="grandAmt">{quote.km ? money(quote.grand) : money(0)}</div></div>
</div>
<div className="hint">Final price shown before you pay. Name, phone, and email are collected in the next step.</div>
<div className="cta">
<button id="bookNow" className="btn" disabled={!canBook} onClick={() => { if (canBook) openCalendly(); }}>
Continue to Scheduling
</button>
</div>
</div>
</div>
<div id="sched" ref={schedRef}></div>
{mapsError && (
<div style={{ marginTop: 12, padding: 12, background: "#fff6f6", color: "#b91c1c", borderRadius: 8 }}>
<strong>Map error:</strong> {mapsError}
</div>
)}
<div className="pd_bottom_90" />
</div>
</Layout>
</>
)
}

View File

@ -9417,11 +9417,11 @@ body div.wpforms-container-full .wpforms-form .wpforms-page-button {
height: unset !important;
font-weight: 500;
color: var(--color-white);
background: var(--color-set-one-1);
background: #ff6600;
border-radius: 7px;
padding: 5px 15px;
box-shadow: unset;
border: 1px solid var(--color-set-one-1);
border: 1px solid #ff6600;
transition: 0.5s ease-in-out;
-ms-transition: 0.5s ease-in-out;
-moz-transition: 0.5s ease-in-out;
@ -9433,8 +9433,8 @@ body input[type=submit]:hover,
body button[type=submit]:hover,
body div.wpforms-container-full .wpforms-form button[type=submit]:hover,
body div.wpforms-container-full .wpforms-form .wpforms-page-button:hover {
background: var(--color-set-one-2);
border-color: var(--color-set-one-2);
background: #08254b;
border-color: #08254b;
}
div.wpforms-container .wpforms-form .choices__inner {
@ -15233,7 +15233,7 @@ body .wp-block-rss li a {
.social-icons ul li .m_icon {
border: 0px;
background: var(--color-set-one-3);
background: #08254b;
width: 40px;
height: 40px;
color: var(--color-white);
@ -15249,7 +15249,7 @@ body .wp-block-rss li a {
}
.social-icons ul li .m_icon:hover {
background: var(--color-set-one-2);
background: #36619A;
color: var(--color-white);
}
@ -17397,4 +17397,20 @@ input[type=range i]:focus::-webkit-slider-thumb {
.process_box.type_four .icon svg {
display: none;
}
}
}
.swiper-button-next,
.swiper-button-prev {
color: #ff6600 !important;
}
.list_box .d-flex {
gap: 10px;
align-items: baseline !important;
}
.list_box .icon i {
color: #ff6600;
font-size: 18px;
margin-top: 3px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB