Commit Graph
265 Commits
Author SHA1 Message Date
Gildas Garcia 243e079a2c chore: remove _Shadcn_ suffix from Command components (#46153)
## Problem

The `_Shadcn_` suffix isn't needed anymore on `Command` components

## Solution

- Remove the `_Shadcn_` suffix
- Simplify UI package exports
- Apply prettier

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Simplified command component imports and exports across the UI library
by removing internal naming aliases and adopting direct component
references. Updated the public UI package barrel export to use wildcard
re-exports for cleaner API surface.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46153?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-20 15:45:32 +02:00
Julian Domke c414146572 fix(upcomingInvoice): do not manually subtract credits (#46116) 2026-05-20 14:46:54 +08:00
Gildas Garcia 5d97339d41 chore: remove <Select> _Shadcn_ suffix (#45988)
## Problem

The `_Shadcn_` suffix isn't needed anymore on `Select` components

## Solution

Remove it. No other changes

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Updated internal component architecture to standardize and simplify
the codebase. These changes improve code maintainability and consistency
across the application without affecting existing functionality or user
experience.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45988)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-15 16:39:57 +02:00
Gildas Garcia 86a3f8b03d chore: upgrade to react-19 (#45886)
- Most changes are related to either types or `useRef` usages (it now
requires an initial value).
- also updated `vaul` to its latest version and haven't noticed any
change ([design-system
demo](https://design-system-git-react-19-supabase.vercel.app/design-system/docs/components/drawer))

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Upgraded workspace to React 19.

* **Bug Fixes**
* Improved null-safety and ref handling across editors, UI components,
shortcuts, and markdown/image rendering to reduce runtime errors.
* Safer event/timeout/interval cleanup and more robust command/context
handling.

* **Chores**
  * Bumped vaul dependency versions.

* **Documentation**
* Type and TypeScript accuracy improvements for clearer developer
feedback.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45886)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-15 16:04:41 +02:00
Gildas Garcia d0fd4478c0 chore: migrate Popover usages to Shadcn components (#45980)
## Problem

We have multiple Popover components

## Solution

- [x] migrate Popover usages to Shadcn components
- Migrated JSON and text editor in the `TableEditor` (inline row
edition)
  - Migrated the template popover in the logs explorer templates page
- [x] remove `_Shadcn_` suffix from Popover components (renaming +
prettier)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Unified popover implementation across the app and design system;
dropdowns, calendars, menus and tooltips now use a consistent popover
API with no visual or interaction changes.

* **Chores**
* Minor prop typing update for the logs date-picker to align with the
consolidated popover content type.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45980)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-15 15:20:28 +02:00
Gildas Garcia 0713a1efc1 chore: remove shadcn suffix for Input, Textarea, Alert and Collapsible (#45867)
## Problem

Now that we migrated old components to their new shadcn alternatives, we
don't need the `_Shadcn_` suffix anymore.

## Solution

Remove it

<img width="659" height="609" alt="image"
src="https://github.com/user-attachments/assets/2d7271a9-066a-4dcc-92fe-729b106d2c2f"
/>
2026-05-15 14:55:37 +02:00
K-Dog (Kevin) 2efaf8e5c1 chore(upcoming invoice): min amount / no plan fee (#45877)
Prep work for new platform plan
<img width="733" height="120" alt="Screenshot 2026-05-13 at 8 25 29 PM"
src="https://github.com/user-attachments/assets/5667bb86-e317-44f7-86ac-07a8c5cc1994"
/>
2026-05-14 12:05:11 +08:00
Joshen Lim 28f5484369 Prevent request billing owner for downgrade of plan (#45823)
Related PR: https://github.com/supabase/supabase/pull/45803

Opting for a simpler way to prevent requesting billing owners for
downgrading of plan as such:
<img width="933" height="258" alt="image"
src="https://github.com/user-attachments/assets/604b8c2f-9341-4aec-885c-e2d9d2861b9f"
/>

Currently we're incorrectly showing a "Request to upgrade to Free" CTA

## To test

- [ ] For a pro plan or above organization, and a user that has a
"Developer" role, ensure that you're not able to downgrade the org nor
send a upgrade request


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Clarified CTA behavior for users without billing update permission:
downgrade actions now show a disabled button with an explicit tooltip,
while non-downgrade upgrade attempts prompt a request to billing owners.
Tooltip messaging has been refined across enterprise, free-tier, and
marketplace-managed plans for clearer guidance.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45823)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-13 21:32:34 +08:00
Gildas Garcia 35571d242e chore: migrate <Collapsible> to shadcn <Collapsible> (#45819)
## Problem

We have multiple `Collapsible` components.

## Solution

Reduce their number by using only the one from shadcn.
I haven't noticed any visual nor functional changes.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Migrated expandable/collapsible UI to a unified shadcn-based
implementation for more consistent expand/collapse behavior across the
app.

* **Style**
* Updated listbox check icon sizing and removed obsolete collapsible
open/close animations.

* **Chores**
* Removed deprecated collapsible variants and consolidated UI component
surface for simpler maintenance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-13 09:39:48 +02:00
Gildas GarciaandDanny White 1fbed21528 chore: migrate old <Alert> usages to <Admonition> (#45797)
## Problem

Some pages still use the old `<Alert>` component

## Solution

- [x] Use the new `<Admonition>`
- [x] Remove `<Alert>` 

## Screenshots

### Table Editor - Disable RLS modal
Before:
<img width="582" height="527" alt="image"
src="https://github.com/user-attachments/assets/bbc5b874-2569-4cd6-98c0-5edd5ac78e0f"
/>

After:
<img width="543" height="505" alt="image"
src="https://github.com/user-attachments/assets/bb1da899-2163-4b26-ba0b-74726e0cb5df"
/>

### Organization Billing
Before:
<img width="1111" height="512" alt="image"
src="https://github.com/user-attachments/assets/6fb410fb-9ac0-4fb7-8dde-e304ddee7ece"
/>

After:
<img width="1103" height="531" alt="image"
src="https://github.com/user-attachments/assets/6eda6ede-edc6-482f-ab9c-d085402cbd64"
/>




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Replaced Alert UIs with Admonition across billing, settings, storage,
integrations, and editor interfaces.
  * Removed the deprecated AlphaPreview component.

* **Chores**
* Removed the Alert component from the UI library, including its styles,
tests, and theme configuration.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45797)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
2026-05-12 16:48:06 +02:00
Ignacio DobronichandJoshen Lim a4f964e452 fix: in-arrears transition in upcoming invoice (#45765)
## Show notice when plan fee is prepaid for the upcoming invoice

When a subscription's plan fee has already been billed for the current
period (e.g. transitioning to in-arrears billing), the upcoming invoice
no longer contains a plan line item. Previously this rendered as an
empty plan row with a `-`, which was confusing.

<img width="2178" height="538" alt="image"
src="https://github.com/user-attachments/assets/1fa289d9-60ae-48b1-b779-34770bc2c242"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Billing breakdown now detects when the plan fee was already paid
upfront, hides the redundant plan line, and notes only usage will be
invoiced; shows the organization plan name when available.
* Backup restoration: added an optional recovery time target for
physical backups.
  * Expanded supported AWS instance types for deployments.

* **UI**
* Compute and Replica Compute docs links now use inline linking for a
smoother in-app experience.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/45765)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-05-11 13:09:10 -03:00
Ignacio Dobronich 27f31ef692 feat(billing): prepaid credits in upcoming invoice (#45475)
## Summary

- Display a "Prepaid Credits" line in the upcoming invoice breakdown,
shown directly below Current Costs when the upcoming invoice contains
a `Prepaid Credits` line item
- Surfaces the credit amount being applied (e.g. `-$300`) so users can
see how prepaid credits offset their projected bill
- Consolidates the projected tax items into the tooltip for `Projected
Costs`
<img width="1416" height="426" alt="image"
src="https://github.com/user-attachments/assets/b3455e82-d03b-40c3-ad5f-493a56004ddf"
/>


## Test plan

- [x]  On an org with prepaid credits applied, verify the "Prepaid
Credits" row appears below Current Costs with the negative amount and a
tooltip showing the backend description
- [x]  On an org without prepaid credits, verify the row is not rendered

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

* **Improvements**
* Clarified the "Upcoming Invoice" explanatory copy for non–AWS
Marketplace-managed organizations: it now notes the invoice will
continue updating until the end of your billing cycle.
* Improved invoice breakdown: compute charges and compute credits are
distinguished, and a dedicated "Prepaid Credits" row is shown before
projected costs for clearer billing totals.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-11 12:30:25 -03:00
Sean OliverandJoshen Lim b14ecb5b1e fix: align grace-period banner copy on org usage page (#45652)
## 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 — copy + visibility logic on the org Usage page.

## What is the current behavior?

On `/org/<slug>/usage` during a grace period, customers see two banners
that read as contradictory:

1. *"Organization plan has exceeded its quota — grace period until
{date}."*
2. *"You have not exceeded your Pro Plan quota in this billing cycle."*

<img width="1680" height="372" alt="image"
src="https://github.com/user-attachments/assets/13826260-55dd-4b55-a3dc-5afc51e6436e"
/>

Both are individually correct. The first is sticky from the previous
cycle's overage (`org.restriction_status`); the second is a live scan
over the current cycle. Neither anchors to which cycle it's talking
about, so together they read like the dashboard contradicting itself.
Surfaced by support off SU-368527 and SU-368395.

## What is the new behavior?

- Top chrome banner copy: *"Organization exceeded its quota in the
previous billing cycle / You have a grace period until {date} to bring
usage back under quota."*
- Inline `<Restriction />` grace-period alert switches from "is over its
quota" to "went over its quota in the previous billing cycle." Same
temporal anchor.
- The "…in this billing cycle" summary line in `<TotalUsage>` is hidden
whenever `restriction_status` is set. Mirrors the precedence rule
`<Restriction />` already applies internally — backend status flag wins
over the live cycle scan.

<img width="1678" height="937" alt="CleanShot 2026-05-06 at 12 58 02"
src="https://github.com/user-attachments/assets/df55eaed-1029-4f39-bea0-df77bcc5151e"
/>


## Additional context

Left the `gracePeriodOver` copy alone on purpose — it doesn't make a
current-overage claim, so there's nothing to contradict, and adding
"previous cycle" would muddy which cycle "previous" refers to.

**Verified**
- Lint and typecheck pass on `apps/studio`.

**Before merge**
- [ ] Load a grace-period org locally: confirm new copy on top banner
and inline `<Restriction />`, and that the "not exceeded in this billing
cycle" line is gone.
- [ ] Copy review with support — happy to workshop wording.

GROWTH-823

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Updates**
* Updated grace period alert messaging to clarify organization quota
status
  * Refined date formatting in billing restriction notifications
* Modified usage display to conditionally hide certain information when
account restrictions are active

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-05-07 15:46:22 -07:00
K-Dog (Kevin) 5082c9b35d chore(billing): use new balance endpoint (#45481)
New billing credits balance endpoint for improved transparency
2026-05-07 16:44:01 -03:00
Gildas Garcia 678aec3845 chore: migrate Input usages to Shadcn component in various screens/components (#45604)
## Screenshots

### Table editor: foreign record selector
Before:
<img width="802" height="213" alt="image"
src="https://github.com/user-attachments/assets/82ee3ce6-ac72-4b49-b1b0-2e635688cbb1"
/>

After:
<img width="609" height="194" alt="image"
src="https://github.com/user-attachments/assets/e9cc09c1-1c6b-4099-8cae-abe08f50fda9"
/>


### Account - Add TOTP
Before:
<img width="527" height="679" alt="image"
src="https://github.com/user-attachments/assets/b9f4a626-e24b-46e3-8385-700ef181308b"
/>

After:
<img width="531" height="684" alt="image"
src="https://github.com/user-attachments/assets/549745a7-9655-4a7d-9e0e-51f75b6a1c61"
/>

### Organisation Audit Logs Details
Before:
<img width="673" height="1321" alt="image"
src="https://github.com/user-attachments/assets/0bb360cf-6f27-4574-b9af-485a3836b17b"
/>

After:
<img width="669" height="1273" alt="image"
src="https://github.com/user-attachments/assets/0382c662-e270-41fd-a8ee-08528dedfce3"
/>

### Data API Integration Docs
Before:
<img width="1115" height="891" alt="image"
src="https://github.com/user-attachments/assets/db0c7698-53b7-4422-aac3-5e674b0bf151"
/>

After:
<img width="1193" height="1272" alt="image"
src="https://github.com/user-attachments/assets/927e5c43-413b-49c1-9b71-8ab628179c70"
/>

### Edge Function Edit Secret
Before:
<img width="599" height="255" alt="image"
src="https://github.com/user-attachments/assets/d6aa2f87-e247-4724-9e43-02b71933241c"
/>

After:
<img width="596" height="261" alt="image"
src="https://github.com/user-attachments/assets/d94acb41-07e1-497f-9697-830390526f4a"
/>

### JWT Key Details
Before:
<img width="536" height="549" alt="image"
src="https://github.com/user-attachments/assets/43672adc-dc0e-4e65-b7d4-b4537d22f6ea"
/>

After:
<img width="523" height="517" alt="image"
src="https://github.com/user-attachments/assets/e501e8a8-7f41-46a0-bb69-d240cea594f0"
/>

### Realtime Filter Popover
Before:
<img width="403" height="576" alt="image"
src="https://github.com/user-attachments/assets/73842450-ba87-456b-98fc-625b99149449"
/>

After:
<img width="387" height="564" alt="image"
src="https://github.com/user-attachments/assets/f2b35035-947c-4342-84dd-3548f9bd5e9f"
/>

### Realtime broadcast message dialog
Before:
<img width="520" height="393" alt="image"
src="https://github.com/user-attachments/assets/4f4a1a93-e0cf-4268-ae4e-baf8b8a62e74"
/>

After:
<img width="525" height="392" alt="image"
src="https://github.com/user-attachments/assets/e1c1934a-1812-4013-8606-9b846dc2498d"
/>

### Impersonation Popover
Before:
<img width="604" height="501" alt="image"
src="https://github.com/user-attachments/assets/9abdc604-94f8-4ed4-9a95-4688e6504e76"
/>
<img width="587" height="599" alt="image"
src="https://github.com/user-attachments/assets/5293c80c-9abd-43eb-899f-da759c83b598"
/>

After:
<img width="594" height="585" alt="image"
src="https://github.com/user-attachments/assets/5eaf2162-2d7f-444c-9052-c9afb00080f6"
/>
<img width="590" height="597" alt="image"
src="https://github.com/user-attachments/assets/149dc7c1-689c-4e0f-a884-c6f5b0228ebc"
/>

### Storage move item
Before:
<img width="521" height="285" alt="image"
src="https://github.com/user-attachments/assets/7d0f945f-add5-412b-813a-9325b260ab28"
/>

After:
<img width="529" height="274" alt="image"
src="https://github.com/user-attachments/assets/ab0891a1-b31b-40b6-be53-92afc95095ea"
/>

### Table Editor - Spreadsheet import
Before:
<img width="673" height="506" alt="image"
src="https://github.com/user-attachments/assets/7a722908-10c2-4c04-95fb-b12d3c23557c"
/>

After:
<img width="671" height="638" alt="image"
src="https://github.com/user-attachments/assets/689b1fb6-031c-4a02-9e7f-739356c1453d"
/>

### Org Billing downgrade survey
Before:
<img width="788" height="655" alt="image"
src="https://github.com/user-attachments/assets/c7a0d4c6-e9b9-4c6c-9cf1-e7d05016233f"
/>

After:
<img width="1630" height="1354" alt="image"
src="https://github.com/user-attachments/assets/e3f5473b-db9a-42b1-9242-40480c25fc02"
/>

### Project API Docs
Before:
<img width="1030" height="396" alt="image"
src="https://github.com/user-attachments/assets/95643b21-811a-4ba7-918a-5e655c262ac1"
/>

After:
<img width="1012" height="457" alt="image"
src="https://github.com/user-attachments/assets/d5559646-bb89-43b6-ad62-c5684b54b3fb"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Standardized form field layouts across panels, dialogs, and modals for
a more consistent editing and reading experience.
* Replaced several Input-based textareas with dedicated
TextArea/ExpandingTextArea controls and aligned labels with wrapper
layouts for clearer accessibility.
* Introduced grouped/composable input controls, added additional
read-only detail fields and labeled value/copy blocks, and tightened
header/layout spacing and control alignment.
  * Swapped notice styles for improved warning/admonition presentation.

* **Chores**
  * Removed a deprecated AutoTextArea component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-07 17:07:11 +02:00
Joshen Lim aab3924eef Refactor Invoice estimate tooltip in plan update confirmation dialog (#45446)
## Context

Main fix is to ensure that the tooltip here is scrollable - but also
adding some refactors
This is the org billing page when downgrading an org

### Before
<img width="400" alt="image"
src="https://github.com/user-attachments/assets/6094c2e6-c1bb-460f-a2d2-347c1d7d2e77"
/>

### After
<img width="400" alt="image"
src="https://github.com/user-attachments/assets/9d0ac9a6-6e89-4758-af14-8144a8a86469"
/>

## Changes involved
- Use HoverCard for invoice estimate in plan confirmation dialog
- Also nudge the UI a little, e.g use a separate column for the compute
prices + adjust text color to improve clarity
- Refactor usage of `any` for some of the TS declarations

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added an invoice estimate tooltip in subscription settings showing
monthly charges with plan fees, combined compute rows, per-project
compute costs, optional compute credits, and a total monthly estimate.

* **Refactor**
* Simplified the plan update flow by consolidating subscription preview
handling and extracting the invoice UI into the new tooltip component.

* **Chores**
* Improved internal type definitions for subscription preview data and
pricing tier identifiers.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 10:54:18 +08:00
Ignacio DobronichandJoshen Lim cf9d88700d fix: top-up loading state and show plan item on downgrade (#45430)
## Summary

- **Subscription downgrade dialog**: The plan name row was being hidden
in the charge breakdown when `changeType === 'downgrade'`, so users
downgrading (e.g. Team → Pro) couldn't see which plan the cost referred
to. Removed the downgrade exclusion so the plan name row renders
consistently across upgrade/downgrade flows.
- **Credit Top Up dialog**: The submit button only
reflected `executingTopUp`/`paymentConfirmationLoading`, but
the `onSubmit` handler runs several async steps first (hCaptcha, billing
profile validation, Stripe `createPaymentMethod`) before the mutation
flips `isPending`. That left a clickable window where users could
trigger multiple top-ups. Added `form.formState.isSubmitting` to
both `loading` and `disabled` so the button is locked for the full
submit lifecycle.

## Test plan

- [ ]  Downgrade from Team → Pro and confirm the Pro plan row appears in
the charge breakdown
- [ ]  Open Credit Top Up, submit, and rapidly click the Top Up button —
verify only one charge is initiated
- [ ]  Verify Top Up button shows a loading state immediately on click
(before the mutation starts)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Consistently show subscription plan cost during billing adjustments,
including downgrades.
* Improve Top Up button to reflect form submission state and prevent
duplicate submissions.

* **Style**
* Enhanced text contrast for better readability in billing information
displays.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-04-30 14:40:08 -03:00
Ivan VasilovandJordi Enric 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00
Gildas Garcia 718021fc7b chore: migrate Listbox to Shadcn components (#45279)
## Problem

We want to reduce the code we ship and maintain.

## Solution

Migrate old `<Listbox />` usage to the new Shadcn component.

## Screenshots

### Billing
Before:
<img width="536" height="458" alt="image"
src="https://github.com/user-attachments/assets/c8883bd8-cbbd-47cd-84a4-e37a36c05cd6"
/>

After:
<img width="541" height="451" alt="image"
src="https://github.com/user-attachments/assets/9c848b1b-e72a-413c-b264-48340ce0c7ef"
/>

### Foreign Key Editor
Before:
<img width="463" height="995" alt="image"
src="https://github.com/user-attachments/assets/4debeeeb-94bd-439d-8f57-a84a2ed5230a"
/>
<img width="428" height="241" alt="image"
src="https://github.com/user-attachments/assets/81a21d58-c023-445a-a6e8-c9be22b53075"
/>

After:
<img width="451" height="1007" alt="image"
src="https://github.com/user-attachments/assets/18c781c0-4f52-4ca2-99e6-1fc34dc857e3"
/>
<img width="434" height="240" alt="image"
src="https://github.com/user-attachments/assets/13fbb3ad-ef3c-499d-a27e-26cfae89ae44"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Replaced legacy dropdowns with a unified Select component and
consistent form layout across payment method, org transfer,
foreign-key/column selectors, region selection, and other dropdowns.
* **Chores**
* Removed the legacy listbox implementation and its public exports from
the UI package.
* **Tests**
* Removed old listbox unit tests and updated e2e selectors to target the
new Select-based controls.
* **Style**
  * Deleted obsolete listbox-specific styles.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-28 14:30:49 +02:00
Ivan Vasilov 308cd791a2 chore: Prep work for migrating to Tailwind v4 (#45285)
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.
2026-04-28 11:33:53 +02:00
9e3a10d557 feat(studio): payment method states for Stripe Projects orgs (#44965)
## What kind of change does this PR introduce?

UI changes for Stripe-managed billing surfaces.

- Resolves DEPR-537
- Related to DEPR-538

## What is the current behaviour?

Stripe-connected organisations still look too self-serve in Studio.

- Payment Methods still reads mostly like ordinary Supabase card
management, even though billing is handled through a Shared Payment
Token via Stripe Projects
- invoice messaging still implies support is the path to changing
payment methods, even for Stripe-managed orgs
- the Subscription Plan flow still needs Stripe-specific guardrails so
users are redirected to the correct upgrade path rather than trying to
self-serve everything in Studio
- the base branch now correctly separates `integration_source` from
`billing_partner`, but this stacked work still needs to carry that split
through the Stripe billing-token surfaces

## What is the new behaviour?

This PR makes the Stripe-managed billing surfaces behave like
Stripe-managed billing surfaces, while leaving AWS and Vercel on the
existing `billing_partner` path.

- Payment Methods now keeps the familiar saved-card row, but augments
Stripe-managed rows with Shared Payment Token context, token status, and
Stripe Projects affordances
- Stripe-managed invoice messaging now points users to Stripe Projects
rather than to support for payment-method changes
- the Subscription Plan flow keeps the existing managed-billing shape,
with Stripe-specific guardrails layered in where plan changes should be
handled outside Studio
- AWS and Vercel continue to use the existing partner-managed alerts and
CTAs driven by `billing_partner` / `billing_via_partner`

| Subscription plan sheet |
| --- |
| <img width="1780" height="448" alt="CleanShot 2026-04-24 at 17 21
43@2x"
src="https://github.com/user-attachments/assets/34c0f3ba-fc42-4d07-97a2-0e4f4cefc55e"
/> |
| _Upgrade instructions_ |
| <img width="1786" height="460" alt="CleanShot 2026-04-24 at 17 20
12@2x"
src="https://github.com/user-attachments/assets/bb67c835-b9b2-4648-b0e1-9c2f8d2317d3"
/> |
| _Downgrade instructions_ | 

> [!NOTE]
> The below screenshots are outdated. The _Shared Payment Token_
terminology has been removed in favour of more generic copy such as
_Stripe Projects token_.

| Stripe payment method states |
| --- |
| <img width="1436" height="234" alt="CleanShot 2026-04-23 at 19 03
49@2x"
src="https://github.com/user-attachments/assets/52ed7a00-dfba-4b66-9a07-a6346692d3c8"
/> |
| _Healthy_ |
| <img width="1434" height="224" alt="CleanShot 2026-04-23 at 19 04
50@2x"
src="https://github.com/user-attachments/assets/94efd943-b7bf-4da2-9e1b-1828aae97126"
/> |
| _Card expiring soon_ |
| <img width="1436" height="236" alt="CleanShot 2026-04-23 at 19 06
51@2x"
src="https://github.com/user-attachments/assets/272cb707-c724-4629-890e-853972e53a18"
/> |
| _Card expired_ |
| <img width="1308" height="238" alt="CleanShot 2026-04-23 at 19 07
21@2x"
src="https://github.com/user-attachments/assets/3eadd2a9-def3-4f43-850e-7d82adfb0b57"
/> |
| _Token expired_ |

## Dependencies

This PR is stacked on:

- #44328

It also depends on the private platform work that exposes Stripe project
connection state and SPT details:

- https://github.com/supabase/platform/pull/31874
- https://github.com/supabase/platform/pull/31940

## Platform dependency status

Most of the remaining platform work for this stack is now covered by the
private dependency below:

- https://github.com/supabase/platform/pull/31940

That PR is expected to provide the SPT details and paid-flow fixes this
Studio work depends on. In practice, the main caveat here is less
“Studio still needs a bunch of new platform work” and more “do not merge
this until `platform#31940` has landed and the end-to-end Stripe-managed
flow has been rechecked”.

## Local testing

Use the same local Stripe setup as the base branch, with
`integration_source: 'stripe_projects'` returned consistently for:

- `/platform/organizations`
- `/platform/organizations/:slug/projects`
- `/platform/projects/:ref`

For payment method demos, the temporary local mock currently lives in
private `platform` on:

- `/platform/organizations/:slug/payments`

That mock can be flipped between:

- healthy token + healthy underlying card
- healthy token + card expiring soon
- healthy token + expired card
- expired token

Then verify:

- the org and project connection affordances from #44328 still render
correctly
- Payment Methods shows Stripe-managed token context rather than
implying ordinary self-serve card management
- regression test ordinary non-Stripe payment methods too, to confirm
the standard saved-card row still renders with the existing `Expires:`
copy and no Shared Payment Token affordances
- invoice messaging points Stripe-managed orgs to Stripe Projects rather
than support
- Subscription Plan keeps the managed-billing guardrails for Stripe
- AWS and Vercel orgs still show the existing partner-managed messaging
rather than the Stripe-specific notices

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Stripe-managed organizations show Stripe Projects billing guidance,
replace in-app payment management with Stripe links, and adjust billing
copy.
* Payment methods support Shared Payment Tokens (SPTs): token
expiry/status badges with tooltips, “Handled via Stripe Projects”
indicator, token last4/expiry display, and disabled local update/delete
actions for SPTs.

* **API**
* Payments response now includes optional shared payment token details
for payment methods.

* **Documentation**
  * Added links to Stripe Projects billing docs in relevant flows.

* **Tests**
  * Updated and added tests covering Stripe-managed and SPT behaviors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Raúl Barroso <code@raulb.dev>
2026-04-28 12:17:29 +10:00
Ignacio Dobronich 98211ed3dc feat: update CreditTopUp to mention pre-tax credits (#45255) 2026-04-27 14:56:20 -03:00
Ignacio Dobronich 4763ac8374 fix: show plan name on empty orgs (#45247)
## Summary

- Show the plan name row in the monthly invoice estimate tooltip even
when the organization has no projects, so the section no longer appears
headerless next to the tax line.

## Test plan

- [ ]  Open an org with no projects → Subscription plan update dialog →
hover the "Monthly invoice estimate" tooltip → verify the plan name +
price row is visible.
- [ ]  Repeat on an org with projects → verify plan, Compute row, and
project breakdown all still render as before.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Improved rendering of the Monthly invoice estimate table in the
subscription plan update dialog, with reorganized display logic for plan
and project billing rows.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-27 14:29:34 -03:00
Joshen Lim 7f5865872a Enforce noUnusedLocals and noUnusedParameters in tsconfig.json + fix all related issues (#45264)
## Context

Enforce `noUnusedLocals` and `noUnusedParameters` in tsconfig.json + fix
all related issues
2026-04-27 17:42:34 +08:00
Gildas Garcia 416210d666 chore: remove _Shadcn_ suffix for Checkbox and Radio components (#45263)
## Problem

With #45211 and #45218 merged, we don't need the `_Shadcn_` suffix
anymore

## Solution

- [x] Remove the `_Shadcn_` suffix 
- [x] Update exports and imports 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Standardized UI component exports by removing legacy naming
conventions and providing direct imports for checkbox and radio group
components throughout the design system.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-27 11:07:06 +02:00
Gildas Garcia 0facd341a6 chore: remove UI form components _Shadcn_ suffix (#45212)
## Problem

We used to have a `_Shadcn_` suffix for all the shadcn form components
because we also had `formik` form components.
This is not needed anymore.

## Solution

- Remove the suffix
- Update all usages
2026-04-24 12:14:15 +02:00
Kanishk Dudeja 9d2807e19b feat(billing): include prepaid credits in credit balance (#45177)
### Summary

This PR updates the logic to include `prepaid_credits_balance` while
showing the existing customer balance.

This changes the credit balance shown in:

- Billing Settings > Credit Balance
- Credit code redemption modal

The displayed amount now reflects the total credit balance across
prepaid credits and the customer balance.

### Testing

- Open an org billing page with prepaid credits and verify Credit
Balance includes both sources.
- Open the credit redemption modal and verify Current Balance matches
the combined credit amount.
- Verify an org with only customer balance still shows the same credit
amount as before.
- Verify an org with only prepaid credits balance and no customer
balance now shows credits correctly.
- Verify an org with no credits shows 0.00 and does not show /credits.
- Verify an org where net balance is debt still shows a negative amount
without the /credits suffix.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Improvements**
* Credit balance display now includes purchased and prorated credits for
a complete account view.
* Credit redemption and current-balance screens now show combined credit
totals (prepaid + existing) for clearer availability.
* UI descriptive text clarified to explain how credits are applied and
how charges occur once credits are exhausted.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-24 15:24:24 +05:30
Ignacio Dobronich 7739b7a540 fix: clear tax ID fields on billing country change (#45182)
### Summary

Mirrors the tax-ID-clearing behavior already present in
`NewPaymentMethodElement` (used by `AddPaymentMethodForm`) over to
`BillingCustomerDataForm`. When a user changes their billing country,
the previously selected tax ID (type, value, name) is now cleared so a
stale tax ID from the previous country doesn't silently persist under
the new one.

### Test plan

- [x]  Open **Organization Settings → Billing → Billing Address** for an
org with a saved billing address + tax ID
- [x]  Verify the saved tax ID is shown on initial load (not cleared)
- [x]  Change the country in the address element to a different country
- [x]  Verify the tax ID combobox resets to "Select tax ID" and the tax
ID value input disappears
- [x]  Change the country back to the original country → tax ID still
cleared (does not re-populate)
- [x]  Pick a new tax ID for the new country, enter a value, save →
confirm it persists
- [x]  Reload the page → saved tax ID shows correctly and is not cleared
on mount

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Tax ID fields in organization billing settings are now automatically
cleared when the billing address country is changed, preventing
country-specific tax ID mismatches.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 16:49:31 -03:00
Ignacio Dobronich e6ca2766ff feat: show tax preview for credit top-ups (#45005)
## Summary

- Add tax preview to the credit top-up flow by integrating the new `POST
/organizations/{slug}/billing/credits/preview` endpoint
- Show a price breakdown (credit amount, tax line item, total) in the
top-up dialog before the user confirms payment
- Handle all three `tax_status` states: show tax when `calculated`, hide
the line when `not_applicable`, show an inline warning when `failed`


## Behavior

- Preview fires as soon as a valid amount (300–2000) is entered; address
and tax ID are optional and refine the estimate
- Amount and address changes are debounced at 1s to avoid excessive API
calls

## Test plan

- [ ]  Open credit top-up dialog - verify preview appears with default
$300 amount
- [ ]  Change amount within 300–2000 - verify preview updates after
debounce
- [ ]  Enter amount outside range (e.g. 100 or 3000) - verify preview
hides and validation error shows
- [ ]  Add a new payment method with a billing address in a taxed region
- verify tax line item appears
- [ ]  Add a new payment method with no tax jurisdiction - verify no tax
line, just total
- [ ]  Complete a top-up - verify the charge goes through and dialog
closes


<img width="571" height="551" alt="image"
src="https://github.com/user-attachments/assets/d3357752-f913-4a4a-b84a-f78e2f457c7b"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Credit top-up preview with charge breakdown (credit, tax or tax note,
total).
* Onboarding survey endpoint and ISO 27001 certificate availability for
organizations.

* **Updates**
* Improved top-up UX: debounced address/tax inputs, enforced min/max
amount validation, preview-driven form state, and submit disabled while
preview is loading/stale.
  * API docs wording changed to “temporary access configuration.”
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-23 12:16:57 -03:00
1ab7251060 chore(studio): clarify partnered orgs and projects (#44328)
## What kind of change does this PR introduce?

UI improvements.

- Resolves DEPR-401
- Resolves DEPR-424
- Resolves DEPR-425

## What is the current behaviour?

Studio currently blurs two different concepts together:

- `billing_partner` / `billing_via_partner`, which represent real
billing ownership for marketplace-managed organisations such as AWS and
Vercel
- Stripe connection state, which is not actually partner billing in the
same sense, but was previously being mocked through the same UI paths

That made the Stripe work harder to reason about and left some local
behaviour dependent on temporary overrides rather than the API shape we
want to ship.

## What is the new behaviour?

This PR separates those concerns while keeping the existing AWS and
Vercel marketplace experience intact.

- AWS and Vercel continue to use `billing_partner` /
`billing_via_partner` for billing ownership, lockouts, and manage CTAs
- Stripe display state now comes from `integration_source`, which lets
Studio show Stripe-specific badges and alerts without treating Stripe as
a billing partner
- organisation-level partner UI is unified across AWS, Vercel, and
Stripe, including the org banner, navbar icon treatment, and
organisation cards
- project-level Stripe UI now appears only when the project itself is
marked as Stripe-connected, including the project switcher, project list
surfaces, and a project-level banner
- Stripe-connected organisations are no longer incorrectly blocked
behind the AWS/Vercel-style billing management alerts for invoices,
billing address, payment methods, or plan changes
- banner dismissal is scoped to the relevant org/project and
partner/integration state

## Review order

Most of the diff size here is regression tests and generated types. The
behavioural changes are concentrated in a smaller set of files.

Recommended review order:

1. `integration_source` vs `billing_partner` data-model split and
org/project query mapping
2. org-level UI: partner icon, org banner, org dropdown/card treatment
3. billing gating updates for Stripe vs AWS/Vercel
4. project-level Stripe UI: dropdown, list surfaces, banner
5. tests and generated types

| Stripe Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/d0ef338c-3b41-4c6d-b3bd-f21a2c182840"
/> |

| Vercel Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/1dc57770-3f24-45ac-840f-34680555cde8"
/> |

| AWS Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/7847dad0-ee30-4a65-ab0b-b3b16af0d34f"
/> |

| Stripe Org, Non-Stripe Project |
| --- |
| <img width="1152" height="885" alt="Mallet Toolshed
Supabase-1673E019-792C-462C-B6F8-C5DDB810B331"
src="https://github.com/user-attachments/assets/556fbea3-b5ae-4f2f-96b9-6f66c6654e4a"
/> |

| Stripe Org, Stripe Project |
| --- |
| <img width="1152" height="885" alt="Hammer Toolshed
Supabase-7E86C17C-561F-4221-BD16-EAFF7D41AAE0"
src="https://github.com/user-attachments/assets/94f8daf6-0320-413e-8d56-59f9acaaea15"
/> |

| Vercel Org |
| --- |
| <img width="1024" height="759" alt="Projects Toolshed
Supabase-A7891653-9366-4B99-89DD-789D70CD52E3"
src="https://github.com/user-attachments/assets/c87ee6e8-4451-4866-a905-23a38b2593e3"
/> |

| AWS Org |
| --- |
| <img width="1024" height="759" alt="Projects Toolshed
Supabase-58A43ECE-569E-4541-9463-346A90B02CFF"
src="https://github.com/user-attachments/assets/9350a180-4d58-42a1-ad1a-95893c2e8b12"
/> |

This also removes the old Stripe mock override path in Studio so the
frontend matches the intended API model more closely.

## ~~Dependencies~~ (merged!)

This work depends on the private platform change that exposes
`integration_source` on the relevant organisation and project payloads:

- https://github.com/supabase/platform/pull/31874

_Update: now merged._

## Local testing

### Stripe

If you have the private `platform` repo checked out locally, make sure
your local API returns `integration_source: 'stripe_projects'`
consistently for the Stripe-linked org/project you are testing.

Important responses:

- `/platform/organizations`
- `/platform/organizations/:slug/projects`
- `/platform/projects/:ref`

Verify:

- org banner and org icon show the Stripe connected state
- unopened and opened project switcher both show Stripe only for
Stripe-linked projects
- project cards / table rows show the Stripe chip only for Stripe-linked
projects
- the project-level Stripe banner appears across project surfaces
- billing address, tax ID, invoices, payment methods, and plan changes
remain editable in Studio for Stripe orgs

### Vercel

Use a Vercel Marketplace org with real `billing_partner` /
`billing_via_partner` values.

Important org-level endpoints for local mocking in `platform`:

- `/platform/organizations`
- `/platform/organizations/:slug`
- `/platform/organizations/:slug/billing/subscription`

Project-level Vercel indicators still come from
`/platform/integrations/:slug`, not `integration_source`.

### AWS

Use an AWS Marketplace org with real `billing_partner` /
`billing_via_partner` values.

Important org-level endpoints for local mocking in `platform`:

- `/platform/organizations`
- `/platform/organizations/:slug`
- `/platform/organizations/:slug/billing/subscription`

AWS does not currently have a Stripe-like project-level indicator in
these org/project payloads.

## Notes

- `billing_partner` is no longer the right abstraction for the
Stripe-connected case in this PR. It remains the source of truth for
marketplace billing ownership, while Stripe currently uses
`integration_source` as a connection/display signal.
- I re-ran `pnpm api:codegen` while tightening this PR and kept only the
generated type changes this branch actually depends on, to avoid
unrelated API drift in the review.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Stripe Projects integration added for billing and project flows
* Partner icons/badges shown across org and project lists, dropdowns,
and rows
* Dismissible, partner-specific marketplace/integration banners with
contextual CTA behavior
* Improved partner-billing detection to drive billing UI and
invoice/plan availability

* **Tests**
* Extensive new test coverage for billing UI, partner-managed fallbacks,
banners, icons, and related flows
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-04-23 12:17:24 +10:00
Ignacio Dobronich 18e21a410b fix: adjust charge breakdown for prorated credits and subtotal calculation (#45075)
Reorders the itemized charge breakdown in the subscription upgrade
preview dialog to: Plan → Tax → Subtotal → Unused Time → Credits. Also
appends a "Includes proportional tax if applicable" note to the unused
time tooltip when tax is being applied, so users understand the prorated
credit already reflects tax.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Reorganized proration breakdown display order in subscription plan
updates for improved clarity.
* Enhanced unused time charge tooltip to conditionally include tax
information.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-21 14:11:57 -03:00
Ignacio DobronichandJoshen Lim 35478cf47b feat: expose tax in upcoming invoice (#44732)
Display tax information in the upcoming invoice breakdown.
- Show a "Tax" line item with amount and rate tooltip when tax is
successfully calculated
- Show a warning row when tax estimation fails, prompting users to
verify their billing address
- Update Current Costs and Projected Costs tooltips to indicate whether
tax is included or could not be estimated

## Test plan

- [ ]  Verify tax row appears with correct amount
when `tax_status` is `calculated`
- [ ]  Verify tax rate percentage shows in the tooltip (e.g., "Estimated
tax at 10%...")
- [ ]  Verify warning row appears when `tax_status` is `failed`
- [ ]  Verify no tax row appears when `tax_status` is `not_applicable`
- [ ]  Verify "Applicable tax included." appears in Current/Projected
Costs tooltips when tax is calculated
- [ ]  Verify "Tax could not be estimated and is not included." appears
in tooltips when tax fails

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Upcoming invoices now include tax details and a tax status.
* Billing breakdown shows projected tax and conditionally displays
projected totals excluding tax when applicable.
* If tax estimation fails, a “Tax — Could not be estimated” row appears
and totals reflect the failure.
* Added "Stripe Projects" as a billing partner option and clarified that
projected amounts may be explicitly null.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-04-15 12:34:28 -03:00
oniani1andGildas Garcia 595061e20c fix(studio): show empty org warning when there are no active projects (#44870)
Closes #44872

The "Empty organization" admonition in the subscription upgrade dialog
checks `.length === 5` instead of `.length === 0`. The warning text says
"This organization has no active projects" but only shows for orgs with
exactly 5 active projects.

Introduced in #44494 (b9e83b25).

The adjacent `.length === 1` check for the single-project note is
correct, confirming this is a count comparison that should be `0`.

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-04-15 09:45:15 +02:00
Ignacio Dobronich 69e00c6bbc feat: validate and save tax id using the customer endpoint (#44682)
## Summary

Reorder AddPaymentMethodForm and PaymentMethodSelection to use a dry run
validation → Stripe payment setup → real update flow:

- Validate address and tax ID via `dry_run: true` before touching Stripe
- Proceed with Stripe payment method creation / 3DS only if validation
passes
- Persist the customer profile update with dry run disabled after Stripe
succeeds
- Add `dry_run` support
to `useOrganizationCustomerProfileUpdateMutation`
- Add `getFormValues()` to `PaymentMethodElementRef` to read address and
tax ID form state
- Delete the now-unused `organization-tax-id-update-mutation.ts`

## Test plan

### Adding a Payment Method

From the billing dashboard `/org/_/billing`:

- [ ]  Add a payment method with a valid tax ID: should dry-run
validate, then create the payment method via Stripe, then persist the
billing profile
- [ ]  Add a payment method with an invalid tax ID: should show a
validation error from the dry run and not proceed to Stripe payment
setup
- [ ]  Add a payment method with the "primary billing address" checkbox
unchecked: should skip the customer profile update entirely and only
create the payment method
- [ ]  Add a payment method where Stripe 3DS fails: billing profile
should not be persisted (only the dry run ran)

### Credit Top Up

- [ ]  Top up credits with a new payment method and valid tax ID: should
dry-run validate, then create the payment method, then process the
top-up
- [ ]  Top up credits with a new payment method and invalid tax ID:
should show a validation error from the dry run and not proceed to
Stripe payment method creation

### Plan Upgrade

- [ ]  Upgrade plan with a new payment method and valid tax ID: should
dry-run validate before creating the payment method
- [ ]  Upgrade plan with a new payment method and invalid tax ID: should
show a validation error and not proceed to Stripe
- [ ]  Upgrade plan with an existing payment method: should proceed
without dry-run validation
2026-04-14 13:42:34 -03:00
Ignacio Dobronich 1986739dc4 chore: increase min credit top up to 300 (#44152)
Increases the minimum credit top-up to $300.

### Testing
- Head to `/org/_/billing`
- Assert that you're not able to do a top-up for less than $300

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Updates**
* Increased the minimum credit top-up amount from 100 USD to 300 USD.
Form defaults and placeholder text updated to reflect the new minimum.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-13 12:03:36 -03:00
Ignacio DobronichandClaude Opus 4.6 cfce3c7efc refactor: save tax ID via customer update endpoint (#44728)
## Summary

- Consolidate tax ID saving into the `PUT
/organizations/{slug}/customer` endpoint instead of using a
separate `/tax-ids` endpoint


## Test plan

### Updating billing information
From the billing dashboard`/org/_/billing`:
- [ ] Manually test updating billing address + tax ID from org billing
settings - single API call should save both
- [ ] Clear the Tax ID in the org, save and assert that it has been
deleted
- [ ] Modify all the fields in the address form, including TaxID. Click
"Cancel" and assert that everything has returned to the previous values.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Billing address and tax ID updates are now sent in a single update
operation.
* Error messaging for billing updates consolidated into a single failure
notification.
* Tax ID handling clarified: you can clear tax ID explicitly or leave it
unchanged; omitting address fields no longer overwrites existing
address.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:49:57 -03:00
kemal.earth fe67f11190 fix(studio): spacing on pricing table header (#44676)
## 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?

Missing a `w-full` to apply `justify-between`. 

| Before | After |
|--------|--------|
| <img width="894" height="98" alt="Screenshot 2026-04-08 at 17 05 26"
src="https://github.com/user-attachments/assets/c3c2cfe3-0280-4772-bbad-9570b5595981"
/> | <img width="897" height="101" alt="Screenshot 2026-04-08 at 17 05
18"
src="https://github.com/user-attachments/assets/36b65fc0-bb9c-43c4-a6da-670c753f846a"
/> |






<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Style
* Adjusted the subscription plan panel header to span the full available
width.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-08 17:24:10 +01:00
Charis 205cbe7d26 chore(studio}: enforce import order, remove bare import specifiers (#44585) 2026-04-07 20:34:10 -04:00
Ignacio Dobronich f6eb9a024e feat: refresh tax preview on address change (#44470)
## Summary

- Passes billing address and tax ID from the payment form to the
subscription preview endpoint, so taxes are recalculated live as the
user updates their details
- Debounces address/tax ID changes (1s) in `NewPaymentMethodElement` to
avoid excessive API calls while typing
- Decouples the preview refetch from the payment form's mount state -
uses `keepPreviousData` so the form stays mounted and the breakdown dims
with `opacity-50` instead of unmounting/remounting during refetches.
Shimmer skeleton only shows on initial load.
- Disables the "Confirm upgrade" button while a refetch is in progress
to prevent submitting with stale tax data
- Respects the "Use address as my org's billing address" checkbox: the
preview should mirror what will actually happen - if the checkbox is
unchecked, the address won't be saved to Orb, so it shouldn't be used
for the tax estimate either. Otherwise the user sees one price and gets
charged another. The logic for this lives in `PlanUpdateSidePanel`


``` mermaid
flowchart TD
    A[User opens upgrade dialog] --> B[Fetch subscription preview]
    B --> C[Show payment form + price breakdown]

    C --> D[User edits address or tax ID]
    D -->|1s debounce| E{Use as billing address?}

    E -->|Yes| F[Re-fetch preview with new address]
    E -->|No| G[Re-fetch preview without address override]

    F --> H[Update breakdown — form stays mounted]
    G --> H

    H --> C

```

## Test plan

- [x]  Open the plan upgrade dialog, verify the payment form and
breakdown load normally on first open
- [x]  Change the billing address country - verify the breakdown dims
briefly and updates with new tax amounts without the payment form
unmounting
- [x]  Toggle the tax ID on/off and change its value - verify the
preview refreshes after ~1s debounce
- [x]  Confirm the upgrade button is disabled while the preview is
refetching
- [x]  Uncheck "Use address as my org's billing address" - verify the
preview refetches without address/tax overrides
- [x]  Re-check the checkbox - verify the preview refetches again with
the current form address
- [x] Assert that adding a new billing address in the CreditTopUp form
works and saves the address

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Payment and subscription flows now propagate billing address and tax
ID via new callbacks; subscription preview requests include these values
and preserve prior results while fetching.
* Preview updates are debounced to reduce noise; loading state disables
confirm actions and visually dims charge breakdown.

* **UX**
* Address input emits complete normalized address updates (empty second
line cleared).
  * Tax ID input emits updates and explicit clears (null).
* “Use address as my org's billing address” is now controlled and
reports changes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-07 13:02:49 -03:00
Ignacio Dobronich 41e6b66d7b feat(billing): show tax in subscription upgrade preview (#44258)
This PR moves the client-side "Charge Today" calculation to the backend
- relying on the `preview` endpoint data to show the `Charge Today`,
`Prorated Credits` and `Customer Balance` in the Subscription Upgrade
Preview.

It also includes fields for displaying Tax information in the preview,
only for enabled orgs. Do note that at the moment the Tax Preview will
not change if the address in the Subscription Preview changes, that will
be tackled in a follow-up PR.

## Changes

- Replace client-side charge calculation with backend data: The upgrade
dialog previously computed the prorated credit and total charge locally
(using subscription period timestamps and plan prices). This PR uses the
`upfront_charge` object returned by the subscription preview API
instead.
- Display itemized tax breakdown: When the backend returns tax data, the
dialog now shows a line-by-line breakdown: plan cost → subtotal (if
different) → tax (with rate %) → total charged today.
- Use `tax_status` from the subscription preview to conditionally show
tax details, and display a warning when tax calculation fails.


## Testing

### No taxes - Upgrade from Free to Paid Plan
- With a Free Org with a billing address in Canada or any other
non-enabled jurisdiction, start the upgrade to the Pro Plan
- Assert that only the Charge Today field is shown in the summary
<img width="410" height="298" alt="image"
src="https://github.com/user-attachments/assets/e8c7e12e-833d-41d5-aec3-00092b12782f"
/>

### Taxes - Upgrade Plan
- Update an Org's Orb Customer on the Free or Pro Plan with the
`automatic_tax_enabled: true` flag.
```
curl --location --request PUT 'https://api.withorb.com/v1/customers/external_customer_id/{ORG_SLUG}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: ••••••' \
--data '{
  "tax_configuration": {
    "tax_exempt": false,
    "tax_provider": "numeral",
    "automatic_tax_enabled": true
  }
}'
```
- Update the Org address to a valid taxable address, like: 
```
  "address": {
    "country": "US",
    "line1": "100 Congress Ave",
    "city": "Austin",
    "state": "TX",
    "postal_code": "78701"
  }
```
- Assert that the tax information is shown in the preview, including Tax
Rate, Prorated credits (if applicable), Customer balance (if applicable)
and the price of the intended plan.

<img width="465" height="470" alt="image"
src="https://github.com/user-attachments/assets/dd6a7e27-1708-48a8-bbf3-5435e6d582c2"
/>






<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added itemized breakdown of subscription charges, including plan cost,
unused time credits, subtotal, and applicable taxes.
  * Enhanced billing estimates with detailed tax information display.

* **Improvements**
* Updated "Charge today" calculations to reflect real-time preview data
for greater accuracy.
* Improved billing estimate UI layout and clarity with better
organization of charge details.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-06 13:24:59 -03:00
K-Dog (Kevin) b2d8772d75 chore: do not preload plan change data on page load (#44562)
The data is preloaded even though the modal is never visible
2026-04-06 09:26:02 +00:00
K-Dog (Kevin) 5ca6182d1e chore: cleanup redeemCodeEnabled flag (#44563) 2026-04-06 09:09:30 +00:00
Ignacio Dobronich 4189e76341 fix: round currency value to 2 decimal places in subscription upgrade preview (#44502)
This PR removes the `Math.round` from the `Totals` in the subscription
upgrade preview.

| Before | After |
|--------|-------|
| <img width="388" height="397" alt="image"
src="https://github.com/user-attachments/assets/f0f63ad5-c7c0-44b2-9ebc-59c9e4ad66c0"
/> | <img width="422" height="457" alt="image"
src="https://github.com/user-attachments/assets/98a7f69f-429a-42eb-98ce-20de4974c29e"
/> |
| <img width="563" height="401" alt="image"
src="https://github.com/user-attachments/assets/083942f5-90b2-4c91-b195-4526694e365d"
/> | <img width="766" height="467" alt="image"
src="https://github.com/user-attachments/assets/854e127d-db45-48d4-b3a9-fdb010748f71"
/> |

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved precision of billing calculations in subscription plans, with
monthly invoice estimates and plan totals now displaying more accurate
currency amounts.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-02 17:22:50 -03:00
Kanishk Dudeja be3737d9d0 feat(billing): use Stripe AddressElement for billing address form (#44105)
### Summary

This PR refactors the billing address form to use Stripe AddressElement
on both the org billing page and the missing-address modal, adding
Google Maps autocomplete and country-aware state/province inputs.

### Testing

- Address element renders on org billing page, autocomplete works, and
state/province options update per country.
- Existing billing address data loads correctly into the form.
  - Need to verify this with invalid country/state as well.
- Save enables only when the form is dirty after editing address or tax
ID fields.
- Cancel restores both address and tax ID to the original values.
- Submitting with missing required address fields shows a validation
toast.
- Tax ID options are filtered by the selected billing country.
- Tax-ID-only edits submit successfully without interacting with the
address form.
- Without billing write permission, address fields are read-only.
- Update billing address modal behaves the same as the org billing page.
- Address element appearance looks correct in both light and dark mode.
- Payment method form remains unchanged and still uses floating labels.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Billing form now uses Stripe Address Element via Stripe Elements with
an embedded custom font and theme-aware appearance; tax-ID entry remains
separate.

* **Bug Fixes**
* Stronger address validation and submit gating, improved dirty-state
tracking, explicit save confirmation and reset behavior, and clearer
error toasts on update failures.

* **Tests**
* Expanded tests covering hook behavior, address element validation,
submit gating, payloads, reset, and permission scenarios.

* **Style**
  * Adjusted billing email form spacing/layout.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-01 15:41:54 +05:30
4a0bb36ca8 style: require sorted imports in studio/components (#44408)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-04-01 10:22:37 +02:00
TheOtherBrian1andGildas Garcia 7259d10053 Fixes Typo in Spend Cap Modal (#44319)
## 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?

Fixes typo in Dashboard

## What is the current behavior?

In the [Billing
Dashboard](https://supabase.com/dashboard/org/_/billing), when one
updates the spend cap:
<img width="2376" height="502" alt="CleanShot 2026-03-29 at 14 52 01@2x"
src="https://github.com/user-attachments/assets/5169fc01-cf78-4450-9184-7d7d6a28b000"
/>

The pop-out modal has a typo (states "includedthen" instead of
"included, then"):
<img width="1182" height="1408" alt="CleanShot 2026-03-29 at 14 52
17@2x"
src="https://github.com/user-attachments/assets/53622f29-cc02-4138-aa83-4e098d31d1a2"
/>

## What is the new behavior?

Updated the line:
```jsx
<p className="text-xs pl-4">{item.plans['pro']}</p>
```

to
```jsx
<p className="text-xs pl-4">
  {Array.isArray(item.plans['pro'])
    ? item.plans['pro']?.join(', ')
    : item.plans['pro']}
</p>
```

Fixed the issue:
<img width="1302" height="1072" alt="CleanShot 2026-03-29 at 15 27
30@2x"
src="https://github.com/user-attachments/assets/722056c8-7b62-4993-83bb-a2ed4cbc5264"
/>

## Additional context

[A user reported the
error](https://supabase.frontapp.com/open/msg_32qr4hpa?key=RjpHZRymA4HTNLMFa-PQ6l_Ne7L66x8A)

The file containing pricing data
"[packages/shared-data/pricing.ts](https://github.com/supabase/supabase/blob/7d7de475ecf31f95d37199456482b665c80aadc8/packages/shared-data/pricing.ts#L125)"
has the following JS object:
```js
// example problematic entry
plans: { 
    //rest of object
    pro: ['8 GB disk size per project included', 'then $0.125 per GB'],
    //rest of object
},
...
// some other entry
plans: {
    //rest of object
    pro: false,
    //rest of object
}
...
```

The relevant content in the Dashboard is an array with two entries:
> ['8 GB disk size per project included', 'then $0.125 per GB']

The [modal
file](https://github.com/supabase/supabase/blob/7d7de475ecf31f95d37199456482b665c80aadc8/apps/studio/components/interfaces/Organization/BillingSettings/CostControl/SpendCapSidePanel.tsx#L174)
deconstructs it within the following element:
```jsx
{usageItems.map((item: any) => {
  return (
    <Table.tr key={item.title}>
      <Table.td>
        <p className="text-xs pl-4">{item.title}</p>
      </Table.td>
      <Table.td>
        <p className="text-xs pl-4">{item.plans['pro']}</p> <!--------RELEVANT LINE-->
      </Table.td>
    </Table.tr>
  )
})}
```

It doesn't bother to separate entries in the array, so the element just
concatenates the two entries without any spacing.

---------

Co-authored-by: Gildas Garcia <1122076+djhi@users.noreply.github.com>
2026-03-31 09:39:48 +02:00
Pamela Chia e09a663292 fix(billing): clarify service restriction reset delay after billing cycle (#44122)
## Summary

Customers were upgrading to Pro to clear service restrictions, unaware
that restrictions aren't lifted immediately when the billing cycle
resets — there's a delay. This adds a clarifying note to both the docs
FAQ and the Studio restricted alert so users know what to expect.

Note: upgrading your plan or disabling spend cap *does* lift
restrictions immediately (unchanged). The delay only applies to the
billing-cycle-reset path for usage-limit violations.

## Changes

- `billing-faq.mdx`: Removes the implication that restrictions clear the
moment the billing period resets; adds "Note that there may be a short
delay after your billing period resets before restrictions are fully
lifted"
- `Restriction.tsx`: Updates the restricted alert to make clear that
upgrading lifts restrictions immediately, while the billing-reset path
may have a delay

## Testing

To test the Studio banner, find or create an org with
`restriction_status === 'restricted'`, or temporarily hardcode
`shownAlert = 'restricted'` in `Restriction.tsx` to preview:

- [x] Restricted alert reads clearly and distinguishes immediate
(upgrade) vs delayed (billing reset) paths
- [x] Docs FAQ answer under "How can I remove restrictions" reads
correctly with the new caveat

## Linear
- fixes GROWTH-704
2026-03-24 18:08:29 +08:00
Kanishk DudejaandIgnacio Dobronich 5d942e2a46 refactor(billing): allow GB VAT tax IDs for Isle of Man customers (#43640)
### Summary

This PR adds support for Isle of Man customers to use GB VAT tax IDs.
Isle of Man uses the UK VAT system, so Orb requires country: 'GB' for
validation - but the billing address country is IM.

- Adds an IM VAT entry to `TAX_IDS` with a new `taxCountryIso2` override
field, so the UI shows "IM VAT" while sending country: 'GB' to Orb
- Introduces `getEffectiveTaxCountry()` to resolve the correct country
code for Orb
- Introduces `resolveStoredTaxId()` to map stored Orb data back to the
correct UI entry, using billing address country to disambiguate IM vs GB
- Updates all three billing forms to use these utilities: Billing
Settings page, Add Payment Method modal and Update Billing Address modal

### Testing

#### Automated tests

I've added unit tests in this PR

#### Manual tests

You can use the following country/city/postal code combinations to test:

- Isle of Man, Douglas, IM1 2LE
- United Kingdom, Crumlin, BT29 4AA

**Billing Settings page**

- Select Isle of Man as billing country → tax ID dropdown shows "Isle of
Man - IM VAT"
- Select United Kingdom as billing country → tax ID dropdown shows
"United Kingdom - UK VAT" / "United Kingdom - GB VAT" (not "IM VAT")
- Select IM VAT, enter a valid GB VAT number, save → check network tab,
Orb receives country: 'GB'
- Reload page for an IM customer with existing tax ID → "IM VAT" is
pre-selected (not "UK VAT")
- Reload page for a GB customer with existing tax ID → "UK VAT" is
pre-selected (no regression)
- Change country from IM to GB → available tax IDs update, IM VAT no
longer shown

**Add Payment Method modal**

- Open modal for an IM customer with existing tax ID → "IM VAT" is
pre-selected
- Check "I'm purchasing as a business", select Isle of Man in Stripe
address → tax ID dropdown shows "IM VAT"
- Check "I'm purchasing as a business", select United Kingdom in Stripe
address → tax ID dropdown shows "UK VAT" / "GB VAT"
- Submit with IM VAT → check network tab, tax ID is saved with country:
'GB'
- Open modal for a GB customer → no regression, "UK VAT" shown as before

**Update Billing Address modal** 

Appears for paid orgs missing a billing address

- Open modal for an IM customer with existing tax ID → "IM VAT" is
pre-selected
- Open modal for a GB customer with existing tax ID → "UK VAT" is
pre-selected
- Fill in IM address + IM VAT and save → saves correctly, modal closes

---------

Co-authored-by: Ignacio Dobronich <ignacio@dobronich.com>
2026-03-20 21:48:56 +05:30
Ivan VasilovandJoshen Lim 9fa96977be chore: Minor prettier fixes (#43849)
This PR fixes some prettier issues:
- Bump and unify all prettier versions to 3.7.3 across teh whole repo
- Bump the SQL prettier plugin
- When running `test:prettier`, check `mdx` files also
- Run the new prettier format on all files

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-03-17 11:17:42 +01:00
Kanishk DudejaandIgnacio Dobronich 83592b1932 feat(billing): show billing address modal for paid orgs with missing address (#43480)
### Summary

This PR adds a dismissable modal that prompts paid org users to fill in
their billing address. We need billing addresses for tax compliance and
the existing banner hasn't been as effective (~10k orgs still missing).

The modal shows on page load when all of these are true:

- ConfigCat flag `enableBillingAddressModal` is on
- Org is on a paid plan (not free)
- Org does not have billing address set
- Org is not partner-managed
- User has BILLING_WRITE permission on stripe.customer

The modal can be dismissed via the close button, but re-opens on every
page navigation.

Once the user saves a valid address, the organizations query is
invalidated and organization_missing_address flips to false - the modal
stops appearing permanently.

<img width="1256" height="703" alt="Screenshot 2026-03-05 at 4 22 11 PM"
src="https://github.com/user-attachments/assets/57e7d1b8-b3b6-4366-ad23-60910a0defe8"
/>

### Testing

#### Automated Tests

I've added unit tests in this PR

#### Manual testing

Manual test cases:

- Free org - modal does not appear
- Partner-managed org - modal does not appear
- User with "developer role" modal does not appear
- Configcat Flag disabled - modal does not appear
- Dismiss modal, navigate to another page - modal re-opens
- Fill form and save - modal closes and does not reappear
- API failure loading billing data - shows error state with Retry button

---------

Co-authored-by: Ignacio Dobronich <ignacio@dobronich.com>
2026-03-13 09:33:09 -03:00