mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 18:35:07 +03:00
### 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.
Writing components
Where to create your components
- For components that declare the general structure and layout of a page:
/components/layouts/xxx
- For components that are tightly coupled to a specific interface:
/components/interfaces/xxx
- For components that are meant to be reusable across multiple pages:
/components/ui/xxx
- Note: We're gradually moving files out of the
to-be-cleanedfolder into the respective folders as we refactor
Component structure
- If a component has constants and utility methods that are tightly coupled to itself, keep them close to the component and enclose them in a folder with an
index.tsxas an entry point - Otherwise it can just be a file on its own
- For example:
-
components/ui - SampleComponentA - SampleComponentA.tsx - SampleComponentA.constants.ts - SampleComponentA.utils.ts - SampleComponentA.types.ts - index.ts - SampleComponentB.tsx
-
Template for building components
// Declare the prop types of your component
interface ComponentAProps {
sampleProp: string
}
// Name your component accordingly
const ComponentA = ({ sampleProp }: ComponentAProps) => {
return <div>ComponentA: {sampleProp}</div>
}
export default ComponentA