SecurityQuestionnaire.tsx99 lines · main
1// @ts-nocheck
2import { PermissionAction } from '@supabase/shared-types/out/constants'
3import { Download } from 'lucide-react'
4import Link from 'next/link'
5import { toast } from 'sonner'
6import { Button } from 'ui'
7import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
8
9import {
10 ScaffoldSection,
11 ScaffoldSectionContent,
12 ScaffoldSectionDetail,
13} from '@/components/layouts/Scaffold'
14import NoPermission from '@/components/ui/NoPermission'
15import { getDocument } from '@/data/documents/document-query'
16import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
17import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
18import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
19import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
20
21export const SecurityQuestionnaire = () => {
22 const { data: organization } = useSelectedOrganizationQuery()
23 const slug = organization?.slug
24
25 const { mutate: sendEvent } = useSendEventMutation()
26 const { can: canReadSubscriptions, isLoading: isLoadingPermissions } = useAsyncCheckPermissions(
27 PermissionAction.BILLING_READ,
28 'stripe.subscriptions'
29 )
30 const { hasAccess: hasAccessToQuestionnaire, isLoading: isLoadingEntitlement } =
31 useCheckEntitlements('security.questionnaire')
32
33 const fetchQuestionnaire = async (orgSlug: string) => {
34 try {
35 const questionnaireLink = await getDocument({
36 orgSlug,
37 docType: 'standard-security-questionnaire',
38 })
39 if (questionnaireLink?.fileUrl) window.open(questionnaireLink.fileUrl, '_blank')
40 } catch (error: unknown) {
41 const message = error instanceof Error ? error.message : 'Unknown error occurred'
42 toast.error(`Failed to download Security Questionnaire: ${message}`)
43 }
44 }
45
46 const handleDownloadClick = () => {
47 if (!slug) return
48
49 sendEvent({
50 action: 'document_view_button_clicked',
51 properties: { documentName: 'Standard Security Questionnaire' },
52 groups: { organization: slug },
53 })
54 fetchQuestionnaire(slug)
55 }
56
57 return (
58 <ScaffoldSection className="py-12">
59 <ScaffoldSectionDetail>
60 <h4 className="mb-5">Standard Security Questionnaire</h4>
61 <div className="space-y-2 text-sm text-foreground-light [&_p]:m-0">
62 <p>
63 Organizations on Team Plan or above have access to our standard security questionnaire.
64 </p>
65 </div>
66 </ScaffoldSectionDetail>
67 <ScaffoldSectionContent>
68 {isLoadingPermissions || isLoadingEntitlement ? (
69 <div className="@lg:flex items-center justify-center h-full">
70 <ShimmeringLoader className="w-24" />
71 </div>
72 ) : !canReadSubscriptions ? (
73 <NoPermission resourceText="access our security questionnaire" />
74 ) : !hasAccessToQuestionnaire ? (
75 <div className="@lg:flex items-center justify-center h-full">
76 <Button asChild type="default">
77 <Link
78 href={`/org/${slug}/billing?panel=subscriptionPlan&source=securityQuestionnaire`}
79 >
80 Upgrade to Team
81 </Link>
82 </Button>
83 </div>
84 ) : (
85 <div className="@lg:flex items-center justify-center h-full">
86 <Button
87 type="default"
88 icon={<Download />}
89 onClick={handleDownloadClick}
90 disabled={!slug}
91 >
92 Download Questionnaire
93 </Button>
94 </div>
95 )}
96 </ScaffoldSectionContent>
97 </ScaffoldSection>
98 )
99}