Skip to content

Commit 5c85341

Browse files
authored
feat: replace hubspot with studio contacts (#5345)
1 parent a888be1 commit 5c85341

File tree

5 files changed

+51
-78
lines changed

5 files changed

+51
-78
lines changed

src/@dvcorg/gatsby-theme-iterative/components/HamburgerMenu/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { ReactComponent as GithubIcon } from '@dvcorg/gatsby-theme-iterative/src
1515

1616
import * as styles from '@dvcorg/gatsby-theme-iterative/src/components/HamburgerMenu/styles.module.css'
1717
import menuData from '../../data/menu'
18-
import { cloudUrl } from '../../../../utils/externalUrls'
18+
import { studioUrl } from '../../../../utils/externalUrls'
1919
import LogoGradient from '@dvcorg/gatsby-theme-iterative/src/components/LogoGradient'
2020

2121
const docsPage = getFirstPage()
@@ -236,7 +236,7 @@ export const HamburgerMenu: React.FC<
236236
Get started
237237
</Link>
238238
<Link
239-
href={cloudUrl}
239+
href={studioUrl}
240240
className={cn(styles.linkButton)}
241241
onClick={() => handleItemClick('get-enterprise')}
242242
>

src/@dvcorg/gatsby-theme-iterative/components/LayoutHeader/Nav/index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ReactComponent as ExternalLinkIcon } from '../../../../../../static/img
77
import * as styles from './styles.module.css'
88
import PseudoButton from '@dvcorg/gatsby-theme-iterative/src/components/PseudoButton'
99
import Link from '@dvcorg/gatsby-theme-iterative/src/components/Link'
10-
import { cloudUrl } from '../../../../../utils/externalUrls'
10+
import { studioUrl } from '../../../../../utils/externalUrls'
1111

