@ohhwells/bridge 0.1.34-next.44 → 0.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -318,18 +318,6 @@ npm run build
318
318
  npm publish --access public
319
319
  ```
320
320
 
321
- ### Staging → rebound-template auto-bump
322
-
323
- When `staging` publishes successfully, the bridge workflow dispatches a `bridge-published` event to `TheFlowOps-Eng/rebound-template`. That repo’s `bump-bridge.yml` workflow checks out `staging`, runs `npm install @ohhwells/bridge@<version> --save-exact`, and pushes the lockfile bump.
324
-
325
- **One-time setup** (in `ohhwells-bridge` GitHub repo → Settings → Secrets):
326
-
327
- | Secret | Value |
328
- |--------|--------|
329
- | `REBOUND_TEMPLATE_DISPATCH_TOKEN` | Fine-grained or classic PAT with `repo` access to `rebound-template` (needs permission to trigger `repository_dispatch`) |
330
-
331
- The published staging version looks like `0.1.31-next.42` and is tagged `next` on npm.
332
-
333
321
  ---
334
322
 
335
323
  ## Link dialog (Canvas Editor)
package/dist/index.cjs CHANGED
@@ -110,7 +110,6 @@ var import_react3 = require("react");
110
110
  var import_react2 = require("react");
111
111
  var import_radix_ui = require("radix-ui");
112
112
  var import_jsx_runtime = require("react/jsx-runtime");
113
- var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
114
113
  function Spinner() {
115
114
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
116
115
  "svg",
@@ -144,17 +143,12 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
144
143
  const [error, setError] = (0, import_react2.useState)(null);
145
144
  const isBook = title === "Confirm your spot";
146
145
  const handleSubmit = async () => {
147
- const trimmed = email.trim();
148
- if (!trimmed) return;
149
- if (!isValidEmail(trimmed)) {
150
- setError("Please enter a valid email address.");
151
- return;
152
- }
146
+ if (!email.trim()) return;
153
147
  setLoading(true);
154
148
  setError(null);
155
149
  try {
156
- await onSubmit(trimmed);
157
- setSubmittedEmail(trimmed);
150
+ await onSubmit(email.trim());
151
+ setSubmittedEmail(email.trim());
158
152
  setSuccess(true);
159
153
  } catch (e) {
160
154
  setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
@@ -229,10 +223,7 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
229
223
  {
230
224
  type: "email",
231
225
  value: email,
232
- onChange: (e) => {
233
- setEmail(e.target.value);
234
- if (error) setError(null);
235
- },
226
+ onChange: (e) => setEmail(e.target.value),
236
227
  onKeyDown: handleKeyDown,
237
228
  placeholder: "hello@gmail.com",
238
229
  autoFocus: true,
@@ -289,20 +280,12 @@ function formatClassTime(cls) {
289
280
  const em = endTotal % 60;
290
281
  return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
291
282
  }
292
- function formatBookingLabel(cls) {
293
- const price = cls.price;
294
- const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
295
- return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
296
- }
297
283
  function getBookingsOnDate(cls, date) {
298
284
  if (!cls.bookings?.length) return 0;
299
- const target = new Date(date);
300
- target.setHours(0, 0, 0, 0);
285
+ const ds = date.toISOString().split("T")[0];
301
286
  return cls.bookings.filter((b) => {
302
287
  try {
303
- const bookingDate = new Date(b.classDate);
304
- bookingDate.setHours(0, 0, 0, 0);
305
- return bookingDate.getTime() === target.getTime();
288
+ return new Date(b.classDate).toISOString().split("T")[0] === ds;
306
289
  } catch {
307
290
  return false;
308
291
  }
@@ -606,7 +589,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
606
589
  if (!cls.id) return;
607
590
  onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
608
591
  },
609
- children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
592
+ children: isFull ? "Join Waitlist" : "Book Now"
610
593
  }
611
594
  )
612
595
  ] })
@@ -648,17 +631,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
648
631
  const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
649
632
  const [modalState, setModalState] = (0, import_react3.useState)(null);
650
633
  const switchScheduleIdRef = (0, import_react3.useRef)(null);
651
- const liveScheduleIdRef = (0, import_react3.useRef)(null);
652
- const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
653
- const id = liveScheduleIdRef.current;
654
- if (!id) return;
655
- try {
656
- const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
657
- const data = await res.json();
658
- if (data?.id) setSchedule(data);
659
- } catch {
660
- }
661
- }, []);
662
634
  const dates = (0, import_react3.useMemo)(() => {
663
635
  const today = /* @__PURE__ */ new Date();
664
636
  today.setHours(0, 0, 0, 0);
@@ -678,18 +650,6 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
678
650
  }
679
651
  }
680
652
  }, [schedule, dates]);
681
- (0, import_react3.useEffect)(() => {
682
- if (typeof window === "undefined") return;
683
- const onVisible = () => {
684
- if (!document.hidden) void refetchLiveSchedule();
685
- };
686
- window.addEventListener("focus", refetchLiveSchedule);
687
- document.addEventListener("visibilitychange", onVisible);
688
- return () => {
689
- window.removeEventListener("focus", refetchLiveSchedule);
690
- document.removeEventListener("visibilitychange", onVisible);
691
- };
692
- }, [refetchLiveSchedule]);
693
653
  (0, import_react3.useEffect)(() => {
694
654
  if (typeof window === "undefined") return;
695
655
  const isInEditor = window.self !== window.top;
@@ -751,7 +711,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
751
711
  setLoading(false);
752
712
  return;
753
713
  }
754
- liveScheduleIdRef.current = effectiveId;
714
+ ;
755
715
  (async () => {
756
716
  try {
757
717
  const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
@@ -808,14 +768,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
808
768
  const data = await res.json().catch(() => ({}));
809
769
  throw new Error(data?.message ?? "Something went wrong. Please try again.");
810
770
  }
811
- await refetchLiveSchedule();
812
771
  };
813
772
  const handleReplaceSchedule = () => {
814
773
  setIsHovered(false);
815
- window.parent.postMessage(
816
- { type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
817
- "*"
818
- );
774
+ if (schedule) {
775
+ window.parent.postMessage({
776
+ type: "ow:schedule-connected",
777
+ schedule: { id: schedule.id, name: schedule.name },
778
+ insertAfter
779
+ }, "*");
780
+ } else {
781
+ window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
782
+ }
819
783
  };
820
784
  if (!inEditor && !loading && !schedule) return null;
821
785
  const sectionId = `scheduling-${insertAfter}`;
@@ -858,19 +822,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
858
822
  ),
859
823
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
860
824
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
861
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
862
- "h2",
863
- {
864
- className: "font-display text-center m-0 text-(--color-dark,#200C02)",
865
- style: {
866
- fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
867
- fontWeight: "var(--font-weight-heading, 400)",
868
- lineHeight: 1.05,
869
- letterSpacing: "-0.02em"
870
- },
871
- children: schedule?.name ?? "Book an appointment"
872
- }
873
- ),
825
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
874
826
  schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
875
827
  ] }),
876
828
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
@@ -6133,8 +6085,6 @@ var ICONS = {
6133
6085
  insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
6134
6086
  insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
6135
6087
  };
6136
- var TOOLBAR_PILL_PADDING = 2;
6137
- var TOOLBAR_TOGGLE_GAP = 4;
6138
6088
  var TOOLBAR_GROUPS = [
6139
6089
  [
6140
6090
  { cmd: "bold", title: "Bold" },
@@ -6253,9 +6203,9 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
6253
6203
  const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
6254
6204
  return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
6255
6205
  }
6256
- function calcToolbarPos(rect, parentScroll, approxW = 306) {
6206
+ function calcToolbarPos(rect, parentScroll, approxW = 330) {
6257
6207
  const GAP = 8;
6258
- const APPROX_H = 32;
6208
+ const APPROX_H = 36;
6259
6209
  const APPROX_W = approxW;
6260
6210
  const clip = getIframeVisibleClip(parentScroll);
6261
6211
  const clipTop = clip?.top ?? 0;
@@ -6313,15 +6263,6 @@ function FloatingToolbar({
6313
6263
  left,
6314
6264
  transform,
6315
6265
  zIndex: 2147483647,
6316
- background: "#fff",
6317
- border: "1px solid #E7E5E4",
6318
- borderRadius: 6,
6319
- boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
6320
- display: "flex",
6321
- alignItems: "center",
6322
- padding: TOOLBAR_PILL_PADDING,
6323
- gap: TOOLBAR_TOGGLE_GAP,
6324
- fontFamily: "sans-serif",
6325
6266
  pointerEvents: "auto"
6326
6267
  },
6327
6268
  children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CustomToolbar, { children: [
@@ -8238,32 +8179,7 @@ function OhhwellsBridge() {
8238
8179
  onSubmit: handleLinkPopoverSubmit
8239
8180
  },
8240
8181
  `${linkPopover.key}-${pathname}`
8241
- ) : null,
8242
- sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
8243
- "div",
8244
- {
8245
- "data-ohw-section-insert-line": "",
8246
- className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
8247
- style: { top: sectionGap.y, transform: "translateY(-50%)" },
8248
- children: [
8249
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
8250
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8251
- Badge,
8252
- {
8253
- className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
8254
- onClick: () => {
8255
- window.parent.postMessage(
8256
- { type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
8257
- "*"
8258
- );
8259
- },
8260
- children: "Add Section"
8261
- }
8262
- ),
8263
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
8264
- ]
8265
- }
8266
- )
8182
+ ) : null
8267
8183
  ] }),
8268
8184
  bridgeRoot
8269
8185
  ) : null;