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