@se-studio/hubspot 1.0.0
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/CHANGELOG.md +16 -0
- package/README.md +92 -0
- package/dist/external/createHubspotFormExternalRenderer.d.ts +23 -0
- package/dist/external/createHubspotFormExternalRenderer.d.ts.map +1 -0
- package/dist/external/createHubspotFormExternalRenderer.js +26 -0
- package/dist/external/createHubspotFormExternalRenderer.js.map +1 -0
- package/dist/forms/client/HubspotDynamicForm.d.ts +13 -0
- package/dist/forms/client/HubspotDynamicForm.d.ts.map +1 -0
- package/dist/forms/client/HubspotDynamicForm.js +101 -0
- package/dist/forms/client/HubspotDynamicForm.js.map +1 -0
- package/dist/forms/client/dependentFields.d.ts +11 -0
- package/dist/forms/client/dependentFields.d.ts.map +1 -0
- package/dist/forms/client/dependentFields.js +39 -0
- package/dist/forms/client/dependentFields.js.map +1 -0
- package/dist/forms/client/getCookieValue.d.ts +2 -0
- package/dist/forms/client/getCookieValue.d.ts.map +1 -0
- package/dist/forms/client/getCookieValue.js +8 -0
- package/dist/forms/client/getCookieValue.js.map +1 -0
- package/dist/forms/client/renderHubspotField.d.ts +11 -0
- package/dist/forms/client/renderHubspotField.d.ts.map +1 -0
- package/dist/forms/client/renderHubspotField.js +61 -0
- package/dist/forms/client/renderHubspotField.js.map +1 -0
- package/dist/forms/client/useHubspotSubmit.d.ts +15 -0
- package/dist/forms/client/useHubspotSubmit.d.ts.map +1 -0
- package/dist/forms/client/useHubspotSubmit.js +93 -0
- package/dist/forms/client/useHubspotSubmit.js.map +1 -0
- package/dist/forms/server/getFormDefinition.d.ts +7 -0
- package/dist/forms/server/getFormDefinition.d.ts.map +1 -0
- package/dist/forms/server/getFormDefinition.js +24 -0
- package/dist/forms/server/getFormDefinition.js.map +1 -0
- package/dist/forms/server/hubspotFormTag.d.ts +3 -0
- package/dist/forms/server/hubspotFormTag.d.ts.map +1 -0
- package/dist/forms/server/hubspotFormTag.js +5 -0
- package/dist/forms/server/hubspotFormTag.js.map +1 -0
- package/dist/forms/server/mapApiResponse.d.ts +4 -0
- package/dist/forms/server/mapApiResponse.d.ts.map +1 -0
- package/dist/forms/server/mapApiResponse.js +91 -0
- package/dist/forms/server/mapApiResponse.js.map +1 -0
- package/dist/forms/server/submitForm.d.ts +8 -0
- package/dist/forms/server/submitForm.d.ts.map +1 -0
- package/dist/forms/server/submitForm.js +32 -0
- package/dist/forms/server/submitForm.js.map +1 -0
- package/dist/forms/types.d.ts +102 -0
- package/dist/forms/types.d.ts.map +1 -0
- package/dist/forms/types.js +2 -0
- package/dist/forms/types.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +6 -0
- package/dist/server.js.map +1 -0
- package/dist/tracking/HubSpotAnalyticsAdapter.d.ts +23 -0
- package/dist/tracking/HubSpotAnalyticsAdapter.d.ts.map +1 -0
- package/dist/tracking/HubSpotAnalyticsAdapter.js +84 -0
- package/dist/tracking/HubSpotAnalyticsAdapter.js.map +1 -0
- package/dist/tracking/createHubSpotBootstrapScript.d.ts +6 -0
- package/dist/tracking/createHubSpotBootstrapScript.d.ts.map +1 -0
- package/dist/tracking/createHubSpotBootstrapScript.js +10 -0
- package/dist/tracking/createHubSpotBootstrapScript.js.map +1 -0
- package/docs/llms.md +24 -0
- package/package.json +76 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# @se-studio/hubspot
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add `@se-studio/hubspot` shared package for HubSpot tracking (`HubSpotAnalyticsAdapter`) and API-driven form rendering with CMS external component support.
|
|
8
|
+
|
|
9
|
+
Add `CompositeAnalyticsAdapter` and `AnalyticsPageTracker` to core-ui for multi-provider analytics (GTM + HubSpot SPA Mode B).
|
|
10
|
+
|
|
11
|
+
Update `AbTestReporter` to route experiment impressions through `useAnalytics`, including `hubspot_event` for HubSpot behavioural events.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- @se-studio/core-ui@1.9.0
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @se-studio/hubspot
|
|
2
|
+
|
|
3
|
+
HubSpot tracking and API-driven form rendering for Next.js marketing sites.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **`HubSpotAnalyticsAdapter`** — `AnalyticsAdapter` for HubSpot tracking code (SPA Mode B page views, custom behavioural events)
|
|
8
|
+
- **`HubspotDynamicForm`** — React renderer from HubSpot Marketing Forms API definitions
|
|
9
|
+
- **`createHubspotFormExternalRenderer`** — CMS external component factory (`externalComponentType: "Hubspot form"`)
|
|
10
|
+
- **Per-form fetch** — `GET /marketing/v3/forms/{formId}` with Next.js `unstable_cache` (no bulk form download)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @se-studio/hubspot
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Environment variables
|
|
19
|
+
|
|
20
|
+
| Variable | Purpose |
|
|
21
|
+
|----------|---------|
|
|
22
|
+
| `HUBSPOT_PORTAL_ID` | Portal ID for tracking script and form submissions |
|
|
23
|
+
| `HUBSPOT_PAT` | Private app token with `forms` scope (server-only, form definition fetch) |
|
|
24
|
+
|
|
25
|
+
## Analytics (with GTM)
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
import { AnalyticsPageTracker, AnalyticsProvider, CompositeAnalyticsAdapter, ConsentAwareAdapter, GoogleTagManagerAdapter } from '@se-studio/core-ui';
|
|
29
|
+
import { AbTestReporter } from '@se-studio/ab-testing/components';
|
|
30
|
+
import { HubSpotAnalyticsAdapter, createHubSpotBootstrapScript } from '@se-studio/hubspot';
|
|
31
|
+
import Script from 'next/script';
|
|
32
|
+
|
|
33
|
+
const adapter = new ConsentAwareAdapter(
|
|
34
|
+
new CompositeAnalyticsAdapter([
|
|
35
|
+
new GoogleTagManagerAdapter({ containerId: process.env.GTM_TAG! }),
|
|
36
|
+
new HubSpotAnalyticsAdapter({ portalId: process.env.HUBSPOT_PORTAL_ID! }),
|
|
37
|
+
]),
|
|
38
|
+
'analytics',
|
|
39
|
+
hasConsent,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// layout.tsx — before HubSpot script loads
|
|
43
|
+
<Script id="hubspot-bootstrap" strategy="beforeInteractive"
|
|
44
|
+
dangerouslySetInnerHTML={{ __html: createHubSpotBootstrapScript('/initial-path') }} />
|
|
45
|
+
|
|
46
|
+
<AnalyticsProvider adapter={adapter}>
|
|
47
|
+
<AnalyticsPageTracker />
|
|
48
|
+
<AbTestReporter />
|
|
49
|
+
{children}
|
|
50
|
+
</AnalyticsProvider>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## CMS external component
|
|
54
|
+
|
|
55
|
+
Add `"Hubspot form"` to your `externalComponent` enum. `data` JSON:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"formId": "hubspot-form-guid",
|
|
60
|
+
"portalId": "optional-override",
|
|
61
|
+
"submitButtonText": "Optional label",
|
|
62
|
+
"hiddenFields": { "campaign": "value" }
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { defineExternalComponent } from '@se-studio/core-ui';
|
|
68
|
+
import { createHubspotFormExternalRenderer } from '@se-studio/hubspot/external';
|
|
69
|
+
import { Section } from '@/framework/Section';
|
|
70
|
+
|
|
71
|
+
export const HubspotFormRegistration = defineExternalComponent({
|
|
72
|
+
name: 'Hubspot form',
|
|
73
|
+
renderer: createHubspotFormExternalRenderer({
|
|
74
|
+
wrap: ({ information, children, componentName }) => (
|
|
75
|
+
<Section information={information} componentName={componentName}>
|
|
76
|
+
{children}
|
|
77
|
+
</Section>
|
|
78
|
+
),
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Cache revalidation
|
|
84
|
+
|
|
85
|
+
When a form changes in HubSpot, revalidate:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { revalidateTag } from 'next/cache';
|
|
89
|
+
import { hubspotFormTag } from '@se-studio/hubspot/server';
|
|
90
|
+
|
|
91
|
+
revalidateTag(hubspotFormTag(formId));
|
|
92
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ITyped } from '@se-studio/core-data-types';
|
|
2
|
+
import type { ExternalComponentRenderer } from '@se-studio/core-ui';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
import type { HubspotFormClassNames } from '../forms/types';
|
|
5
|
+
export interface HubspotFormExternalRendererOptions<TExternal extends ITyped> {
|
|
6
|
+
/** Wrap the form in the project's Section/layout component. */
|
|
7
|
+
wrap: (params: {
|
|
8
|
+
information: TExternal;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
componentName: string;
|
|
11
|
+
}) => ReactNode;
|
|
12
|
+
/** Resolve portal ID from env when not set in CMS data. */
|
|
13
|
+
getPortalId?: () => string | undefined;
|
|
14
|
+
/** Optional Tailwind/class overrides for form fields. */
|
|
15
|
+
classNames?: HubspotFormClassNames;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Factory for a CMS external component renderer (`externalComponentType: "Hubspot form"`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function createHubspotFormExternalRenderer<TExternal extends ITyped & {
|
|
21
|
+
data?: unknown;
|
|
22
|
+
}>(options: HubspotFormExternalRendererOptions<TExternal>): ExternalComponentRenderer<TExternal>;
|
|
23
|
+
//# sourceMappingURL=createHubspotFormExternalRenderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHubspotFormExternalRenderer.d.ts","sourceRoot":"","sources":["../../src/external/createHubspotFormExternalRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,qBAAqB,EAA2B,MAAM,gBAAgB,CAAC;AAErF,MAAM,WAAW,kCAAkC,CAAC,SAAS,SAAS,MAAM;IAC1E,+DAA+D;IAC/D,IAAI,EAAE,CAAC,MAAM,EAAE;QACb,WAAW,EAAE,SAAS,CAAC;QACvB,QAAQ,EAAE,SAAS,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;KACvB,KAAK,SAAS,CAAC;IAChB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IACvC,yDAAyD;IACzD,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,SAAS,SAAS,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EAC7F,OAAO,EAAE,kCAAkC,CAAC,SAAS,CAAC,GACrD,yBAAyB,CAAC,SAAS,CAAC,CA+BtC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { HubspotDynamicForm } from '../forms/client/HubspotDynamicForm';
|
|
3
|
+
import { getHubspotFormDefinition } from '../forms/server/getFormDefinition';
|
|
4
|
+
/**
|
|
5
|
+
* Factory for a CMS external component renderer (`externalComponentType: "Hubspot form"`).
|
|
6
|
+
*/
|
|
7
|
+
export function createHubspotFormExternalRenderer(options) {
|
|
8
|
+
const getPortalId = options.getPortalId ?? (() => process.env.HUBSPOT_PORTAL_ID);
|
|
9
|
+
return async function HubspotFormExternalRenderer({ information }) {
|
|
10
|
+
const data = (information.data ?? {});
|
|
11
|
+
const portalId = data.portalId ?? getPortalId();
|
|
12
|
+
if (!data.formId || !portalId) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const formDefinition = await getHubspotFormDefinition(data.formId);
|
|
16
|
+
if (!formDefinition) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
return options.wrap({
|
|
20
|
+
information,
|
|
21
|
+
componentName: 'Hubspot form',
|
|
22
|
+
children: (_jsx(HubspotDynamicForm, { portalId: portalId, formDefinition: formDefinition, submitButtonText: data.submitButtonText, classNames: options.classNames, hiddenFields: data.hiddenFields, initialValues: data.initialValues })),
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=createHubspotFormExternalRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createHubspotFormExternalRenderer.js","sourceRoot":"","sources":["../../src/external/createHubspotFormExternalRenderer.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAgB7E;;GAEG;AACH,MAAM,UAAU,iCAAiC,CAC/C,OAAsD;IAEtD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEjF,OAAO,KAAK,UAAU,2BAA2B,CAAC,EAAE,WAAW,EAAE;QAC/D,MAAM,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;QAEhD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CAAC;YAClB,WAAW;YACX,aAAa,EAAE,cAAc;YAC7B,QAAQ,EAAE,CACR,KAAC,kBAAkB,IACjB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EACvC,UAAU,EAAE,OAAO,CAAC,UAAU,EAC9B,YAAY,EAAE,IAAI,CAAC,YAAY,EAC/B,aAAa,EAAE,IAAI,CAAC,aAAa,GACjC,CACH;SACF,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { HubspotFieldResponse, HubspotFormClassNames, HubspotFormDefinition } from '../types';
|
|
2
|
+
export interface HubspotDynamicFormProps {
|
|
3
|
+
portalId: string;
|
|
4
|
+
formDefinition: HubspotFormDefinition;
|
|
5
|
+
submitButtonText?: string;
|
|
6
|
+
classNames?: HubspotFormClassNames;
|
|
7
|
+
hiddenFields?: Record<string, string>;
|
|
8
|
+
initialValues?: Record<string, string>;
|
|
9
|
+
ipAddress?: string;
|
|
10
|
+
onSuccess?: (fields: Record<string, HubspotFieldResponse>) => void;
|
|
11
|
+
}
|
|
12
|
+
export declare function HubspotDynamicForm({ portalId, formDefinition, submitButtonText, classNames: classNamesProp, hiddenFields, initialValues, ipAddress, onSuccess, }: HubspotDynamicFormProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=HubspotDynamicForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HubspotDynamicForm.d.ts","sourceRoot":"","sources":["../../../src/forms/client/HubspotDynamicForm.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAmFnG,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,qBAAqB,CAAC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,KAAK,IAAI,CAAC;CACpE;AAED,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,UAAU,EAAE,cAAc,EAC1B,YAAY,EACZ,aAAa,EACb,SAAS,EACT,SAAS,GACV,EAAE,uBAAuB,+BAwGzB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { decode } from 'html-entities';
|
|
4
|
+
import { useCallback, useEffect, useMemo } from 'react';
|
|
5
|
+
import { collectVisibleFields } from './dependentFields';
|
|
6
|
+
import { isSupportedFieldType, renderHubspotField } from './renderHubspotField';
|
|
7
|
+
import { useHubspotSubmit } from './useHubspotSubmit';
|
|
8
|
+
const DEFAULT_CLASS_NAMES = {
|
|
9
|
+
form: 'flex flex-col gap-4',
|
|
10
|
+
fieldGroup: 'flex flex-col gap-4',
|
|
11
|
+
field: 'flex flex-col gap-1',
|
|
12
|
+
label: 'font-medium',
|
|
13
|
+
description: 'text-sm opacity-80',
|
|
14
|
+
input: 'border px-3 py-2',
|
|
15
|
+
textarea: 'border px-3 py-2',
|
|
16
|
+
select: 'border px-3 py-2',
|
|
17
|
+
checkboxGroup: 'flex flex-col gap-2',
|
|
18
|
+
checkboxLabel: 'flex items-center gap-2',
|
|
19
|
+
radioGroup: 'flex flex-col gap-2',
|
|
20
|
+
radioLabel: 'flex items-center gap-2',
|
|
21
|
+
submitButton: 'border px-4 py-2 font-medium',
|
|
22
|
+
message: 'text-sm',
|
|
23
|
+
legalConsent: 'text-sm flex flex-col gap-2',
|
|
24
|
+
richText: 'text-sm',
|
|
25
|
+
};
|
|
26
|
+
function buildDefaultValues(formDefinition, hiddenFields, initialValues) {
|
|
27
|
+
const defaults = {};
|
|
28
|
+
for (const group of formDefinition.fieldGroups) {
|
|
29
|
+
for (const field of group.fields) {
|
|
30
|
+
if (field.hidden && field.defaultValues?.length) {
|
|
31
|
+
defaults[field.name] = {
|
|
32
|
+
name: field.name,
|
|
33
|
+
objectTypeId: field.objectTypeId,
|
|
34
|
+
value: field.defaultValues.length > 1 ? field.defaultValues : (field.defaultValues[0] ?? ''),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
else if (field.hidden && field.defaultValue) {
|
|
38
|
+
defaults[field.name] = {
|
|
39
|
+
name: field.name,
|
|
40
|
+
objectTypeId: field.objectTypeId,
|
|
41
|
+
value: field.defaultValue,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const [name, value] of Object.entries(hiddenFields ?? {})) {
|
|
47
|
+
defaults[name] = {
|
|
48
|
+
name,
|
|
49
|
+
objectTypeId: '0-1',
|
|
50
|
+
value,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
for (const [name, value] of Object.entries(initialValues ?? {})) {
|
|
54
|
+
defaults[name] = {
|
|
55
|
+
name,
|
|
56
|
+
objectTypeId: '0-1',
|
|
57
|
+
value,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return defaults;
|
|
61
|
+
}
|
|
62
|
+
function renderRichText(content, className) {
|
|
63
|
+
if (!content?.includes('<')) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const cleanContent = content.replace(/<p[^>]+>/g, '<p>');
|
|
67
|
+
return (_jsx("div", { className: className,
|
|
68
|
+
// biome-ignore lint/security/noDangerouslySetInnerHtml: HubSpot form rich text from API
|
|
69
|
+
dangerouslySetInnerHTML: { __html: cleanContent } }));
|
|
70
|
+
}
|
|
71
|
+
export function HubspotDynamicForm({ portalId, formDefinition, submitButtonText, classNames: classNamesProp, hiddenFields, initialValues, ipAddress, onSuccess, }) {
|
|
72
|
+
const classNames = useMemo(() => ({ ...DEFAULT_CLASS_NAMES, ...classNamesProp }), [classNamesProp]);
|
|
73
|
+
const { handleSubmit, handleInputChange, message, formData, setFormData } = useHubspotSubmit({
|
|
74
|
+
portalId,
|
|
75
|
+
formDefinition,
|
|
76
|
+
ipAddress,
|
|
77
|
+
onSuccess,
|
|
78
|
+
});
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
setFormData(buildDefaultValues(formDefinition, hiddenFields, initialValues));
|
|
81
|
+
}, [formDefinition, hiddenFields, initialValues, setFormData]);
|
|
82
|
+
const { visibleFields, dependentFieldsMap } = collectVisibleFields(formDefinition.fieldGroups, formData);
|
|
83
|
+
const renderField = useCallback((fieldName, field) => {
|
|
84
|
+
if (field.hidden || !visibleFields.has(fieldName)) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const actualField = dependentFieldsMap[fieldName] ?? field;
|
|
88
|
+
if (!isSupportedFieldType(actualField.fieldType)) {
|
|
89
|
+
return (_jsxs("p", { className: classNames.message, children: ["Unsupported field type: ", actualField.fieldType] }, fieldName));
|
|
90
|
+
}
|
|
91
|
+
return renderHubspotField({
|
|
92
|
+
field: actualField,
|
|
93
|
+
formData,
|
|
94
|
+
handleInputChange,
|
|
95
|
+
classNames,
|
|
96
|
+
});
|
|
97
|
+
}, [classNames, dependentFieldsMap, formData, handleInputChange, visibleFields]);
|
|
98
|
+
const buttonText = submitButtonText ?? formDefinition.submitButtonText;
|
|
99
|
+
return (_jsxs("form", { onSubmit: handleSubmit, className: classNames.form, "data-hsforms-manual": "true", "data-hs-do-not-collect": "true", children: [formDefinition.recaptchaEnabled && (_jsx("p", { className: classNames.message, children: "This form requires CAPTCHA in HubSpot. Configure bot protection for your deployment." })), formDefinition.fieldGroups.map((group) => (_jsxs("div", { className: classNames.fieldGroup, children: [renderRichText(group.richText, classNames.richText), group.fields.map((field) => renderField(field.name, field))] }, `${group.groupType}-${group.richText ?? group.fields.map((f) => f.name).join('-')}`))), formDefinition.legalConsentOptions && (_jsxs("div", { className: classNames.legalConsent, children: [formDefinition.legalConsentOptions.privacyText && (_jsx("p", { children: decode(formDefinition.legalConsentOptions.privacyText) })), formDefinition.legalConsentOptions.consentToProcessCheckboxLabel && (_jsxs("label", { className: classNames.checkboxLabel, children: [_jsx("input", { type: "checkbox", required: true, name: "consentToProcess" }), _jsx("span", { children: decode(formDefinition.legalConsentOptions.consentToProcessCheckboxLabel) })] })), formDefinition.legalConsentOptions.communicationsCheckboxes?.map((checkbox) => (_jsxs("label", { className: classNames.checkboxLabel, children: [_jsx("input", { type: "checkbox", required: checkbox.required, name: `communication-${checkbox.subscriptionTypeId ?? checkbox.label}` }), _jsx("span", { children: decode(checkbox.label) })] }, checkbox.label)))] })), _jsx("button", { type: "submit", className: classNames.submitButton, children: decode(buttonText) }), message && _jsx("p", { className: classNames.message, children: message })] }));
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=HubspotDynamicForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HubspotDynamicForm.js","sourceRoot":"","sources":["../../../src/forms/client/HubspotDynamicForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HubspotDependentCondition, HubspotFormField } from '../types';
|
|
2
|
+
export declare function checkDependentCondition(condition: HubspotDependentCondition, fieldValue: string | string[] | undefined): boolean;
|
|
3
|
+
export declare function collectVisibleFields(fieldGroups: {
|
|
4
|
+
fields: HubspotFormField[];
|
|
5
|
+
}[], formData: Record<string, {
|
|
6
|
+
value: string | string[];
|
|
7
|
+
}>): {
|
|
8
|
+
visibleFields: Set<string>;
|
|
9
|
+
dependentFieldsMap: Record<string, HubspotFormField>;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=dependentFields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependentFields.d.ts","sourceRoot":"","sources":["../../../src/forms/client/dependentFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5E,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,yBAAyB,EACpC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GACxC,OAAO,CAmBT;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE;IAAE,MAAM,EAAE,gBAAgB,EAAE,CAAA;CAAE,EAAE,EAC7C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC,GACrD;IACD,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CACtD,CAqBA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function checkDependentCondition(condition, fieldValue) {
|
|
2
|
+
if (!condition.values.length || fieldValue === undefined) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
switch (condition.operator) {
|
|
6
|
+
case 'set_any':
|
|
7
|
+
if (Array.isArray(fieldValue)) {
|
|
8
|
+
return fieldValue.some((v) => condition.values.includes(v));
|
|
9
|
+
}
|
|
10
|
+
return condition.values.includes(fieldValue);
|
|
11
|
+
case 'set_not_any':
|
|
12
|
+
if (Array.isArray(fieldValue)) {
|
|
13
|
+
return !fieldValue.some((v) => condition.values.includes(v));
|
|
14
|
+
}
|
|
15
|
+
return Boolean(fieldValue) && !condition.values.includes(fieldValue);
|
|
16
|
+
default:
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function collectVisibleFields(fieldGroups, formData) {
|
|
21
|
+
const visibleFields = new Set();
|
|
22
|
+
const dependentFieldsMap = {};
|
|
23
|
+
for (const group of fieldGroups) {
|
|
24
|
+
for (const field of group.fields) {
|
|
25
|
+
if (!field.hidden) {
|
|
26
|
+
visibleFields.add(field.name);
|
|
27
|
+
}
|
|
28
|
+
for (const dependent of field.dependentFields ?? []) {
|
|
29
|
+
dependentFieldsMap[dependent.dependentField.name] = dependent.dependentField;
|
|
30
|
+
const fieldValue = formData[field.name]?.value;
|
|
31
|
+
if (checkDependentCondition(dependent.dependentCondition, fieldValue)) {
|
|
32
|
+
visibleFields.add(dependent.dependentField.name);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { visibleFields, dependentFieldsMap };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=dependentFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependentFields.js","sourceRoot":"","sources":["../../../src/forms/client/dependentFields.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,uBAAuB,CACrC,SAAoC,EACpC,UAAyC;IAEzC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,QAAQ,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC3B,KAAK,SAAS;YACZ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/C,KAAK,aAAa;YAChB,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACvE;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,WAA6C,EAC7C,QAAsD;IAKtD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;IACxC,MAAM,kBAAkB,GAAqC,EAAE,CAAC;IAEhE,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBAClB,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;YAED,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,eAAe,IAAI,EAAE,EAAE,CAAC;gBACpD,kBAAkB,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,cAAc,CAAC;gBAC7E,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;gBAC/C,IAAI,uBAAuB,CAAC,SAAS,CAAC,kBAAkB,EAAE,UAAU,CAAC,EAAE,CAAC;oBACtE,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getCookieValue.d.ts","sourceRoot":"","sources":["../../../src/forms/client/getCookieValue.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM/D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function getCookieValue(name) {
|
|
2
|
+
if (typeof document === 'undefined') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
|
|
6
|
+
return match?.[1] ? decodeURIComponent(match[1]) : undefined;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=getCookieValue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getCookieValue.js","sourceRoot":"","sources":["../../../src/forms/client/getCookieValue.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC,CAAC;IAC3E,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HubspotFieldResponse, HubspotFormClassNames, HubspotFormField } from '../types';
|
|
2
|
+
export declare function isSupportedFieldType(fieldType: string): boolean;
|
|
3
|
+
interface RenderFieldContext {
|
|
4
|
+
field: HubspotFormField;
|
|
5
|
+
formData: Record<string, HubspotFieldResponse>;
|
|
6
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => void;
|
|
7
|
+
classNames: HubspotFormClassNames;
|
|
8
|
+
}
|
|
9
|
+
export declare function renderHubspotField({ field, formData, handleInputChange, classNames, }: RenderFieldContext): React.ReactNode;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=renderHubspotField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderHubspotField.d.ts","sourceRoot":"","sources":["../../../src/forms/client/renderHubspotField.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAgB9F,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC/C,iBAAiB,EAAE,CACjB,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,GAAG,iBAAiB,GAAG,mBAAmB,CAAC,KAC7E,IAAI,CAAC;IACV,UAAU,EAAE,qBAAqB,CAAC;CACnC;AAED,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,iBAAiB,EACjB,UAAU,GACX,EAAE,kBAAkB,GAAG,KAAK,CAAC,SAAS,CA0KtC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { decode } from 'html-entities';
|
|
3
|
+
const SUPPORTED_FIELD_TYPES = new Set([
|
|
4
|
+
'email',
|
|
5
|
+
'phone',
|
|
6
|
+
'mobile_phone',
|
|
7
|
+
'single_line_text',
|
|
8
|
+
'multi_line_text',
|
|
9
|
+
'number',
|
|
10
|
+
'dropdown',
|
|
11
|
+
'radio',
|
|
12
|
+
'multiple_checkboxes',
|
|
13
|
+
'single_checkbox',
|
|
14
|
+
'datepicker',
|
|
15
|
+
]);
|
|
16
|
+
export function isSupportedFieldType(fieldType) {
|
|
17
|
+
return SUPPORTED_FIELD_TYPES.has(fieldType);
|
|
18
|
+
}
|
|
19
|
+
export function renderHubspotField({ field, formData, handleInputChange, classNames, }) {
|
|
20
|
+
const fieldName = field.name;
|
|
21
|
+
const value = formData[fieldName]?.value ?? '';
|
|
22
|
+
const commonProps = {
|
|
23
|
+
id: fieldName,
|
|
24
|
+
name: fieldName,
|
|
25
|
+
value: typeof value === 'string' ? value : '',
|
|
26
|
+
'data-object-type-id': field.objectTypeId,
|
|
27
|
+
onChange: handleInputChange,
|
|
28
|
+
required: field.required,
|
|
29
|
+
className: classNames.input,
|
|
30
|
+
};
|
|
31
|
+
const label = (_jsxs("label", { htmlFor: fieldName, className: classNames.label, children: [decode(field.label), field.required && _jsx("span", { "aria-hidden": "true", children: " *" })] }));
|
|
32
|
+
const description = field.description ? (_jsx("p", { className: classNames.description, children: decode(field.description) })) : null;
|
|
33
|
+
switch (field.fieldType) {
|
|
34
|
+
case 'radio':
|
|
35
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("div", { className: classNames.radioGroup, role: "radiogroup", "aria-labelledby": fieldName, children: field.options?.map((option) => (_jsxs("label", { className: classNames.radioLabel, children: [_jsx("input", { type: "radio", name: fieldName, value: option.value, checked: formData[fieldName]?.value === option.value, onChange: handleInputChange, "data-object-type-id": field.objectTypeId, required: field.required }), _jsx("span", { children: decode(option.label) })] }, option.value))) })] }, fieldName));
|
|
36
|
+
case 'multiple_checkboxes':
|
|
37
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("div", { className: classNames.checkboxGroup, children: field.options?.map((option) => {
|
|
38
|
+
const current = formData[fieldName]?.value;
|
|
39
|
+
const checked = Array.isArray(current) && current.includes(option.value);
|
|
40
|
+
return (_jsxs("label", { className: classNames.checkboxLabel, children: [_jsx("input", { type: "checkbox", name: fieldName, value: option.value, checked: checked, onChange: handleInputChange, "data-object-type-id": field.objectTypeId, "data-checkbox-mode": "multiple" }), _jsx("span", { children: decode(option.label) })] }, option.value));
|
|
41
|
+
}) })] }, fieldName));
|
|
42
|
+
case 'single_checkbox':
|
|
43
|
+
return (_jsxs("div", { className: classNames.field, children: [_jsxs("label", { className: classNames.checkboxLabel, children: [_jsx("input", { type: "checkbox", name: fieldName, checked: formData[fieldName]?.value === 'true', onChange: handleInputChange, "data-object-type-id": field.objectTypeId, "data-checkbox-mode": "single", required: field.required }), _jsxs("span", { children: [decode(field.label), field.required && _jsx("span", { "aria-hidden": "true", children: " *" })] })] }), description] }, fieldName));
|
|
44
|
+
case 'multi_line_text':
|
|
45
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("textarea", { ...commonProps, rows: 4, className: classNames.textarea })] }, fieldName));
|
|
46
|
+
case 'dropdown':
|
|
47
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsxs("select", { ...commonProps, className: classNames.select, children: [_jsx("option", { value: "", children: decode(field.label) }), field.options?.map((option) => (_jsx("option", { value: option.value, children: decode(option.label) }, option.value)))] })] }, fieldName));
|
|
48
|
+
case 'email':
|
|
49
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("input", { ...commonProps, type: "email", autoComplete: "email" })] }, fieldName));
|
|
50
|
+
case 'phone':
|
|
51
|
+
case 'mobile_phone':
|
|
52
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("input", { ...commonProps, type: "tel", autoComplete: "tel" })] }, fieldName));
|
|
53
|
+
case 'number':
|
|
54
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("input", { ...commonProps, type: "number" })] }, fieldName));
|
|
55
|
+
case 'datepicker':
|
|
56
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("input", { ...commonProps, type: "date" })] }, fieldName));
|
|
57
|
+
default:
|
|
58
|
+
return (_jsxs("div", { className: classNames.field, children: [label, description, _jsx("input", { ...commonProps, type: "text" })] }, fieldName));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=renderHubspotField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderHubspotField.js","sourceRoot":"","sources":["../../../src/forms/client/renderHubspotField.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,OAAO;IACP,OAAO;IACP,cAAc;IACd,kBAAkB;IAClB,iBAAiB;IACjB,QAAQ;IACR,UAAU;IACV,OAAO;IACP,qBAAqB;IACrB,iBAAiB;IACjB,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,OAAO,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC;AAWD,MAAM,UAAU,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,iBAAiB,EACjB,UAAU,GACS;IACnB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;IAC/C,MAAM,WAAW,GAAG;QAClB,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QAC7C,qBAAqB,EAAE,KAAK,CAAC,YAAY;QACzC,QAAQ,EAAE,iBAAiB;QAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,UAAU,CAAC,KAAK;KAC5B,CAAC;IAEF,MAAM,KAAK,GAAG,CACZ,iBAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,KAAK,aACnD,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EACnB,KAAK,CAAC,QAAQ,IAAI,8BAAkB,MAAM,mBAAU,IAC/C,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CACtC,YAAG,SAAS,EAAE,UAAU,CAAC,WAAW,YAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAK,CACtE,CAAC,CAAC,CAAC,IAAI,CAAC;IAET,QAAQ,KAAK,CAAC,SAAS,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,cAAK,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,IAAI,EAAC,YAAY,qBAAkB,SAAS,YAChF,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC9B,iBAA0B,SAAS,EAAE,UAAU,CAAC,UAAU,aACxD,gBACE,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,MAAM,CAAC,KAAK,EACpD,QAAQ,EAAE,iBAAiB,yBACN,KAAK,CAAC,YAAY,EACvC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,EACF,yBAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAQ,KAVzB,MAAM,CAAC,KAAK,CAWhB,CACT,CAAC,GACE,KAlBE,SAAS,CAmBb,CACP,CAAC;QAEJ,KAAK,qBAAqB;YACxB,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,cAAK,SAAS,EAAE,UAAU,CAAC,aAAa,YACrC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;4BAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;4BAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;4BACzE,OAAO,CACL,iBAA0B,SAAS,EAAE,UAAU,CAAC,aAAa,aAC3D,gBACE,IAAI,EAAC,UAAU,EACf,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,iBAAiB,yBACN,KAAK,CAAC,YAAY,wBACpB,UAAU,GAC7B,EACF,yBAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAQ,KAVzB,MAAM,CAAC,KAAK,CAWhB,CACT,CAAC;wBACJ,CAAC,CAAC,GACE,KAtBE,SAAS,CAuBb,CACP,CAAC;QAEJ,KAAK,iBAAiB;YACpB,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC9C,iBAAO,SAAS,EAAE,UAAU,CAAC,aAAa,aACxC,gBACE,IAAI,EAAC,UAAU,EACf,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,MAAM,EAC9C,QAAQ,EAAE,iBAAiB,yBACN,KAAK,CAAC,YAAY,wBACpB,QAAQ,EAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ,GACxB,EACF,2BACG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EACnB,KAAK,CAAC,QAAQ,IAAI,8BAAkB,MAAM,mBAAU,IAChD,IACD,EACP,WAAW,KAhBJ,SAAS,CAiBb,CACP,CAAC;QAEJ,KAAK,iBAAiB;YACpB,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,sBAAc,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,QAAQ,GAAI,KAH9D,SAAS,CAIb,CACP,CAAC;QAEJ,KAAK,UAAU;YACb,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,qBAAY,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,aACnD,iBAAQ,KAAK,EAAC,EAAE,YAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAU,EAC9C,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC9B,iBAA2B,KAAK,EAAE,MAAM,CAAC,KAAK,YAC3C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IADV,MAAM,CAAC,KAAK,CAEhB,CACV,CAAC,IACK,KAVD,SAAS,CAWb,CACP,CAAC;QAEJ,KAAK,OAAO;YACV,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,mBAAW,WAAW,EAAE,IAAI,EAAC,OAAO,EAAC,YAAY,EAAC,OAAO,GAAG,KAHpD,SAAS,CAIb,CACP,CAAC;QAEJ,KAAK,OAAO,CAAC;QACb,KAAK,cAAc;YACjB,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,mBAAW,WAAW,EAAE,IAAI,EAAC,KAAK,EAAC,YAAY,EAAC,KAAK,GAAG,KAHhD,SAAS,CAIb,CACP,CAAC;QAEJ,KAAK,QAAQ;YACX,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,mBAAW,WAAW,EAAE,IAAI,EAAC,QAAQ,GAAG,KAHhC,SAAS,CAIb,CACP,CAAC;QAEJ,KAAK,YAAY;YACf,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,mBAAW,WAAW,EAAE,IAAI,EAAC,MAAM,GAAG,KAH9B,SAAS,CAIb,CACP,CAAC;QAEJ;YACE,OAAO,CACL,eAAqB,SAAS,EAAE,UAAU,CAAC,KAAK,aAC7C,KAAK,EACL,WAAW,EACZ,mBAAW,WAAW,EAAE,IAAI,EAAC,MAAM,GAAG,KAH9B,SAAS,CAIb,CACP,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HubspotFieldResponse, HubspotFormDefinition } from '../types';
|
|
2
|
+
export interface UseHubspotSubmitOptions {
|
|
3
|
+
portalId: string;
|
|
4
|
+
formDefinition: HubspotFormDefinition;
|
|
5
|
+
ipAddress?: string;
|
|
6
|
+
onSuccess?: (fields: Record<string, HubspotFieldResponse>) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useHubspotSubmit({ portalId, formDefinition, ipAddress, onSuccess, }: UseHubspotSubmitOptions): {
|
|
9
|
+
handleSubmit: (e: React.FormEvent) => void;
|
|
10
|
+
handleInputChange: (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => void;
|
|
11
|
+
message: string | null;
|
|
12
|
+
formData: Record<string, HubspotFieldResponse>;
|
|
13
|
+
setFormData: import("react").Dispatch<import("react").SetStateAction<Record<string, HubspotFieldResponse>>>;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useHubspotSubmit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHubspotSubmit.d.ts","sourceRoot":"","sources":["../../../src/forms/client/useHubspotSubmit.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAG5E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,qBAAqB,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,KAAK,IAAI,CAAC;CACpE;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,cAAc,EACd,SAAS,EACT,SAAS,GACV,EAAE,uBAAuB;sBAkDlB,KAAK,CAAC,SAAS;2BA3ChB,KAAK,CAAC,WAAW,CAAC,gBAAgB,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;;;;EA+FnF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useRouter } from 'next/navigation';
|
|
3
|
+
import { useCallback, useRef, useState } from 'react';
|
|
4
|
+
import { submitHubspotForm } from '../server/submitForm';
|
|
5
|
+
import { getCookieValue } from './getCookieValue';
|
|
6
|
+
export function useHubspotSubmit({ portalId, formDefinition, ipAddress, onSuccess, }) {
|
|
7
|
+
const router = useRouter();
|
|
8
|
+
const [formData, setFormData] = useState({});
|
|
9
|
+
const formStartTimeRef = useRef(0);
|
|
10
|
+
const [message, setMessage] = useState(null);
|
|
11
|
+
const handleInputChange = (e) => {
|
|
12
|
+
if (formStartTimeRef.current === 0) {
|
|
13
|
+
formStartTimeRef.current = Date.now();
|
|
14
|
+
}
|
|
15
|
+
const { name, value, type } = e.target;
|
|
16
|
+
const objectTypeId = e.target.getAttribute('data-object-type-id') || '';
|
|
17
|
+
if (type === 'checkbox') {
|
|
18
|
+
const checked = e.target.checked;
|
|
19
|
+
const checkboxMode = e.target.getAttribute('data-checkbox-mode');
|
|
20
|
+
if (checkboxMode === 'single') {
|
|
21
|
+
setFormData((prev) => {
|
|
22
|
+
if (!checked) {
|
|
23
|
+
const { [name]: _removed, ...rest } = prev;
|
|
24
|
+
return rest;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
...prev,
|
|
28
|
+
[name]: { name, value: 'true', objectTypeId },
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
setFormData((prev) => {
|
|
34
|
+
const currentValue = prev[name]?.value || [];
|
|
35
|
+
const currentArray = Array.isArray(currentValue) ? currentValue : [];
|
|
36
|
+
const newValue = checked
|
|
37
|
+
? [...currentArray, value]
|
|
38
|
+
: currentArray.filter((v) => v !== value);
|
|
39
|
+
return { ...prev, [name]: { name, value: newValue, objectTypeId } };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
setFormData((prev) => ({
|
|
45
|
+
...prev,
|
|
46
|
+
[name]: { name, value, objectTypeId },
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const handleSubmit = useCallback((e) => {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
const transformedFields = Object.values(formData).map((field) => ({
|
|
53
|
+
...field,
|
|
54
|
+
value: Array.isArray(field.value) ? field.value.join(';') : field.value,
|
|
55
|
+
}));
|
|
56
|
+
submitHubspotForm(portalId, formDefinition.id, transformedFields, {
|
|
57
|
+
hutk: getCookieValue('hubspotutk'),
|
|
58
|
+
ipAddress,
|
|
59
|
+
pageUri: window.location.href,
|
|
60
|
+
pageName: document.title,
|
|
61
|
+
}, formStartTimeRef.current, Date.now())
|
|
62
|
+
.then((result) => {
|
|
63
|
+
if (result.failure) {
|
|
64
|
+
setMessage('Form submission failed. Please try again later.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (onSuccess) {
|
|
68
|
+
onSuccess(formData);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (result.data?.inlineMessage) {
|
|
72
|
+
setMessage(result.data.inlineMessage);
|
|
73
|
+
}
|
|
74
|
+
else if (result.data?.redirectUri) {
|
|
75
|
+
router.push(result.data.redirectUri);
|
|
76
|
+
}
|
|
77
|
+
else if (formDefinition.postSubmitAction.type === 'redirect_url') {
|
|
78
|
+
router.push(formDefinition.postSubmitAction.value);
|
|
79
|
+
}
|
|
80
|
+
else if (formDefinition.postSubmitAction.type === 'thank_you') {
|
|
81
|
+
setMessage(formDefinition.postSubmitAction.value);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
setMessage('Form submitted successfully');
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
.catch(() => {
|
|
88
|
+
setMessage('Form submission failed. Please try again later.');
|
|
89
|
+
});
|
|
90
|
+
}, [formData, formDefinition, ipAddress, onSuccess, portalId, router]);
|
|
91
|
+
return { handleSubmit, handleInputChange, message, formData, setFormData };
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=useHubspotSubmit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHubspotSubmit.js","sourceRoot":"","sources":["../../../src/forms/client/useHubspotSubmit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import type { HubspotFormDefinition } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Fetch a single HubSpot form definition by ID (cached per form).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getHubspotFormDefinition(formId: string): Promise<HubspotFormDefinition | null>;
|
|
7
|
+
//# sourceMappingURL=getFormDefinition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFormDefinition.d.ts","sourceRoot":"","sources":["../../../src/forms/server/getFormDefinition.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAIrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAetD;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAKvC"}
|