NoticeBanner.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { LOCAL_STORAGE_KEYS } from 'common'
  2. import { useRouter } from 'next/router'
  3. import {
  4. Button,
  5. cn,
  6. Dialog,
  7. DialogClose,
  8. DialogContent,
  9. DialogDescription,
  10. DialogFooter,
  11. DialogHeader,
  12. DialogSection,
  13. DialogSectionSeparator,
  14. DialogTitle,
  15. DialogTrigger,
  16. } from 'ui'
  17. import { HeaderBanner } from '@/components/interfaces/Organization/HeaderBanner'
  18. import { InlineLink, InlineLinkClassName } from '@/components/ui/InlineLink'
  19. import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
  20. // Update this whenever the banner content below changes so old client bundles
  21. // stop displaying outdated notices after the relevant date passes.
  22. const BANNER_EXPIRES_AT = new Date('2026-07-04T00:00:00Z')
  23. /**
  24. * Used to display urgent notices that apply for all users, such as maintenance windows.
  25. */
  26. export const NoticeBanner = () => {
  27. const router = useRouter()
  28. const [bannerAcknowledged, setBannerAcknowledged, { isSuccess }] = useLocalStorageQuery(
  29. LOCAL_STORAGE_KEYS.TERMS_OF_SERVICE_UPDATE,
  30. false
  31. )
  32. if (
  33. Date.now() >= BANNER_EXPIRES_AT.getTime() ||
  34. router.pathname.includes('sign-in') ||
  35. !isSuccess ||
  36. bannerAcknowledged
  37. ) {
  38. return null
  39. }
  40. return (
  41. <HeaderBanner
  42. variant="note"
  43. title="We've updated our Terms of Service"
  44. description={<UpdatedTermsOfServiceDialog onDismiss={() => setBannerAcknowledged(true)} />}
  45. onDismiss={() => setBannerAcknowledged(true)}
  46. />
  47. )
  48. }
  49. const UpdatedTermsOfServiceDialog = ({ onDismiss }: { onDismiss: () => void }) => {
  50. return (
  51. <Dialog>
  52. <DialogTrigger className={cn(InlineLinkClassName, 'cursor-pointer')}>
  53. Learn more
  54. </DialogTrigger>
  55. <DialogContent>
  56. <DialogHeader>
  57. <DialogTitle>Terms of Service update</DialogTitle>
  58. <DialogDescription>
  59. We've updated our Terms of Service to better define the responsibilities of both you and
  60. Briven in the use of AI.
  61. </DialogDescription>
  62. </DialogHeader>
  63. <DialogSectionSeparator />
  64. <DialogSection className="text-sm flex flex-col gap-y-2">
  65. <p>
  66. We've clarified how we use AI in our customer support tooling, introduced guidelines for
  67. the responsible use of AI by our users, and updated our indemnification terms to clarify
  68. the allocation of responsibility for claims arising from AI-generated inputs and
  69. outputs.
  70. </p>
  71. <p>
  72. Additionally, we've made an explicit commitment that Briven will never use the data
  73. you submit to the Briven services to train or improve any AI without your prior
  74. written consent.
  75. </p>
  76. <p>
  77. The updated Terms (Version 2) will take effect on June 6, 2026. By continuing to use the
  78. Services after that date, you agree to the updated Terms. You can review the changes{' '}
  79. <InlineLink href="https://supabase.com/terms">here</InlineLink>.
  80. </p>
  81. <p>
  82. This notice applies to users on Briven's standard Terms of Service only. If you are on
  83. an Enterprise plan or with a separately negotiated agreement, your existing terms
  84. continue to govern your use of the Services.
  85. </p>
  86. </DialogSection>
  87. <DialogFooter>
  88. <DialogClose asChild>
  89. <Button type="default" className="opacity-100" onClick={onDismiss}>
  90. Understood
  91. </Button>
  92. </DialogClose>
  93. </DialogFooter>
  94. </DialogContent>
  95. </Dialog>
  96. )
  97. }