1212
const Nav: React.FC = () => (
1313
<div className={styles.wrapper}>
@@ -23,7 +23,7 @@ const Nav: React.FC = () => (
2323
</PseudoButton>
2424
<div className="text-dark hidden md:flex items-center">
2525
<div className="mx-3 select-none">|</div>
26-
<Link className="no-underline hover" href={cloudUrl}>
26+
<Link className="no-underline hover" href={studioUrl}>
2727
Get Enterprise{` `}
2828
<ExternalLinkIcon className="ml-0.5 inline-block w-4 h-4" />
2929
</Link>

src/components/Support/RequestAQuoteForm.tsx

+20-55
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import { Textarea } from '../base/textarea'
66
import Button from '../base/button'
77
import { cn } from '../../utils'
88
import { Loader2Icon } from 'lucide-react'
9-
import { getHubSpotFormUrl } from '../../utils/externalUrls'
9+
1010
import {
1111
FormField,
1212
FromErrors,
1313
checkErrors,
1414
defaultValues,
1515
emptyValues,
16+
refreshStudioCSRFToken,
1617
teamSize
1718
} from './utils'
19+
import { studioContactUsApi } from '../../utils/externalUrls'
1820

1921
const ErrorMessage = ({
2022
name,
@@ -114,68 +116,31 @@ const RequestAQuoteForm = ({
114116
}
115117

116118
try {
117-
const formId = `50ebdb54-825e-436f-9afc-6c6fa4b2d865`
118-
/**
119-
* NOTE: For Testing, simply call getHubSpotFormUrl() i.e without parameters
120-
* it defaults to test form id
121-
*/
122-
const response = await fetch(getHubSpotFormUrl({ formId }), {
119+
const csrfToken = await refreshStudioCSRFToken()
120+
const response = await fetch(studioContactUsApi, {
123121
method: `POST`,
124122
headers: {
125-
'Content-Type': `application/json`
123+
'Content-Type': `application/json`,
124+
'X-CsrfToken': csrfToken
126125
},
126+
credentials: `include`,
127+
mode: `cors`,
127128
body: JSON.stringify({
128-
fields: [
129-
{
130-
objectTypeId: `0-1`,
131-
name: `full_name`,
132-
value: values.name
133-
},
134-
{
135-
objectTypeId: `0-1`,
136-
name: `company`,
137-
value: values.company
138-
},
139-
{
140-
objectTypeId: `0-1`,
141-
name: `email`,
142-
value: values.email
143-
},
144-
{
145-
objectTypeId: `0-1`,
146-
name: `team_size`,
147-
value: values.teamSize
148-
},
149-
{
150-
objectTypeId: `0-1`,
151-
name: `area_of_interest`,
152-
value: values.areaOfInterest
153-
},
154-
{
155-
objectTypeId: `0-1`,
156-
name: `phone`,
157-
value: values.phone
158-
},
159-
{
160-
objectTypeId: `0-1`,
161-
name: `message`,
162-
value: values.message
163-
},
164-
{
165-
objectTypeId: `0-1`,
166-
name: `purpose`,
167-
value: values.purpose
168-
}
169-
],
170-
context: {
171-
pageName: `Platinum Services (Request a Quote)`,
172-
pageUri: `https://dvc.org/support`
173-
}
129+
area_of_interest: values.areaOfInterest,
130+
company: values.company,
131+
email: values.email,
132+
info: values.message,
133+
name: values.name,
134+
phone: values.phone,
135+
purpose: values.purpose,
136+
site: window.location.href,
137+
team_size: values.teamSize
174138
}),
175139
signal: newAbortController.signal
176140
})
141+
if (!response.ok) throw new Error(response.statusText)
177142
const data = await response.json()
178-
if (data.status === `error`) throw new Error(data)
143+
if (data.error) throw new Error(data.error)
179144

180145
setSubmitting(false)
181146
setValues(defaultValues)

src/components/Support/utils.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { studioRefreshCsfrApi } from '../../utils/externalUrls'
2+
13
export type FormField =
24
| 'name'
35
| 'company'
@@ -80,3 +82,24 @@ export const checkErrors = (
8082

8183
return { hasError, newErrors }
8284
}
85+
86+
function getCookie(name: string) {
87+
let cookieValue = null
88+
if (document.cookie && document.cookie !== ``) {
89+
const cookies = document.cookie.split(`;`)
90+
for (let i = 0; i < cookies.length; i++) {
91+
const cookie = cookies[i].trim()
92+
// Does this cookie string begin with the name we want?
93+
if (cookie.substring(0, name.length + 1) === name + `=`) {
94+
cookieValue = decodeURIComponent(cookie.substring(name.length + 1))
95+
break
96+
}
97+
}
98+
}
99+
return cookieValue
100+
}
101+
102+
export const refreshStudioCSRFToken = async () => {
103+
await fetch(studioRefreshCsfrApi)
104+
return getCookie(`csrftoken`) || ``
105+
}

src/utils/externalUrls.ts

+4-19
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,11 @@
22

33
export const studioUrl = 'https://studio.datachain.ai'
44

5-
// cloud.dvc.ai
6-
7-
// Temporarily it's the same as studio
8-
// TODO: change to cloud.dvc.ai
9-
10-
// export const cloudUrl = 'https://cloud.dvc.ai'
11-
export const cloudUrl = studioUrl
5+
// Studio API Urls
6+
const studioApi = `${studioUrl}/api`
7+
export const studioRefreshCsfrApi = `${studioApi}/refresh-csrf`
8+
export const studioContactUsApi = `${studioApi}/contacts`
129

1310
// Github Urls
1411
export const githubDatachainUrl = `https://github.com/iterative/datachain`
1512
export const githubDvcUrl = `https://github.com/iterative/dvc`
16-
17-
// HubSpot Forms
18-
interface IHubSpotFormUrlOptions {
19-
portalId?: string
20-
formId?: string
21-
}
22-
23-
export const getHubSpotFormUrl = ({
24-
portalId = `21087317`,
25-
formId = `e43684c2-476c-4838-adf2-d489da58ad89`
26-
}: IHubSpotFormUrlOptions = {}) =>
27-
`https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formId}`

0 commit comments

Comments
 (0)