@@ -64,4 +84,4 @@ const LinterPageFooter = ({
)
}
-export default LinterPageFooter
+export { LinterPageFooter }
diff --git a/apps/studio/pages/project/[ref]/advisors/performance.tsx b/apps/studio/pages/project/[ref]/advisors/performance.tsx
index ff4321175aa58..3b0e83b7a2320 100644
--- a/apps/studio/pages/project/[ref]/advisors/performance.tsx
+++ b/apps/studio/pages/project/[ref]/advisors/performance.tsx
@@ -6,7 +6,7 @@ import { LINTER_LEVELS } from 'components/interfaces/Linter/Linter.constants'
import { lintInfoMap } from 'components/interfaces/Linter/Linter.utils'
import LinterDataGrid from 'components/interfaces/Linter/LinterDataGrid'
import LinterFilters from 'components/interfaces/Linter/LinterFilters'
-import LinterPageFooter from 'components/interfaces/Linter/LinterPageFooter'
+import { LinterPageFooter } from 'components/interfaces/Linter/LinterPageFooter'
import AdvisorsLayout from 'components/layouts/AdvisorsLayout/AdvisorsLayout'
import DefaultLayout from 'components/layouts/DefaultLayout'
import { FormHeader } from 'components/ui/Forms/FormHeader'
diff --git a/apps/studio/pages/project/[ref]/advisors/security.tsx b/apps/studio/pages/project/[ref]/advisors/security.tsx
index cd324bed41ffb..aaa28234f92f2 100644
--- a/apps/studio/pages/project/[ref]/advisors/security.tsx
+++ b/apps/studio/pages/project/[ref]/advisors/security.tsx
@@ -6,7 +6,7 @@ import { LINTER_LEVELS } from 'components/interfaces/Linter/Linter.constants'
import { lintInfoMap } from 'components/interfaces/Linter/Linter.utils'
import LinterDataGrid from 'components/interfaces/Linter/LinterDataGrid'
import LinterFilters from 'components/interfaces/Linter/LinterFilters'
-import LinterPageFooter from 'components/interfaces/Linter/LinterPageFooter'
+import { LinterPageFooter } from 'components/interfaces/Linter/LinterPageFooter'
import AdvisorsLayout from 'components/layouts/AdvisorsLayout/AdvisorsLayout'
import DefaultLayout from 'components/layouts/DefaultLayout'
import { FormHeader } from 'components/ui/Forms/FormHeader'
diff --git a/packages/common/constants/local-storage.ts b/packages/common/constants/local-storage.ts
index 3572600e27315..03d597f036654 100644
--- a/packages/common/constants/local-storage.ts
+++ b/packages/common/constants/local-storage.ts
@@ -39,6 +39,7 @@ export const LOCAL_STORAGE_KEYS = {
CLS_DIFF_WARNING: 'cls-diff-warning-dismissed',
CLS_SELECT_STAR_WARNING: 'cls-select-star-warning-dismissed',
QUERY_PERF_SHOW_BOTTOM_SECTION: 'supabase-query-perf-show-bottom-section',
+ LINTER_SHOW_FOOTER: 'supabase-linter-show-footer',
// Key to track account deletion requests
ACCOUNT_DELETION_REQUEST: 'supabase-account-deletion-request',
// Used for storing a user id when sending reports to Sentry. The id is hashed for anonymity.
@@ -110,6 +111,7 @@ const LOCAL_STORAGE_KEYS_ALLOWLIST = [
LOCAL_STORAGE_KEYS.AI_ASSISTANT_MCP_OPT_IN,
LOCAL_STORAGE_KEYS.UI_PREVIEW_REALTIME_SETTINGS,
LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
+ LOCAL_STORAGE_KEYS.LINTER_SHOW_FOOTER,
]
export function clearLocalStorage() {
diff --git a/packages/ui-patterns/src/Banners/LW15Banner.tsx b/packages/ui-patterns/src/Banners/LW15Banner.tsx
index 84268c24c4449..8e87d463ebb33 100644
--- a/packages/ui-patterns/src/Banners/LW15Banner.tsx
+++ b/packages/ui-patterns/src/Banners/LW15Banner.tsx
@@ -53,11 +53,11 @@ export function LW15Banner() {
- {announcement.title}
+ {announcement.text}
-
{announcement.desc}
+
{announcement.launch}
diff --git a/packages/ui-patterns/src/Banners/SelectBanner.tsx b/packages/ui-patterns/src/Banners/SelectBanner.tsx
index 32afcf91928bf..b3cae094a4bd6 100644
--- a/packages/ui-patterns/src/Banners/SelectBanner.tsx
+++ b/packages/ui-patterns/src/Banners/SelectBanner.tsx
@@ -1,26 +1,84 @@
+import React from 'react'
import Link from 'next/link'
-import { Button } from 'ui/src/components/Button'
-import announcement from './data.json'
export function SelectBanner() {
+ const selectSiteUrl = 'https://select.supabase.com/'
+ const desc = ['Our first user conference', 'Oct 3 2025', 'Guillermo Rauch, Dylan Field, and more']
+ const cta = 'Save your seat'
+
+ const baseStyles = 'flex flex-col justify-center border-l border-muted py-8 '
+ const textBlockStyles =
+ baseStyles +
+ 'pr-8 text-xs font-mono uppercase leading-none tracking-wide text-white/50 [&_p]:mt-[5px]'
+
return (
-
-
-
-
-

+
+
+
+
+

+
+
+
+
-
- {announcement.desc}
- {announcement.verbose}
-
-
-
+
+
+ {cta}
+ {/* Crosshairs */}
+
+ {['top-left', 'top-right', 'bottom-left', 'bottom-right'].map((position) => (
+
+ ))}
+
+
diff --git a/packages/ui-patterns/src/Banners/data.json b/packages/ui-patterns/src/Banners/data.json
index bd3f41eb0f4ea..a7f1e2fee1432 100644
--- a/packages/ui-patterns/src/Banners/data.json
+++ b/packages/ui-patterns/src/Banners/data.json
@@ -1,8 +1,7 @@
{
- "title": "Supabase Select",
- "desc": "Our first user conference · October 3, San Francisco",
- "verbose": " · Guillermo Rauch, Dylan Field, and more",
- "link": "https://select.supabase.com/",
- "target": "_blank",
- "button": "Save your seat"
+ "text": "",
+ "launch": "",
+ "launchDate": "2025-07-17T08:00:00.000-07:00",
+ "link": "#",
+ "cta": "Learn more"
}
diff --git a/packages/ui-patterns/src/PromoToast/PromoToast.tsx b/packages/ui-patterns/src/PromoToast/PromoToast.tsx
index 6c7c49049d277..af51c5e351544 100644
--- a/packages/ui-patterns/src/PromoToast/PromoToast.tsx
+++ b/packages/ui-patterns/src/PromoToast/PromoToast.tsx
@@ -46,7 +46,7 @@ const PromoToast = () => {
poster={`${process.env.NEXT_PUBLIC_SUPABASE_URL}/storage/v1/object/public/images/launch-week/lw15/assets/lw15-galaxy.png`}
/>
-
{announcement.title}
+
{announcement.text}
diff --git a/packages/ui/src/layout/banners/Announcement.tsx b/packages/ui/src/layout/banners/Announcement.tsx
index 60dc358c34a44..aef0cde8e3ef7 100644
--- a/packages/ui/src/layout/banners/Announcement.tsx
+++ b/packages/ui/src/layout/banners/Announcement.tsx
@@ -9,8 +9,8 @@ import { X } from 'lucide-react'
export interface AnnouncementProps {
show: boolean
- title: string
- launchDate: string | null
+ text: string
+ launchDate: string
link: string
badge?: string
}
@@ -66,7 +66,7 @@ const Announcement = ({
{dismissable && !isLaunchWeekSection && (