## Problem
The dashboard renders all timestamps in the browser's local timezone.
When debugging app issues, users often want to see logs and timestamps
in a different timezone (e.g. their app's deployment region) without
changing their OS clock.
## Fix
- New Timezone submenu in the user-avatar dropdown, sitting next to the
existing Theme picker. Search-as-you-type combobox over the full IANA
catalog plus an Auto detect option.
- Selection persists in localStorage (`supabase-ui-timezone`) and
survives `clearLocalStorage()`. No backend schema change.
- New `lib/datetime.tsx` exposes pure timezone-aware formatters
(`formatDateTime`, `formatDate`, `formatTime`, `formatFromNow`,
`toTimezone`) plus a `TimezoneProvider` and matching React hooks
(`useTimezone`, `useFormatDateTime`, ...). The pure functions take `tz`
explicitly so they're easy to unit test (17 vitest cases covering DST
transitions, multi-tz formatting, unix-micro/Date inputs, invalid-tz
fallback).
- The selected timezone propagates to every existing `<TimestampInfo>`
in Studio via a new `TimestampInfoProvider` context exported from
`ui-patterns`. No per-callsite changes needed for those ~20+ surfaces.
- The `UnifiedLogs` date column migrates off `date-fns` to the new
`useFormatDateTime` hook (the rest of the date-fns callers stay as-is,
since they're either internal range math or non-display).
- `ALL_TIMEZONES` (~600 entries) moves out of `PITR.constants.ts` into a
shared `lib/constants/timezones.ts`. PITR keeps a re-export shim so its
callers don't move. New `TIMEZONES_BY_IANA` dedupes the catalog by
primary IANA name (the original list contains both PDT and PST rows for
`America/Los_Angeles`, etc.) and `findTimezoneByIana` provides reverse
lookup.
- Telemetry: `timezone_picker_clicked` PostHog event with
`previousTimezone`, `nextTimezone`, `isAutoDetected` properties.
Notes for reviewers:
- Bare `dayjs(x).format(...)` calls (~157 files) intentionally still
render in browser-local time. Surfaces opt in by switching to the new
wrappers, so this PR is the abstraction plus logs adoption; broader
migration is a follow-up.
- Two `// prettier-ignore` lines (`apps/studio/pages/_app.tsx`,
`apps/studio/components/interfaces/UnifiedLogs/UnifiedLogs.fields.tsx`)
work around a pre-existing local-tooling issue where
`prettier-plugin-sql-cst` strips angle-bracket type arguments under
certain conditions. Project's pinned prettier (3.8.1) does not strip;
the issue surfaces with a globally-installed prettier. Worth tracking
separately.
- Hydration: `guessLocalTimezone()` and `useLocalStorageQuery` are
client-only. Studio is mostly CSR via the Pages Router, but any SSR'd
`<TimestampInfo>` may briefly render in the server's tz before client
hydration. Existing behavior already had this mismatch with `.local()`;
this PR does not regress it.
- Backend timestamps round-tripped through query params and mutations
stay UTC. The picker is display-only.
## How to test
- Run `pnpm dev:studio`, sign in.
- Open the user avatar dropdown (top right). Hover Timezone.
- Search for "tokyo", pick `(UTC+09:00) Osaka, Sapporo, Tokyo`.
- Open any project, navigate to Logs (e.g. `Project > Logs > Edge
Functions`). Hover a log row's timestamp; the popover should show UTC,
the chosen tz (`Asia/Tokyo`), and the relative time. Visible cell text
should be in JST.
- Visit any page that uses `<TimestampInfo>` (Database > Backups,
Project Pause state, Edge Function details). Same tooltip should reflect
Asia/Tokyo.
- Refresh the page; timezone is still Asia/Tokyo.
- Reopen the picker, choose Auto detect; timestamps revert to browser
local.
- Run `pnpm --filter studio test lib/datetime.test.ts`. 17 tests should
pass.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Timezone selector added to the user menu with auto-detect and manual
override
* App-wide timezone provider and hooks plus a shared timezone catalog
for consistent timezone-aware display
* Timestamp components accept an optional timezone prop and respect user
preference (persisted)
* **Bug Fixes / Improvements**
* Logs and timestamp displays now use the new timezone formatting hooks
* **Tests**
* Added comprehensive datetime and timezone catalog tests
* **Telemetry**
* Telemetry event added for timezone picker interactions
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This PR preps the monorepo for a migration to Tailwind v4:
- Bump all Tailwind dependencies and libraries to the latest possible
version, while still compatible with Tailwind 3.
- Cleans up obsolete Tailwind 3 specific options and configs.
- Cleans up unused CSS files and fixes the CSS imports.
- Migrates all `important` uses in `@apply` lines to using the `!`
prefix.
- Move `typography.css` to the `config` package and import it from the
apps.
- Migrated all occurrences of `flex-grow`, `flex-shrink`,
`overflow-clip` and `overflow-ellipsis` since they're deprecated and
will be removed in Tailwind 4.
- Make the default theme object typesafe in the `ui` package.
- Migrate all `bg-opacity`, `border-opacity`, `ring-opacity` and
`divider-opacity` to the new format where they're declared as part of
the property color.
- Bump and unify all imports of `postcss` dependency.
smol fix
- closes https://github.com/supabase/supabase/issues/44595
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Improved visual feedback for the Changelog dropdown entry with
enhanced cursor styling to indicate interactivity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Adds a tooltip for the account settings button
## What is the current behavior?
It has no tooltip
Closes#44524
## What is the new behavior?
Has Tooltip
## Additional context
<img width="552" height="167" alt="Screenshot 2026-04-03 at 22 21 35"
src="https://github.com/user-attachments/assets/e41caee7-e688-4bd9-8823-0c47133c5470"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Improved interface usability by adding descriptive tooltips to
dropdown menu triggers in the studio. The settings dropdown trigger now
displays a "Settings" tooltip, while the user account dropdown trigger
displays "Account settings" to provide clearer guidance, help users
navigate key interface controls, and enhance the overall user
experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ali Waseem <waseema393@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Bug fix / UI Polish
## What is the current behavior?
Interactive menu items in the User Account dropdown (top right profile
picture) use the `default` (arrow) cursor. This makes it less intuitive
that these items are clickable.
Closes#42360
## What is the new behavior?
This PR adds `cursor-pointer` to all interactive menu items in both the
[UserDropdown](cci:1://file:///home/erik/Documents/supabase/apps/studio/components/interfaces/UserDropdown.tsx:27:0-140:1)
(platform) and
[LocalDropdown](cci:1://file:///home/erik/Documents/supabase/apps/studio/components/interfaces/LocalDropdown.tsx:21:0-68:1)
(local/self-hosted) components. This provides correct visual feedback to
users when hovering over:
- Account preferences
- Feature previews
- Command menu (local)
- Theme selections
- Logout
## Additional context
Verified the changes locally for both
[LocalDropdown](cci:1://file:///home/erik/Documents/supabase/apps/studio/components/interfaces/LocalDropdown.tsx:21:0-68:1)
and
[UserDropdown](cci:1://file:///home/erik/Documents/supabase/apps/studio/components/interfaces/UserDropdown.tsx:27:0-140:1).
### Screenshots
Before:
<img width="262" height="301" alt="image"
src="https://github.com/user-attachments/assets/0c985b1b-065c-49d4-94d4-8dd07fa0ff67"
/>
After:
<img width="262" height="301" alt="image"
src="https://github.com/user-attachments/assets/e2ade471-0a84-4405-8e2c-8f757f5dfaf4"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Cursor-pointer indicators added to interactive dropdown items across
the app (account settings, feature previews, command menu entries, theme
selection radios, logout), improving hover feedback and visual
consistency for menu interactions.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a Changelog link to the user dropdown menu, providing quick
access to product updates.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
When user logs out from the user dropdown, they're redirected to the
sign-in page via the withAuth redirect, which means that the returnTo
param is used -- but if the user _intentionally_ logged out, this might
not be the right behavior, i.e., if they want to log in to another
account. Instead, if they chose to log out, we shouldn't use the
returnTo param.
Since the /logout page already implements this behavior, I changed "Log
out" button to just route to the /logout page.
* update onboarding
* update model and fix part issue
* action orientated assistant
* fix tool
* lock
* remove unused filter
* fix tests
* fix again
* update package
* update container
* fix tests
* refactor(ai assistant): break out message markdown and profile picture
* wip
* refactor(ai assistant): break up message component
* refactor: break ai assistant message down into multiple files
* refactor: simplify ReportBlock state
* fix: styling of draggable report block header
When the drag handle is showing, it overlaps with the block header.
Decrease the opacity of the header so the handle can be seen and the two
can be distinguished.
* fix: minor tweaks to tool ui
* refactor: simplify DisplayBlockRenderer state
* fix: remove double deploy button in edge function block
When the confirm footer is shown, the deploy button on the top right should be
hidden (not just disabled) to avoid confusion.
* refactor, test: message sanitization by opt-in level
Refactor the message sanitization to have more type safety and be more testable.
Add tests to ensure:
- Message sanitization always runs on generate-v4
- Message sanitization correctly works by opt-in level
* Fix conflicts in pnpm lock
* Couple of nits and refactors
* Revert casing for report block snippet
* adjust sanitised prompt
* Fix tests
---------
Co-authored-by: Charis Lam <26616127+charislam@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* feat(profile): add self-serve editing of username and primary email
Users can now update `username` and choose a `primary_email` directly in the
Dashboard profile editor.
Changes:
- Add `username` and `primary_email` fields to the profile form.
- Introduce `Select_Shadcn_` dropdown listing the user's identities
(via `useProfileIdentitiesQuery`) for selecting a primary email.
- Default `primary_email` selection is derived from the current profile.
- Extend form submission to patch `username` and `primary_email` to the
profile API.
- Wire zod schema and react-hook-form defaults for new fields.
* chore: remove unused variable
* fix: disable username & primary_email modification for SSO users
* Small refactors
* Remove hard code
* Refactor to use FormItemLayout
* chore: add descriptions for primary_email and username
* chore: fix format and lint error
* chore: fix lint error
* Use identities to derive user dropdown profile image, and remove profile image from useProfile hook
---------
Co-authored-by: Chris Stockton <chris.stockton@supabase.io>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* feat: enable/disable dashboard features
* use the set directly
* move enabled features to common
* remove sneaky any
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
* chore: add signed out redirect timeout
* Add modal
* Nudge language
* Add temp github link
* Use captureException
* Minor refactor
* Revert staging specific testing logic
* Fix the sentry message send
* Change to event
* Add debugging
* Use an actual error
* Adjust logging
* always send errors
* even more debugging
* Remove all beforeSend checks
* Restore beforeSend
* Debug
* Retry original
* Again
* Test always send
* Cleanup
* Test frames again
* Retry third party error function
* Cleanup
* Remove hardcoded debugging
---------
Co-authored-by: Terry Sutton <saltcod@gmail.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>