Commit Graph
11 Commits
Author SHA1 Message Date
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
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
Charis 205cbe7d26 chore(studio}: enforce import order, remove bare import specifiers (#44585) 2026-04-07 20:34:10 -04: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
Kanishk Dudeja d37de74cba feat(billing): show billing address modal to users other than owners/admins (#44132)
### Summary

This PR updates the billing address required modal so it also shows for
users with billing read access but without billing write access, such as
developers and users with read-only acess.

For users with BILLING_WRITE, the existing blocking behavior remains in
place:

- the modal has no visible close button
- it closes only after a successful billing address update

For users with BILLING_READ but not BILLING_WRITE, the modal now:

- the modal includes a visible close button
- no editable billing form is shown
- the copy tells the user to ask an organization administrator or owner
to update the billing address

<img width="1280" height="626" alt="Screenshot 2026-03-24 at 7 18 49 PM"
src="https://github.com/user-attachments/assets/ddc5e90d-c7d8-4d67-a138-59a5a5baf71b"
/>

### Manual testing

#### Admins/owners

1. As a user with BILLING_WRITE, open an org that is missing a billing
address.
2. Confirm the modal appears with the billing address form.
3. Confirm there is no visible close button.
4. Submit a valid billing address and verify the modal closes after a
successful save.

For testing whether an update successfully closes the modal, you can:

-  You can create a free org without a billing address
- You will need to tweak this logic (on the frontend)

```
const shouldShow = Boolean(
  IS_PLATFORM &&
  // showMissingAddressModal &&
  org &&
  // org.plan.id !== 'free' &&
  org.organization_missing_address &&
  !org.billing_partner &&
  permissionsLoaded &&
  canViewModal
)
```

- Tweak the backend logic which computes `organization_missing_address`
to exclude free orgs

#### Developers/users with readp-only access

1. As a user with BILLING_READ but not BILLING_WRITE, open an org that
is missing a billing address.
2. Confirm the modal appears with informational copy only and no
editable form.
3. Click the close button and verify the modal dismisses.
2026-03-25 01:58:47 +05:30
Kanishk DudejaandJoshen Lim c55908bbf0 chore(billing): make update billing address modal non-dismissable (#44127)
### Summary

This PR removes the visible close button from the billing address
required modal to make it non dismissable, since the majority of users
on paid orgs are still not filling their billing address.

The modal already prevents dismissal via Esc and outside/backdrop
interaction, and this change preserves that behavior. The existing
submit flow is unchanged, so the modal still closes after a successful
billing address update.

### Manual testing:

1. Open Studio in a state where the billing address required modal
appears.
2. Confirm the top-right close button is no longer shown.
3. Press Esc and verify the modal remains open.
4. Click outside the modal / on the backdrop and verify the modal
remains open.
5. Submit a valid billing address and verify the modal closes after a
successful save.

For testing whether an update successfully closes the modal, you can:

- You can create a free org without a billing address
- You will need to tweak this logic (on the frontend)

```
const shouldShow = Boolean(
  IS_PLATFORM &&
  // showMissingAddressModal &&
  org &&
  // org.plan.id !== 'free' &&
  org.organization_missing_address &&
  !org.billing_partner &&
  permissionsLoaded &&
  canBillingWrite
)
```

- Tweak the backend logic which computes `organization_missing_address`
to exclude free orgs

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-03-24 18:25:58 +05:30
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
Ivan Vasilov fd4a546db6 fix: Fix Studio breaking for Team users (#43759)
This PR fixes an issue which caused the Studio to break for Team users.
It was caused because non-boolean value was passed to `enabled`.
2026-03-13 19:29:49 +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