d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
156 lines
4.7 KiB
TypeScript
156 lines
4.7 KiB
TypeScript
'use client'
|
|
|
|
import { useCallback, useState } from 'react'
|
|
import {
|
|
Chip,
|
|
ChipModal,
|
|
ChipModalBody,
|
|
ChipModalError,
|
|
ChipModalField,
|
|
ChipModalFooter,
|
|
ChipModalHeader,
|
|
} from '@sim/emcn'
|
|
import { requestJson } from '@/lib/api/client/request'
|
|
import { integrationRequestContract } from '@/lib/api/contracts/common'
|
|
|
|
type SubmitStatus = 'idle' | 'submitting' | 'success' | 'error'
|
|
|
|
export function RequestIntegrationModal() {
|
|
const [open, setOpen] = useState(false)
|
|
const [status, setStatus] = useState<SubmitStatus>('idle')
|
|
|
|
const [integrationName, setIntegrationName] = useState('')
|
|
const [email, setEmail] = useState('')
|
|
const [useCase, setUseCase] = useState('')
|
|
|
|
const resetForm = useCallback(() => {
|
|
setIntegrationName('')
|
|
setEmail('')
|
|
setUseCase('')
|
|
setStatus('idle')
|
|
}, [])
|
|
|
|
const handleOpenChange = useCallback(
|
|
(nextOpen: boolean) => {
|
|
setOpen(nextOpen)
|
|
if (!nextOpen) resetForm()
|
|
},
|
|
[resetForm]
|
|
)
|
|
|
|
const handleSubmit = useCallback(async () => {
|
|
if (!integrationName.trim() || !email.trim()) return
|
|
|
|
setStatus('submitting')
|
|
|
|
try {
|
|
await requestJson(integrationRequestContract, {
|
|
body: {
|
|
integrationName: integrationName.trim(),
|
|
email: email.trim(),
|
|
useCase: useCase.trim() || undefined,
|
|
},
|
|
})
|
|
|
|
setStatus('success')
|
|
setTimeout(() => setOpen(false), 1500)
|
|
} catch {
|
|
setStatus('error')
|
|
}
|
|
}, [integrationName, email, useCase])
|
|
|
|
const canSubmit = integrationName.trim() && email.trim() && status === 'idle'
|
|
|
|
return (
|
|
<>
|
|
<Chip className='border border-[var(--border-1)]' onClick={() => setOpen(true)}>
|
|
Request an integration
|
|
</Chip>
|
|
|
|
<ChipModal open={open} onOpenChange={handleOpenChange} srTitle='Request an Integration'>
|
|
<ChipModalHeader onClose={() => handleOpenChange(false)}>
|
|
Request an Integration
|
|
</ChipModalHeader>
|
|
|
|
<ChipModalBody>
|
|
{status === 'success' ? (
|
|
<div className='flex flex-col items-center gap-3 py-6 text-center'>
|
|
<div className='flex size-10 items-center justify-center rounded-full bg-[var(--brand-accent)]/10'>
|
|
<svg
|
|
className='size-5 text-[var(--brand-accent)]'
|
|
viewBox='0 0 24 24'
|
|
fill='none'
|
|
stroke='currentColor'
|
|
strokeWidth={2}
|
|
strokeLinecap='round'
|
|
strokeLinejoin='round'
|
|
>
|
|
<polyline points='20 6 9 17 4 12' />
|
|
</svg>
|
|
</div>
|
|
<p className='text-[14px] text-[var(--text-primary)]'>
|
|
Request submitted. We'll follow up at <span>{email}</span>.
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<>
|
|
<ChipModalField
|
|
type='input'
|
|
title='Integration name'
|
|
value={integrationName}
|
|
onChange={(value) => setIntegrationName(value)}
|
|
placeholder='e.g. Stripe, HubSpot, Snowflake'
|
|
maxLength={200}
|
|
autoComplete='off'
|
|
required
|
|
/>
|
|
<ChipModalField
|
|
type='email'
|
|
title='Your email'
|
|
value={email}
|
|
onChange={(value) => setEmail(value)}
|
|
placeholder='you@company.com'
|
|
autoComplete='email'
|
|
required
|
|
/>
|
|
<ChipModalField
|
|
type='textarea'
|
|
title={
|
|
<>
|
|
Use case <span className='text-[var(--text-subtle)]'>(optional)</span>
|
|
</>
|
|
}
|
|
value={useCase}
|
|
onChange={(value) => setUseCase(value)}
|
|
placeholder='What would you automate with this integration?'
|
|
rows={3}
|
|
maxLength={2000}
|
|
/>
|
|
{status === 'error' && (
|
|
<ChipModalError>Something went wrong. Please try again.</ChipModalError>
|
|
)}
|
|
</>
|
|
)}
|
|
</ChipModalBody>
|
|
|
|
{status === 'success' ? (
|
|
<ChipModalFooter
|
|
onCancel={() => handleOpenChange(false)}
|
|
primaryAction={{ label: 'Done', onClick: () => handleOpenChange(false) }}
|
|
/>
|
|
) : (
|
|
<ChipModalFooter
|
|
onCancel={() => setOpen(false)}
|
|
cancelDisabled={status === 'submitting'}
|
|
primaryAction={{
|
|
label: status === 'submitting' ? 'Submitting...' : 'Submit request',
|
|
onClick: handleSubmit,
|
|
disabled: !canSubmit && status !== 'error',
|
|
}}
|
|
/>
|
|
)}
|
|
</ChipModal>
|
|
</>
|
|
)
|
|
}
|