@patientos/website-kit 0.1.0 → 0.2.1
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/dist/{chunk-G3U6EXJM.js → chunk-BW7YKCKH.js} +58 -4
- package/dist/{chunk-Q4URDZAK.js → chunk-CRYD7EXD.js} +1 -1
- package/dist/{chunk-TOPPLOH2.js → chunk-EO64UB5F.js} +18 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/islands-impl.d.ts +4 -4
- package/dist/islands-impl.js +2 -2
- package/dist/islands-registry.js +3 -3
- package/dist/{portal-account-EhOtLV5u.d.ts → portal-account-CaK1lqSZ.d.ts} +22 -2
- package/dist/{portal-account.client-CTget1-3.d.ts → portal-account.client-CqnsCCiC.d.ts} +1 -1
- package/dist/portal-booking-client.d.ts +2 -2
- package/dist/portal-booking-client.js +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,44 @@ import * as React4 from "react";
|
|
|
4
4
|
// src/portal-shared.client.tsx
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
var apiOrigin = "";
|
|
8
|
+
var apiOriginLocked = false;
|
|
9
|
+
function normalizePortalApiOrigin(raw) {
|
|
10
|
+
let u;
|
|
11
|
+
try {
|
|
12
|
+
u = new URL(raw.trim());
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const loopback = u.hostname === "localhost" || u.hostname === "127.0.0.1";
|
|
17
|
+
if (u.protocol !== "https:" && !(u.protocol === "http:" && loopback)) return null;
|
|
18
|
+
if (u.username || u.password || u.search || u.hash) return null;
|
|
19
|
+
if (u.pathname !== "/" && u.pathname !== "") return null;
|
|
20
|
+
return u.origin;
|
|
21
|
+
}
|
|
22
|
+
function configurePortalApiOrigin(raw) {
|
|
23
|
+
const wanted = raw?.trim();
|
|
24
|
+
if (!wanted) return;
|
|
25
|
+
const origin = normalizePortalApiOrigin(wanted);
|
|
26
|
+
if (!origin) {
|
|
27
|
+
console.error("[portal] ignoring a malformed portal API origin", wanted);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (apiOriginLocked) {
|
|
31
|
+
if (origin !== apiOrigin) {
|
|
32
|
+
console.error("[portal] refusing to re-point the portal API origin", {
|
|
33
|
+
configured: apiOrigin,
|
|
34
|
+
rejected: origin
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
apiOrigin = origin;
|
|
40
|
+
apiOriginLocked = true;
|
|
41
|
+
}
|
|
42
|
+
function portalApiUrl(path) {
|
|
43
|
+
return apiOrigin && path.startsWith("/") ? apiOrigin + path : path;
|
|
44
|
+
}
|
|
7
45
|
var PORTAL_MAGIC_LINK_URL = "/portal/api/magic-link";
|
|
8
46
|
var PORTAL_SIGN_OUT_URL = "/portal/api/sign-out";
|
|
9
47
|
var PORTAL_REQUEST_INIT = { credentials: "include", cache: "no-store" };
|
|
@@ -30,14 +68,16 @@ async function readPortalResult(res) {
|
|
|
30
68
|
}
|
|
31
69
|
async function portalGet(url, fetchImpl) {
|
|
32
70
|
try {
|
|
33
|
-
return await readPortalResult(
|
|
71
|
+
return await readPortalResult(
|
|
72
|
+
await portalFetch(fetchImpl)(portalApiUrl(url), PORTAL_REQUEST_INIT)
|
|
73
|
+
);
|
|
34
74
|
} catch {
|
|
35
75
|
return { ok: false, status: null, error: null };
|
|
36
76
|
}
|
|
37
77
|
}
|
|
38
78
|
async function portalSend(url, method, body, fetchImpl) {
|
|
39
79
|
try {
|
|
40
|
-
const res = await portalFetch(fetchImpl)(url, {
|
|
80
|
+
const res = await portalFetch(fetchImpl)(portalApiUrl(url), {
|
|
41
81
|
...PORTAL_REQUEST_INIT,
|
|
42
82
|
method,
|
|
43
83
|
headers: { "content-type": "application/json" },
|
|
@@ -50,7 +90,10 @@ async function portalSend(url, method, body, fetchImpl) {
|
|
|
50
90
|
}
|
|
51
91
|
async function portalDelete(url, fetchImpl) {
|
|
52
92
|
try {
|
|
53
|
-
const res = await portalFetch(fetchImpl)(url, {
|
|
93
|
+
const res = await portalFetch(fetchImpl)(portalApiUrl(url), {
|
|
94
|
+
...PORTAL_REQUEST_INIT,
|
|
95
|
+
method: "DELETE"
|
|
96
|
+
});
|
|
54
97
|
return await readPortalResult(res);
|
|
55
98
|
} catch {
|
|
56
99
|
return { ok: false, status: null, error: null };
|
|
@@ -89,9 +132,18 @@ async function signOutOfPortal(fetchImpl) {
|
|
|
89
132
|
const res = await portalSend(PORTAL_SIGN_OUT_URL, "POST", {}, fetchImpl);
|
|
90
133
|
return { ok: res.ok };
|
|
91
134
|
}
|
|
135
|
+
var PORTAL_RETURN_PATH = "/portal/return";
|
|
136
|
+
function encodeReturnTarget(url) {
|
|
137
|
+
const bytes = new TextEncoder().encode(url);
|
|
138
|
+
let binary = "";
|
|
139
|
+
for (const b of bytes) binary += String.fromCharCode(b);
|
|
140
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
141
|
+
}
|
|
92
142
|
function currentPagePath() {
|
|
93
143
|
if (typeof window === "undefined") return "/";
|
|
94
|
-
|
|
144
|
+
const path = `${window.location.pathname || "/"}${window.location.search}${window.location.hash}`;
|
|
145
|
+
if (!apiOrigin) return path;
|
|
146
|
+
return `${PORTAL_RETURN_PATH}?to=${encodeReturnTarget(window.location.origin + path)}`;
|
|
95
147
|
}
|
|
96
148
|
var LOCALE = "en-AU";
|
|
97
149
|
function parseInstant(iso) {
|
|
@@ -1198,6 +1250,8 @@ export {
|
|
|
1198
1250
|
formatSlotTime,
|
|
1199
1251
|
zoneAbbr,
|
|
1200
1252
|
SlotPicker,
|
|
1253
|
+
configurePortalApiOrigin,
|
|
1254
|
+
portalApiUrl,
|
|
1201
1255
|
PORTAL_REQUEST_INIT,
|
|
1202
1256
|
portalGet,
|
|
1203
1257
|
portalSend,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
SlotPicker,
|
|
26
26
|
SummarisedFieldErrors,
|
|
27
27
|
adoptClaimToken,
|
|
28
|
+
configurePortalApiOrigin,
|
|
28
29
|
currentPagePath,
|
|
29
30
|
describedBy,
|
|
30
31
|
effectiveFee,
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
patientos,
|
|
55
56
|
persistClaimToken,
|
|
56
57
|
pickDeliveryOption,
|
|
58
|
+
portalApiUrl,
|
|
57
59
|
portalDelete,
|
|
58
60
|
portalGet,
|
|
59
61
|
portalSend,
|
|
@@ -64,7 +66,7 @@ import {
|
|
|
64
66
|
signOutOfPortal,
|
|
65
67
|
writePortalSignedInHint,
|
|
66
68
|
zoneAbbr
|
|
67
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-BW7YKCKH.js";
|
|
68
70
|
import {
|
|
69
71
|
__export
|
|
70
72
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -1492,13 +1494,14 @@ function portalSurfaceHref(surface, portalUrl) {
|
|
|
1492
1494
|
function PortalPanel({
|
|
1493
1495
|
surface,
|
|
1494
1496
|
portalUrl,
|
|
1497
|
+
portalApiOrigin,
|
|
1495
1498
|
className
|
|
1496
1499
|
}) {
|
|
1497
1500
|
return /* @__PURE__ */ jsxs4(
|
|
1498
1501
|
Island,
|
|
1499
1502
|
{
|
|
1500
1503
|
name: "portal-panel",
|
|
1501
|
-
props: { surface, portalUrl },
|
|
1504
|
+
props: { surface, portalUrl, portalApiOrigin },
|
|
1502
1505
|
className: ["sk-portal-panel", className].filter(Boolean).join(" "),
|
|
1503
1506
|
children: [
|
|
1504
1507
|
/* @__PURE__ */ jsx5("h2", { className: "sk-portal-panel__heading", children: PORTAL_SURFACE_LABEL[surface] ?? "Your portal" }),
|
|
@@ -4548,7 +4551,7 @@ async function loadPortalPanel(surface, fetchImpl) {
|
|
|
4548
4551
|
let body;
|
|
4549
4552
|
try {
|
|
4550
4553
|
const res = await fetchImpl(
|
|
4551
|
-
`${SUMMARY_URL}?surface=${encodeURIComponent(surface)}
|
|
4554
|
+
portalApiUrl(`${SUMMARY_URL}?surface=${encodeURIComponent(surface)}`),
|
|
4552
4555
|
PORTAL_REQUEST_INIT
|
|
4553
4556
|
);
|
|
4554
4557
|
body = await res.json();
|
|
@@ -4581,9 +4584,11 @@ function itemMeta(item) {
|
|
|
4581
4584
|
function PortalPanelClient({
|
|
4582
4585
|
surface,
|
|
4583
4586
|
portalUrl,
|
|
4587
|
+
portalApiOrigin,
|
|
4584
4588
|
initialState,
|
|
4585
4589
|
fetchImpl
|
|
4586
4590
|
}) {
|
|
4591
|
+
configurePortalApiOrigin(portalApiOrigin);
|
|
4587
4592
|
const [state, setState] = React16.useState(initialState ?? { kind: "loading" });
|
|
4588
4593
|
React16.useEffect(() => {
|
|
4589
4594
|
if (initialState) return;
|
|
@@ -10260,6 +10265,7 @@ function PortalAccount({
|
|
|
10260
10265
|
bookHref,
|
|
10261
10266
|
appointmentsHref,
|
|
10262
10267
|
funnelHref,
|
|
10268
|
+
portalApiOrigin,
|
|
10263
10269
|
className
|
|
10264
10270
|
}) {
|
|
10265
10271
|
const href = portalUrl ?? "/portal";
|
|
@@ -10276,6 +10282,7 @@ function PortalAccount({
|
|
|
10276
10282
|
portalUrl,
|
|
10277
10283
|
bookHref,
|
|
10278
10284
|
appointmentsHref,
|
|
10285
|
+
portalApiOrigin,
|
|
10279
10286
|
...isBook ? { funnelHref, services, publicApi, clinicPhone } : {}
|
|
10280
10287
|
},
|
|
10281
10288
|
className: ["sk-portal-account", className].filter(Boolean).join(" "),
|
|
@@ -10380,8 +10387,11 @@ var VALIDATE_URL = "/api/address/validate";
|
|
|
10380
10387
|
async function searchPortalAddresses(query) {
|
|
10381
10388
|
const q = query.trim();
|
|
10382
10389
|
if (q.length < 3) return [];
|
|
10383
|
-
const res = await fetch(`${AUTOCOMPLETE_URL}?q=${encodeURIComponent(q)}
|
|
10384
|
-
|
|
10390
|
+
const res = await fetch(portalApiUrl(`${AUTOCOMPLETE_URL}?q=${encodeURIComponent(q)}`), {
|
|
10391
|
+
// `include`, not `same-origin`: on a separately-deployed clinic site this resolves to
|
|
10392
|
+
// the APP's origin, and the endpoint's only door for a patient is the portal session
|
|
10393
|
+
// cookie (address-google.server.ts `hasAddressAccess`). Same-origin it is identical.
|
|
10394
|
+
credentials: "include",
|
|
10385
10395
|
headers: { accept: "application/json" }
|
|
10386
10396
|
});
|
|
10387
10397
|
if (!res.ok) return [];
|
|
@@ -10389,9 +10399,9 @@ async function searchPortalAddresses(query) {
|
|
|
10389
10399
|
return body.suggestions ?? [];
|
|
10390
10400
|
}
|
|
10391
10401
|
async function validatePortalAddress(address) {
|
|
10392
|
-
const res = await fetch(VALIDATE_URL, {
|
|
10402
|
+
const res = await fetch(portalApiUrl(VALIDATE_URL), {
|
|
10393
10403
|
method: "POST",
|
|
10394
|
-
credentials: "
|
|
10404
|
+
credentials: "include",
|
|
10395
10405
|
headers: { "content-type": "application/json" },
|
|
10396
10406
|
body: JSON.stringify({ address })
|
|
10397
10407
|
});
|
|
@@ -10852,6 +10862,7 @@ async function savePortalProfileAndReload(patch, fetchImpl) {
|
|
|
10852
10862
|
}
|
|
10853
10863
|
function PortalAccountClient(props) {
|
|
10854
10864
|
const { surface } = props;
|
|
10865
|
+
configurePortalApiOrigin(props.portalApiOrigin);
|
|
10855
10866
|
if (surface === "book") return /* @__PURE__ */ jsx26(PortalAccountBookLauncher, { ...props });
|
|
10856
10867
|
return /* @__PURE__ */ jsx26(PortalAccountSurfaceClient, { ...props, surface });
|
|
10857
10868
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
export { ISLAND_ATTR, ISLAND_PROPS_ATTR, Island, IslandProps, IslandRegistry, mountIslandsWith, readIslandProps } from './islands.js';
|
|
4
4
|
export { ISLANDS, IslandName, mountIslands } from './islands-registry.js';
|
|
5
5
|
export { B as BookingBlock, a as BookingBlockMarkerProps, b as BookingBlockProps, c as BookingTypeOption, C as Cart, d as CartMarkerProps, e as CartProps, f as CertificateFunnel, g as CertificateFunnelMarkerProps, h as CertificateFunnelProps, i as Checkout, j as CheckoutMarkerProps, k as CheckoutProps, F as FunnelPublicApi, l as FunnelServiceOption, S as Store, m as StoreMarkerProps, n as StoreProps } from './checkout-block-CrO7OxI9.js';
|
|
6
|
-
export { P as PortalAccount, a as PortalAccountMarkerProps, b as PortalAccountProps, c as PortalAccountSurface, d as PortalPanel, e as PortalPanelMarkerProps, f as PortalPanelProps, g as PortalSurface } from './portal-account-
|
|
6
|
+
export { P as PortalAccount, a as PortalAccountMarkerProps, b as PortalAccountProps, c as PortalAccountSurface, d as PortalPanel, e as PortalPanelMarkerProps, f as PortalPanelProps, g as PortalSurface } from './portal-account-CaK1lqSZ.js';
|
|
7
7
|
export { PatientSurfaceTheme, patientSurfaceTheme } from './patient-surface-theme.js';
|
|
8
8
|
export { Rgb, contrastRatio, deriveForeground, parseHexColor, relativeLuminance } from './contrast.js';
|
|
9
9
|
export { AnswerValue, Answers, ShowWhenCondition, evaluateShowWhen, visibleQuestions } from './show-when.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ISLANDS,
|
|
3
3
|
mountIslands
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CRYD7EXD.js";
|
|
5
5
|
import {
|
|
6
6
|
PortalAccount,
|
|
7
7
|
PortalPanel,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getPublicApi,
|
|
11
11
|
getServices,
|
|
12
12
|
getThemeTokens
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EO64UB5F.js";
|
|
14
14
|
import {
|
|
15
15
|
BPOINT_SCRIPT_ORIGIN,
|
|
16
16
|
BPOINT_SCRIPT_URL,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
mountIslandsWith,
|
|
31
31
|
readIslandProps
|
|
32
32
|
} from "./chunk-THMT43MV.js";
|
|
33
|
-
import "./chunk-
|
|
33
|
+
import "./chunk-BW7YKCKH.js";
|
|
34
34
|
import {
|
|
35
35
|
contrastRatio,
|
|
36
36
|
deriveForeground,
|
package/dist/islands-impl.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { b as BookingBlockProps, h as CertificateFunnelProps, n as StoreProps, e as CartProps, k as CheckoutProps } from './checkout-block-CrO7OxI9.js';
|
|
3
|
-
import { f as PortalPanelProps } from './portal-account-
|
|
4
|
-
import { F as FetchLike } from './portal-account.client-
|
|
5
|
-
export { P as PortalAccountClient } from './portal-account.client-
|
|
3
|
+
import { f as PortalPanelProps } from './portal-account-CaK1lqSZ.js';
|
|
4
|
+
import { F as FetchLike } from './portal-account.client-CqnsCCiC.js';
|
|
5
|
+
export { P as PortalAccountClient } from './portal-account.client-CqnsCCiC.js';
|
|
6
6
|
|
|
7
7
|
declare function BookingBlockClient(props: BookingBlockProps): React.ReactElement;
|
|
8
8
|
|
|
@@ -57,7 +57,7 @@ type PortalPanelClientProps = PortalPanelProps & {
|
|
|
57
57
|
/** Test seam: the fetch used for whoami/summary/magic-link. Defaults to global. */
|
|
58
58
|
fetchImpl?: FetchLike;
|
|
59
59
|
};
|
|
60
|
-
declare function PortalPanelClient({ surface, portalUrl, initialState, fetchImpl, }: PortalPanelClientProps): React.ReactElement;
|
|
60
|
+
declare function PortalPanelClient({ surface, portalUrl, portalApiOrigin, initialState, fetchImpl, }: PortalPanelClientProps): React.ReactElement;
|
|
61
61
|
|
|
62
62
|
declare function StoreClient({ categoryHandle, title, columns }: StoreProps): React.ReactElement;
|
|
63
63
|
|
package/dist/islands-impl.js
CHANGED
|
@@ -6,11 +6,11 @@ import {
|
|
|
6
6
|
PortalAccountClient,
|
|
7
7
|
PortalPanelClient,
|
|
8
8
|
StoreClient
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-EO64UB5F.js";
|
|
10
10
|
import "./chunk-ZOF22TJA.js";
|
|
11
11
|
import "./chunk-QDO3SJWR.js";
|
|
12
12
|
import "./chunk-THMT43MV.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-BW7YKCKH.js";
|
|
14
14
|
import "./chunk-MLKGABMK.js";
|
|
15
15
|
export {
|
|
16
16
|
BookingBlockClient,
|
package/dist/islands-registry.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ISLANDS,
|
|
3
3
|
mountIslands
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-CRYD7EXD.js";
|
|
5
|
+
import "./chunk-EO64UB5F.js";
|
|
6
6
|
import "./chunk-ZOF22TJA.js";
|
|
7
7
|
import "./chunk-QDO3SJWR.js";
|
|
8
8
|
import "./chunk-THMT43MV.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-BW7YKCKH.js";
|
|
10
10
|
import "./chunk-MLKGABMK.js";
|
|
11
11
|
export {
|
|
12
12
|
ISLANDS,
|
|
@@ -11,6 +11,12 @@ type PortalPanelProps = {
|
|
|
11
11
|
* `/portal` path on this same origin.
|
|
12
12
|
*/
|
|
13
13
|
portalUrl?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The APP's origin, when the site is deployed SEPARATELY from it (PAT-908). Omitted ⇒
|
|
16
|
+
* same-origin, which is what a one-origin clinic site wants. See the fuller note on
|
|
17
|
+
* `PortalAccountProps.portalApiOrigin` — the two islands take the same value.
|
|
18
|
+
*/
|
|
19
|
+
portalApiOrigin?: string;
|
|
14
20
|
};
|
|
15
21
|
/** Marker-only props: the island config plus presentation the page controls. */
|
|
16
22
|
type PortalPanelMarkerProps = PortalPanelProps & {
|
|
@@ -26,7 +32,7 @@ type PortalPanelMarkerProps = PortalPanelProps & {
|
|
|
26
32
|
* gets permanently. A `visibility:hidden` / `opacity:0` placeholder would make the
|
|
27
33
|
* no-JS experience a blank box.
|
|
28
34
|
*/
|
|
29
|
-
declare function PortalPanel({ surface, portalUrl, className, }: PortalPanelMarkerProps): React.ReactElement;
|
|
35
|
+
declare function PortalPanel({ surface, portalUrl, portalApiOrigin, className, }: PortalPanelMarkerProps): React.ReactElement;
|
|
30
36
|
|
|
31
37
|
/** A service the launcher can offer — what the build snapshot carries, nothing more. */
|
|
32
38
|
type LauncherService = {
|
|
@@ -88,6 +94,20 @@ type PortalAccountProps = {
|
|
|
88
94
|
* patient who picks a service (PAT-899). Omitted ⇒ `/certificates`.
|
|
89
95
|
*/
|
|
90
96
|
funnelHref?: string;
|
|
97
|
+
/**
|
|
98
|
+
* The APP's origin, when this site is deployed SEPARATELY from it (PAT-908).
|
|
99
|
+
*
|
|
100
|
+
* A one-origin clinic site omits this: the app serves `/portal/api/*` on the same host
|
|
101
|
+
* and every call is a relative path, exactly as before. A site on its own deployment —
|
|
102
|
+
* pocketdoc.com.au on a Worker, the app behind `my.pocketdoc.com.au` — names the app
|
|
103
|
+
* here, and every portal request is made against it with the patient cookie attached.
|
|
104
|
+
*
|
|
105
|
+
* It must be a bare `https://host[:port]` that the clinic has registered in its
|
|
106
|
+
* `web_form` channel `allowedOrigins`, or the app answers 403 with no ACAO. Keep it
|
|
107
|
+
* SAME-SITE with the page (a subdomain of the same registrable domain): a genuinely
|
|
108
|
+
* cross-SITE origin gets no cookie from the browser and every call reads signed-out.
|
|
109
|
+
*/
|
|
110
|
+
portalApiOrigin?: string;
|
|
91
111
|
/** The clinic's services, for the `book` launcher. */
|
|
92
112
|
services?: LauncherService[];
|
|
93
113
|
/** How the launcher reaches the public API to price those services. */
|
|
@@ -108,6 +128,6 @@ type PortalAccountMarkerProps = PortalAccountProps & {
|
|
|
108
128
|
* It shows no patient data because there is none at build time: the page is ONE static
|
|
109
129
|
* artifact served to every visitor.
|
|
110
130
|
*/
|
|
111
|
-
declare function PortalAccount({ surface, portalUrl, bookHref, appointmentsHref, funnelHref, className, }: PortalAccountMarkerProps): React.ReactElement;
|
|
131
|
+
declare function PortalAccount({ surface, portalUrl, bookHref, appointmentsHref, funnelHref, portalApiOrigin, className, }: PortalAccountMarkerProps): React.ReactElement;
|
|
112
132
|
|
|
113
133
|
export { PortalAccount as P, type PortalAccountMarkerProps as a, type PortalAccountProps as b, type PortalAccountSurface as c, PortalPanel as d, type PortalPanelMarkerProps as e, type PortalPanelProps as f, type PortalSurface as g };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { b as PortalAccountProps } from './portal-account-
|
|
2
|
+
import { b as PortalAccountProps } from './portal-account-CaK1lqSZ.js';
|
|
3
3
|
|
|
4
4
|
/** The injectable fetch. Present so every behaviour here is provable without a DOM. */
|
|
5
5
|
type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { a as PortalAppointment, F as FetchLike, b as PortalAppointmentsBody, c as PortalResult } from './portal-account.client-
|
|
3
|
-
import './portal-account-
|
|
2
|
+
import { a as PortalAppointment, F as FetchLike, b as PortalAppointmentsBody, c as PortalResult } from './portal-account.client-CqnsCCiC.js';
|
|
3
|
+
import './portal-account-CaK1lqSZ.js';
|
|
4
4
|
|
|
5
5
|
/** One bookable instant, collapsing the practitioners free at the same time. */
|
|
6
6
|
interface TimeSlot {
|