From cecb3281201d6990437ba01bf4518c0ba3598cc2 Mon Sep 17 00:00:00 2001
From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com>
Date: Wed, 2 Sep 2026 09:32:36 +0100
Subject: [PATCH] feat(studio): clean up free tier upgrade box (#49851)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## 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?
Small update of the Projects overview UI to resolve the competing CTA's
as well as alignment. Open to tweak a little more here.
| Before | After |
|--------|--------|
| |
|
## Summary by CodeRabbit
* **Style**
* Refined the plan usage card layout with larger metric values and
cleaner labels.
* Added dividers between usage metrics for improved readability.
* Simplified card and loading-state styling by removing unnecessary
borders, backgrounds, and padding.
* Updated the upgrade button’s visual treatment.
---
.../interfaces/ProjectHome/PlanUsageCard.tsx | 68 ++++++-------------
1 file changed, 20 insertions(+), 48 deletions(-)
diff --git a/apps/studio/components/interfaces/ProjectHome/PlanUsageCard.tsx b/apps/studio/components/interfaces/ProjectHome/PlanUsageCard.tsx
index 740ff099c64..2b9b91e3ce3 100644
--- a/apps/studio/components/interfaces/ProjectHome/PlanUsageCard.tsx
+++ b/apps/studio/components/interfaces/ProjectHome/PlanUsageCard.tsx
@@ -14,7 +14,6 @@ type MetricConfig = {
key: PricingMetric
label: string
unit: MetricUnit
- /** Anchor id of the matching section on the org usage page. */
anchor: string
}
@@ -40,26 +39,15 @@ const METRICS: MetricConfig[] = [
},
]
-const formatGigabytes = (value: number) => {
- if (value === 0) return '0 GB'
- if (value < 1) return `${(value * 1000).toFixed(0)} MB`
- return `${value.toFixed(value < 10 ? 2 : 1)} GB`
-}
-
-const formatGigabyteLimit = (limit: number) => {
- if (limit < 1) return `${(limit * 1000).toFixed(0)} MB`
- return `${limit} GB`
-}
-
-// Show counts in full with thousands separators (e.g. `50,000`) rather than abbreviated
-// (`50k`), to match the pricing page and avoid ambiguity around plan limits.
const formatCount = (value: number) => value.toLocaleString()
-const formatValue = (value: number, unit: MetricUnit) =>
- unit === 'gigabytes' ? formatGigabytes(value) : formatCount(value)
-
-const formatLimit = (limit: number, unit: MetricUnit) =>
- unit === 'gigabytes' ? formatGigabyteLimit(limit) : formatCount(limit)
+const formatUsagePair = (value: number, limit: number, unit: MetricUnit) => {
+ if (unit === 'count') return { value: formatCount(value), limit: formatCount(limit) }
+ if (limit < 1) {
+ return { value: (value * 1000).toFixed(0), limit: `${(limit * 1000).toFixed(0)} MB` }
+ }
+ return { value: value === 0 ? '0' : value.toFixed(value < 10 ? 2 : 1), limit: `${limit} GB` }
+}
const RING_RADIUS = 7
const RING_CIRCUMFERENCE = 2 * Math.PI * RING_RADIUS
@@ -113,8 +101,6 @@ const ProgressRing = ({
)
}
-// The upgrade CTA surface this card represents. Used as the telemetry `source` +
-// `placement` value. Kept as a constant so the tracking stays explicit.
const PLACEMENT = 'org_projects_list'
const CompactMetricRow = ({
@@ -131,26 +117,25 @@ const CompactMetricRow = ({
const ratio = limit > 0 ? current / limit : 0
const isOver = limit > 0 && current >= limit
const isApproaching = limit > 0 && ratio >= 0.8 && !isOver
+ const formatted = formatUsagePair(current, limit, config.unit)
return (
-
Current billing cycle
@@ -222,11 +193,12 @@ export const PlanUsageCard = () => {