Last active
December 7, 2024 23:29
-
-
Save gioiliop7/7397b1687fd821ceb99aa6c1c531e2e2 to your computer and use it in GitHub Desktop.
[TYPESCRIPT,TAILWIND,REACT] - BoxNow Locker Selection React Component Widget
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useState } from "react"; | |
import BoxNowMapWidget from "./components/BoxNowMapWidget"; | |
export default function Home() { | |
const [selectedLocker, setSelectedLocker] = useState<{ | |
postalCode: string; | |
address: string; | |
lockerId: string; | |
lockerName: string; | |
} | null>(null); | |
const handleSelect = (selected: { | |
postalCode: string; | |
address: string; | |
lockerId: string; | |
lockerName: string; | |
}) => { | |
setSelectedLocker(selected); | |
}; | |
const widgetType = "iframe"; | |
return ( | |
<main className="flex min-h-screen flex-col items-center justify-center bg-gray-50"> | |
<h1 className="text-2xl font-bold mb-6">BOX NOW Map Widget Demo</h1> | |
<BoxNowMapWidget | |
onSelect={handleSelect} | |
type={widgetType} | |
customStyles={{ | |
padding: "20px", | |
display: "block", | |
}} | |
/> | |
{selectedLocker && selectedLocker.lockerId && ( | |
<div className="mt-4 p-4 bg-white border rounded shadow"> | |
<h2 className="text-lg font-semibold">Selected Locker</h2> | |
<p> | |
<strong>Postal Code:</strong> {selectedLocker.postalCode} | |
</p> | |
<p> | |
<strong>Address:</strong> {selectedLocker?.address} | |
</p> | |
<p> | |
<strong>Locker ID:</strong> {selectedLocker.lockerId} | |
</p> | |
<p> | |
<strong>Name:</strong> {selectedLocker?.lockerName} | |
</p> | |
</div> | |
)} | |
</main> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Documentation there https://widget-v5.boxnow.gr/devs | |
import { useEffect, useRef, useState } from "react"; | |
interface BoxNowMapWidgetProps { | |
onSelect: (selected: { | |
postalCode: string; | |
address: string; | |
lockerId: string; | |
lockerName: string; | |
}) => void; | |
customStyles?: React.CSSProperties; | |
type: "popup" | "iframe"; | |
} | |
interface SelectedLocker { | |
boxnowLockerPostalCode: string; | |
boxnowLockerAddressLine1: string; | |
boxnowLockerAddressLine2?: string; | |
boxnowLockerId: string; | |
boxnowLockerName: string; | |
} | |
interface BoxNowWidgetConfig { | |
partnerId: number; | |
parentElement: string; | |
type: "popup" | "iframe"; | |
gps: boolean; | |
autoclose: boolean; | |
autoselect?: boolean; | |
afterSelect: (selected: SelectedLocker) => void; | |
} | |
declare global { | |
interface Window { | |
_bn_map_widget_config?: BoxNowWidgetConfig; | |
} | |
} | |
const BoxNowMapWidget = ({ | |
onSelect, | |
customStyles, | |
type = "popup", | |
}: BoxNowMapWidgetProps) => { | |
const isInitialized = useRef(false); | |
const [mapOpen, setMapOpen] = useState(false); | |
useEffect(() => { | |
if (isInitialized.current) return; | |
const script = document.createElement("script"); | |
script.src = "https://widget-cdn.boxnow.gr/map-widget/client/v5.js"; | |
script.async = true; | |
script.defer = true; | |
document.head.appendChild(script); | |
const widgetConfig: BoxNowWidgetConfig = { | |
partnerId: 123, | |
parentElement: "#boxnowmap", | |
type, | |
gps: true, | |
autoclose: type === "popup", | |
autoselect: type === "iframe", | |
afterSelect: (selected: SelectedLocker) => { | |
try { | |
const formattedData = { | |
postalCode: selected.boxnowLockerPostalCode, | |
address: selected.boxnowLockerAddressLine1 | |
? `${selected.boxnowLockerAddressLine1} - ${ | |
selected.boxnowLockerAddressLine2 || "" | |
}`.trim() | |
: "", | |
lockerId: selected.boxnowLockerId, | |
lockerName: selected.boxnowLockerName, | |
}; | |
onSelect(formattedData); | |
} catch (e: unknown) { | |
console.log(e); | |
} | |
}, | |
}; | |
window._bn_map_widget_config = widgetConfig; | |
isInitialized.current = true; | |
const button = document.querySelector(".boxnow-map-widget-button"); | |
button?.addEventListener("click", () => { | |
const widgetContainer = document.querySelector("#boxnowmap"); | |
setMapOpen(true); | |
if (widgetContainer instanceof HTMLElement && customStyles) { | |
Object.assign(widgetContainer.style, { | |
minHeight: type === "iframe" ? "500px" : "0px", | |
...customStyles, | |
}); | |
} | |
}); | |
return () => { | |
document.head.removeChild(script); | |
}; | |
}, [onSelect, customStyles, type, isInitialized]); | |
return ( | |
<div className="w-full flex justify-center flex-col items-center"> | |
<div | |
id="boxnowmap" | |
className={`w-full ${type === "iframe" ? "h-64" : ""} hidden`} | |
></div> | |
{!mapOpen && ( | |
<> | |
<a | |
href="#" | |
className="boxnow-map-widget-button mt-4 inline-block px-4 py-2 text-white bg-[#42d72a] rounded" | |
> | |
Διάλεξε box now locker | |
</a> | |
</> | |
)} | |
</div> | |
); | |
}; | |
export default BoxNowMapWidget; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment