Files
Danny White ec53175b8a refactor(ui): rename text-brand to text-primary (#50564)
## What kind of change does this PR introduce?

Refactor. Follow-up to #49871.

## What is the current behavior?

Branded (green) text still uses the `text-brand` classname while the
colour comes from `--primary`.

## What is the new behavior?

**Rename-only:** `text-brand` → `text-primary` across callsites and
docs. Leftover `bg-brand` / `border-brand` alias to `brand-default`. No
intentional colour changes in this PR.

This better matches how we treat our green in other components and
props, like `variant="primary"` for green buttons.

## To test

On light mode: smoke-test that branded text still looks like #49871
(readable green, not the bright fill).

-
[Homepage](https://zone-www-dot-com-git-dnywh-depr-316-text-brand-de2380-supabase.vercel.app/):
“Scale to millions” uses `text-primary`
- [Docs
homepage](https://docs-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/docs):
branded links like “More on self-hosting” are still readable
- [Typography
docs](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/typography):
documents `text-primary`
- [Colour
usage](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/color-usage):
`text-primary` is visibly darker than `bg-brand-default` _on light mode_
- [Studio auth
providers](https://studio-staging-git-dnywh-depr-316-text-brand-to-60fa6c-supabase.vercel.app/dashboard/project/_/auth/providers):
enabled provider badge text readable; status dot stays bright green

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

* **Style**
* Updated branded text, link hover states, icons, badges, indicators,
and highlighted content across the Design System, Docs, Studio, Learn,
UI Library, and marketing experiences to use the primary theme color.
* Updated syntax highlighting and table-of-contents styling for
consistent primary-color presentation.
  * Refined brand color fallback behavior for bright fills and borders.

* **Documentation**
* Updated color-usage and typography guidance to recommend the primary
text utility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-22 16:19:03 +10:00

159 lines
6.3 KiB
TypeScript

import { useParams } from 'common'
import dayjs from 'dayjs'
import { PauseCircle } from 'lucide-react'
import Link from 'next/link'
import { Button, Card, CardContent, CardFooter } from 'ui'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { TimestampInfo } from 'ui-patterns/TimestampInfo'
import { DownloadBackupsSection } from './DownloadBackupsSection'
import { PauseDisabledState } from './PauseDisabledState'
import { ResumeProjectButton } from '@/components/interfaces/Project/ResumeProjectButton'
import { AlertError } from '@/components/ui/AlertError'
import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton'
import { useProjectPauseStatusQuery } from '@/data/projects/project-pause-status-query'
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { usePHFlag } from '@/hooks/ui/useFlag'
import { PROJECT_STATUS } from '@/lib/constants'
export interface ProjectPausedStateProps {
product?: string
}
export const ProjectPausedState = ({ product }: ProjectPausedStateProps) => {
const { ref } = useParams()
const { data: project } = useSelectedProjectQuery()
const { data: selectedOrganization } = useSelectedOrganizationQuery()
const enableProBenefitWording = usePHFlag('proBenefitWording')
const {
data: pauseStatus,
error: pauseStatusError,
isError,
isSuccess: isPauseStatusSuccess,
isPending: isLoading,
} = useProjectPauseStatusQuery({ ref }, { enabled: project?.status === PROJECT_STATUS.INACTIVE })
// null when there is no expiry (e.g. paid plans can always restore)
const restoreExpiresAt =
pauseStatus?.remaining_days_till_restore_disabled != null
? dayjs().utc().add(pauseStatus.remaining_days_till_restore_disabled, 'day').toISOString()
: null
const isFreePlan = selectedOrganization?.plan?.id === 'free'
const isRestoreDisabled = isPauseStatusSuccess && !pauseStatus.can_restore
return (
<Card className="w-full max-w-160 mx-auto">
<CardContent>
<PauseCircle size={48} strokeWidth={1} className="text-foreground-lighter shrink-0 mb-4" />
<div className="flex-1">
<div>
<h2 className="mb-4">Project "{project?.name}" is paused</h2>
<div className="text-foreground-light max-w-4xl">
{isLoading && <GenericSkeletonLoader className="mt-3" />}
{isPauseStatusSuccess && !isRestoreDisabled ? (
isFreePlan ? (
<ul className="text-sm list-disc pl-4 space-y-2">
<li>All data, including backups and storage objects, remains safe.</li>
{restoreExpiresAt ? (
<>
<li>
You can resume this project from the dashboard until{' '}
<TimestampInfo
displayAs="local"
utcTimestamp={restoreExpiresAt}
className="text-sm text-foreground"
labelFormat="DD MMM YYYY"
/>
.
</li>
<li>
After that, this project will not be resumable, but data will still be
available for download.
</li>
</>
) : (
<li>You can resume this project from the dashboard.</li>
)}
<li>
{enableProBenefitWording === 'variant-a'
? 'Upgrade to Pro to prevent pauses and unlock features like branching, compute upgrades, and daily backups.'
: 'To prevent future pauses, consider upgrading to Pro.'}
</li>
</ul>
) : (
<>
<p className="text-sm">
Your project data is safe
{restoreExpiresAt ? (
<>
{' '}
and available until{' '}
<TimestampInfo
displayAs="local"
utcTimestamp={restoreExpiresAt}
className="text-sm text-foreground"
labelFormat="DD MMM YYYY"
/>
</>
) : null}
, but inaccessible while paused.
</p>
<p className="text-sm mt-2">
Once resumed, usage will be billed by compute size and hours active.
</p>
</>
)
) : !isLoading ? (
<p className="text-sm">
All of your project's data is still intact, but your project is inaccessible while
paused.{' '}
{product !== undefined ? (
<>
Resume this project to access the{' '}
<span className="text-primary">{product}</span> page.
</>
) : !isRestoreDisabled ? (
'Resume this project and get back to building!'
) : null}
</p>
) : null}
</div>
</div>
</div>
</CardContent>
{isError && (
<AlertError
className="rounded-none border-0"
error={pauseStatusError}
subject="Failed to retrieve pause status"
/>
)}
{isPauseStatusSuccess && !isRestoreDisabled && (
<>
<CardFooter className="flex flex-wrap justify-end items-center gap-2">
<ResumeProjectButton size="tiny" variant="default" />
{isFreePlan ? (
<UpgradePlanButton source="projectPausedStateRestore" />
) : (
<Button asChild>
<Link href={`/project/${ref}/settings/general`}>View project settings</Link>
</Button>
)}
</CardFooter>
<DownloadBackupsSection />
</>
)}
{isPauseStatusSuccess && isRestoreDisabled && <PauseDisabledState />}
</Card>
)
}