PageSourceSearch

https://mensenlinq.nl/build/assets/CardPreview-CfrLGIbF.js

js mensenlinq.nl collected 2026-09-24 21:58:24 UTC 7,714 bytes, 205 lines download raw bytes

1import { a as require_react, d as __toESM, n as require_jsx_runtime } from "./axios-D_Zw0bxE.js";
2import { Q as FontAwesomeIcon, V as faSpinner, Z as faWarning, h as faArrowRight, m as faArrowLeft, s as Button, z as faRotateLeft } from "./entry-app.js";
3import { r as Tabs, t as Tab } from "./Tabs-CsJZ5s-2.js";
4import { t as NumberSlider } from "./NumberSlider-qB9QZ0sG.js";
5var CardPreview_module_default = {
6	container: "_container_1bp78_1",
7	header: "_header_1bp78_1",
8	title: "_title_1bp78_1",
9	tabs: "_tabs_1bp78_4",
10	zoomControls: "_zoomControls_1bp78_7",
11	tools: "_tools_1bp78_14",
12	preview: "_preview_1bp78_19",
13	hasFocus: "_hasFocus_1bp78_30",
14	pageNav: "_pageNav_1bp78_33",
15	previous: "_previous_1bp78_40",
16	next: "_next_1bp78_40"
17};
18//#endregion
19//#region resources/js/Organisms/CardPreview/CardPreview.tsx
20var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
21var import_jsx_runtime = require_jsx_runtime();
22var CardPreview_default = ({ title, items, isLoading, errors, className }) => {
23	const minZoom = 75;
24	const maxZoom = 400;
25	const [currentPage, setCurrentPage] = (0, import_react.useState)(0);
26	const previewRef = (0, import_react.useRef)(null);
27	const wheelTimeout = (0, import_react.useRef)(null);
28	const [isInteracting, setIsInteracting] = (0, import_react.useState)(false);
29	const [zoom, setZoom] = (0, import_react.useState)(1);
30	(0, import_react.useEffect)(() => {
31		handleReset();
32	}, [currentPage]);
33	const [offset, setOffset] = (0, import_react.useState)({
34		x: 0,
35		y: 0
36	});
37	const [start, setStart] = (0, import_react.useState)({
38		x: 0,
39		y: 0
40	});
41	const [isDragging, setIsDragging] = (0, import_react.useState)(false);
42	const [hasFocus, setHasFocus] = (0, import_react.useState)(false);
43	const handleReset = () => {
44		setZoom(1);
45		setOffset({
46			x: 0,
47			y: 0
48		});
49	};
50	const applyZoom = (nextZoom, anchor) => {
51		setOffset((prev) => {
52			const scaleFactor = nextZoom / zoom;
53			return {
54				x: prev.x - (anchor.x - prev.x) * (scaleFactor - 1),
55				y: prev.y - (anchor.y - prev.y) * (scaleFactor - 1)
56			};
57		});
58		setZoom(nextZoom);
59	};
60	const handleWheel = (e) => {
61		if (!hasFocus || !previewRef.current) return;
62		e.preventDefault();
63		setIsInteracting(true);
64		if (wheelTimeout.current) window.clearTimeout(wheelTimeout.current);
65		wheelTimeout.current = window.setTimeout(() => {
66			setIsInteracting(false);
67		}, 80);
68		const rect = previewRef.current.getBoundingClientRect();
69		const nextZoom = Math.min(maxZoom / 100, Math.max(minZoom / 100, zoom + e.deltaY * -.001));
70		const anchor = {
71			x: e.clientX - rect.left,
72			y: e.clientY - rect.top
73		};
74		applyZoom(nextZoom, anchor);
75	};
76	const handleSliderZoom = (scaleFactor) => {
77		if (!previewRef.current) return;
78		const rect = previewRef.current.getBoundingClientRect();
79		const anchor = {
80			x: rect.width / 2,
81			y: rect.height / 2
82		};
83		applyZoom(scaleFactor / 100, anchor);
84	};
85	(0, import_react.useEffect)(() => {
86		const el = previewRef.current;
87		if (!el) return;
88		el.addEventListener("wheel", handleWheel, { passive: false });
89		return () => {
90			el.removeEventListener("wheel", handleWheel);
91		};
92	}, [zoom, hasFocus]);
93	(0, import_react.useEffect)(() => {
94		const handler = (e) => {
95			const isInsideContainer = previewRef.current.contains(e.target);
96			setHasFocus(isInsideContainer);
97		};
98		document.addEventListener("pointerdown", handler);
99		return () => document.removeEventListener("pointerdown", handler);
100	}, []);
101	let src = items?.[currentPage]?.image ?? "";
102	src = typeof src !== "string" ? src.image : src;
103	return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
104		className: `${CardPreview_module_default.container} ${className}`,
105		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
106			className: CardPreview_module_default.header,
107			children: [title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
108				className: CardPreview_module_default.title,
109				children: title
110			}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
111				className: CardPreview_module_default.tools,
112				children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tabs, {
113					value: currentPage,
114					onChange: setCurrentPage,
115					className: CardPreview_module_default.tabs,
116					children: items && items.map((page, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tab, { children: page.title }, index))
117				}
117), items && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
118					className: CardPreview_module_default.zoomControls,
119					children: [
120						/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "Inzoomen:" }),
121						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(NumberSlider, {
122							numericInput: false,
123							centerValue: 100,
124							value: Math.round(zoom * 100),
125							onChange: handleSliderZoom,
126							min: minZoom,
127							max: maxZoom,
128							step: 5
129						}),
130						/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [Math.round(zoom * 100), "%"] }),
131						/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
132							size: "small",
133							onClick: handleReset,
134							title: "Terug naar 100%",
135							children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontAwesomeIcon, { icon: faRotateLeft })
136						})
137					]
138				})]
139			})]
140		}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
141			ref: previewRef,
142			className: `${CardPreview_module_default.preview} ${hasFocus ? CardPreview_module_default.hasFocus : ""}`,
143			onClick: () => setHasFocus(true),
144			onMouseDown: (e) => {
145				setIsDragging(true);
146				setStart({
147					x: e.clientX - offset.x,
148					y: e.clientY - offset.y
149				});
150			},
151			onMouseMove: (e) => {
152				if (isDragging) setOffset({
153					x: e.clientX - start.x,
154					y: e.clientY - start.y
155				});
156			},
157			onMouseUp: () => {
158				setIsDragging(false);
159			},
160			onMouseLeave: () => {
161				setIsDragging(false);
162			},
163			children: [
164				isLoading && !errors && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: ["Bezig met genereren van proefdruk...", /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontAwesomeIcon, {
165					icon: faSpinner,
166					className: "ms-2",
167					spinPulse: true
168				})] }),
169				errors && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
170					"Er is een fout opgetreden bij het genereren van de proefdruk.",
171					/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontAwesomeIcon, {
172						icon: faWarning,
173						className: "ms-2"
174					}),
175					/* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
176					errors
177				] }),
178				items && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
179					className: CardPreview_module_default.pageNav,
180					children: [currentPage > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
181						className: CardPreview_module_default.previous,
182						onClick: () => setCurrentPage(currentPage - 1),
183						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontAwesomeIcon, { icon: faArrowLeft })
184					}), currentPage < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
185						className: CardPreview_module_default.next,
186						onClick: () => setCurrentPage(currentPage + 1),
187						children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FontAwesomeIcon, { icon: faArrowRight })
188					})]
189				}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", {
190					src,
191					style: {
192						cursor: isDragging ? "grabbing" : "grab",
193						transform: `translate(${offset.x}px, ${offset.y}px) scale(${zoom})`,
194						transition: isInteracting || isDragging ? "none" : "transform 0.2s ease"
195					},
196					alt: ""
197				})] })
198			]
199		})]
200	});
201};
202//#endregion
203export { CardPreview_default as t };
204
205//# sourceMappingURL=CardPreview-CfrLGIbF.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.