Skip to content

Instantly share code, notes, and snippets.

@gioiliop7
Last active December 7, 2024 23:29
Show Gist options
  • Save gioiliop7/7397b1687fd821ceb99aa6c1c531e2e2 to your computer and use it in GitHub Desktop.
Save gioiliop7/7397b1687fd821ceb99aa6c1c531e2e2 to your computer and use it in GitHub Desktop.
[TYPESCRIPT,TAILWIND,REACT] - BoxNow Locker Selection React Component Widget
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>
);
}
//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