DPA.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { useState } from 'react'
  2. import { toast } from 'sonner'
  3. import { Button } from 'ui'
  4. import {
  5. ScaffoldSection,
  6. ScaffoldSectionContent,
  7. ScaffoldSectionDetail,
  8. } from '@/components/layouts/Scaffold'
  9. import { InlineLink } from '@/components/ui/InlineLink'
  10. import { TextConfirmModal } from '@/components/ui/TextConfirmModalWrapper'
  11. import { useDpaRequestMutation } from '@/data/documents/dpa-request-mutation'
  12. import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
  13. import { useProfile } from '@/lib/profile'
  14. import { useTrack } from '@/lib/telemetry/track'
  15. export const DPA = () => {
  16. const { profile } = useProfile()
  17. const { data: organization } = useSelectedOrganizationQuery()
  18. const slug = organization?.slug
  19. const [isOpen, setIsOpen] = useState(false)
  20. const track = useTrack()
  21. const { mutate: requestDpa, isPending: isRequesting } = useDpaRequestMutation({
  22. onSuccess: () => {
  23. toast.success('DPA request sent successfully')
  24. setIsOpen(false)
  25. },
  26. })
  27. const onConfirmRequest = async () => {
  28. if (!slug) return toast.error('Organization not found.')
  29. if (!profile?.primary_email) return toast.error('Profile email not found.')
  30. requestDpa({ recipient_email: profile?.primary_email, slug: slug })
  31. }
  32. return (
  33. <>
  34. <ScaffoldSection className="py-12">
  35. <ScaffoldSectionDetail>
  36. <h4 className="mb-5">Data Processing Addendum (DPA)</h4>
  37. <div className="space-y-2 text-sm text-foreground-light [&_p]:m-0">
  38. <p>
  39. All organizations can sign our Data Processing Addendum ("DPA") as part of their GDPR
  40. compliance.
  41. </p>
  42. <p>
  43. You can review a static PDF version of our latest DPA document{' '}
  44. <InlineLink
  45. href="https://supabase.com/downloads/docs/Supabase+DPA+260317.pdf"
  46. onClick={() => track('dpa_pdf_opened', { source: 'studio' })}
  47. >
  48. here
  49. </InlineLink>
  50. .
  51. </p>
  52. </div>
  53. </ScaffoldSectionDetail>
  54. <ScaffoldSectionContent>
  55. <div className="@lg:flex items-center justify-center h-full">
  56. <Button
  57. onClick={() => {
  58. setIsOpen(true)
  59. track('dpa_request_button_clicked')
  60. }}
  61. type="default"
  62. >
  63. Request DPA
  64. </Button>
  65. </div>
  66. </ScaffoldSectionContent>
  67. </ScaffoldSection>
  68. <TextConfirmModal
  69. visible={isOpen}
  70. title="Request executable DPA to sign"
  71. loading={isRequesting}
  72. confirmPlaceholder="Enter your email address"
  73. confirmString={profile?.primary_email ?? ''}
  74. confirmLabel="Send DPA request"
  75. errorMessage="Email must match your account email."
  76. onCancel={() => setIsOpen(false)}
  77. onConfirm={() => onConfirmRequest()}
  78. >
  79. <div className="space-y-2 text-sm">
  80. <p>
  81. To make the DPA legally binding, you need to sign and complete the details through a
  82. PandaDoc document that we prepare.
  83. </p>
  84. <p>
  85. Please enter your email address to request an executable version of the DPA. You will
  86. receive a document link via PandaDoc in the next 24 hours.
  87. </p>
  88. <p>
  89. Once signed, the DPA will be considered executed and you'll be notified of any future
  90. updates via this email.
  91. </p>
  92. </div>
  93. </TextConfirmModal>
  94. </>
  95. )
  96. }