SecurityQuestionnaire.tsx 3.5 KB

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