Files
supabase/apps/lite-studio/app/routes/projects.$ref.tsx
Gildas Garcia b554f58106 chore: migrate Input usages to Shadcn components (#45429)
## Problem

We want to reduce the code we ship and maintain.

## Solution

- Migrate old `Input` usage to the new Shadcn `input`

This PR focuses on:
- DevToolbar
- design-system examples
- `www` usages
- `docs` usages

## Screenshots

### Docs: OAuth Apple

Before:
<img width="613" height="508" alt="image"
src="https://github.com/user-attachments/assets/1d2d7726-cc5e-471f-a2c2-995b9d7f70ee"
/>

After:
<img width="606" height="530" alt="image"
src="https://github.com/user-attachments/assets/ca4f522f-de9c-4edf-966b-70cad5015d0c"
/>

NOTE: Also used the `DataInput` for the secret once the inputs are
filled.

### Docs: Extensions

Before:
<img width="596" height="161" alt="image"
src="https://github.com/user-attachments/assets/16d2f548-90dc-4987-9954-7c47ac58e76e"
/>

After:
<img width="604" height="227" alt="image"
src="https://github.com/user-attachments/assets/62c74102-98c6-47a6-b19b-cbf67dfad68f"
/>

### WWW: Blog search
Before:
<img width="971" height="417" alt="image"
src="https://github.com/user-attachments/assets/efb0307e-60b5-4d8f-9823-c8b8996cdf32"
/>

After:
<img width="964" height="403" alt="image"
src="https://github.com/user-attachments/assets/2dc0decd-b773-4bc6-9a72-c43f352f8cbf"
/>

### WWW: Blog author search

Before:
<img width="953" height="337" alt="image"
src="https://github.com/user-attachments/assets/1f629704-ab7d-4e4b-878e-1838ab16037f"
/>

After:
<img width="1028" height="341" alt="image"
src="https://github.com/user-attachments/assets/d8d54dcb-3c00-46ea-b97f-55c16cda917f"
/>

### WWW: Assistant demo
Before:
<img width="421" height="715" alt="image"
src="https://github.com/user-attachments/assets/bcc4a591-d53c-4202-acf8-2b3d6cfd52d2"
/>

After:
<img width="435" height="731" alt="image"
src="https://github.com/user-attachments/assets/8a57c5da-5c9e-474d-a89e-2835d3498aef"
/>

### WWW: Integrations
Before:
<img width="740" height="599" alt="image"
src="https://github.com/user-attachments/assets/cf3d3d8a-b247-4e20-b47d-11976ca49c57"
/>

After:
<img width="911" height="492" alt="image"
src="https://github.com/user-attachments/assets/dcb5b6e8-f4e2-4801-b390-352390a0b486"
/>

### WWW: features
Before:
<img width="1098" height="491" alt="image"
src="https://github.com/user-attachments/assets/ea3645c5-df03-4eb9-b28c-41018e01c41e"
/>

After:
<img width="976" height="479" alt="image"
src="https://github.com/user-attachments/assets/4439a38e-6342-42cd-a859-1e599a8cf0f4"
/>

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

* **Style**
* Adjusted input widths and spacing for more consistent search and form
layouts.

* **Refactor**
* Standardized input components across apps and docs, and reimplemented
search controls as composed input groups with dedicated icon/action
areas.

* **Chores**
* Removed a deprecated legacy input variant along with its legacy styles
and tests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-05 08:09:31 +02:00

203 lines
6.4 KiB
TypeScript

import { useState } from 'react'
import { useParams } from 'react-router'
import {
Badge,
Button,
Card,
Checkbox,
Input_Shadcn_ as Input,
Label_Shadcn_ as Label,
Separator,
Switch,
Tabs_Shadcn_ as Tabs,
TabsContent_Shadcn_ as TabsContent,
TabsList_Shadcn_ as TabsList,
TabsTrigger_Shadcn_ as TabsTrigger,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import {
PageHeader,
PageHeaderDescription,
PageHeaderMeta,
PageHeaderSummary,
PageHeaderTitle,
} from 'ui-patterns/PageHeader'
import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader'
import type { Route } from './+types/projects.$ref'
export function meta({}: Route.MetaArgs) {
return [
{ title: 'Project Overview' },
{ name: 'description', content: 'Manage your Supabase project' },
]
}
export default function ProjectPage() {
const { ref } = useParams()
const [loading, setLoading] = useState(false)
const [enableRls, setEnableRls] = useState(true)
return (
<div className="py-8 space-y-8">
<PageHeader>
<PageHeaderMeta>
<PageHeaderSummary>
<PageHeaderTitle>{`Project: ${ref}`}</PageHeaderTitle>
<PageHeaderDescription>
Manage your project settings and resources
</PageHeaderDescription>
</PageHeaderSummary>
</PageHeaderMeta>
</PageHeader>
<Admonition
type="default"
title="Getting started"
description="This is a lite version of the Supabase Studio. Explore the tabs below to manage your project."
/>
<Tabs defaultValue="overview">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="database">Database</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
<TabsContent value="overview" className="space-y-6 pt-4">
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<StatusCard title="Database" status="healthy" description="PostgreSQL 15.4" />
<StatusCard title="API" status="healthy" description="REST & GraphQL" />
<StatusCard title="Auth" status="warning" description="3 providers active" />
</div>
<Card className="p-6 space-y-4">
<h3>Quick Actions</h3>
<Separator />
<div className="flex flex-wrap gap-3">
<Button type="primary">New Table</Button>
<Button type="default">SQL Editor</Button>
<Button type="default">View Logs</Button>
<Button
type="outline"
loading={loading}
onClick={() => {
setLoading(true)
setTimeout(() => setLoading(false), 2000)
}}
>
Refresh Status
</Button>
</div>
</Card>
{loading && (
<div className="space-y-2">
<ShimmeringLoader />
<ShimmeringLoader className="w-3/4" />
<ShimmeringLoader className="w-1/2" />
</div>
)}
</TabsContent>
<TabsContent value="database" className="space-y-6 pt-4">
<Card className="p-6 space-y-4">
<h3>Tables</h3>
<Separator />
<div className="space-y-3">
{['users', 'posts', 'comments'].map((table) => (
<div
key={table}
className="flex items-center justify-between p-3 rounded-md border"
>
<div className="flex items-center gap-3">
<span className="font-mono text-sm">{table}</span>
<Badge variant="default">public</Badge>
</div>
<Button type="text" size="tiny">
View
</Button>
</div>
))}
</div>
</Card>
<Admonition
type="warning"
title="Row Level Security"
description="Some tables do not have RLS enabled. Consider enabling it for production."
/>
</TabsContent>
<TabsContent value="settings" className="space-y-6 pt-4">
<Card className="p-6 space-y-6">
<h3 className="text-lg font-medium">Project Settings</h3>
<Separator />
<div className="space-y-4">
<div className="grid gap-2">
<Label htmlFor="project-name">Project Name</Label>
<Input id="project-name" placeholder="my-project" defaultValue={ref} />
</div>
<div className="grid gap-2">
<Label htmlFor="project-url">Project URL</Label>
<Input
id="project-url"
placeholder="https://xyz.supabase.co"
disabled
defaultValue={`https://${ref}.supabase.co`}
/>
</div>
<div className="flex items-center space-x-2">
<Switch
id="enable-rls"
checked={enableRls}
onCheckedChange={(checked) => setEnableRls(checked)}
/>
<Label htmlFor="enable-rls">Enable RLS by default on new tables</Label>
</div>
<div className="flex items-center gap-3">
<Checkbox id="confirm" />
<Label htmlFor="confirm">
I understand that changing these settings may affect running services
</Label>
</div>
</div>
<div className="flex gap-3">
<Button type="primary">Save Changes</Button>
<Button type="default">Cancel</Button>
</div>
</Card>
</TabsContent>
</Tabs>
</div>
)
}
function StatusCard({
title,
status,
description,
}: {
title: string
status: 'healthy' | 'warning' | 'error'
description: string
}) {
const badgeVariant =
status === 'healthy' ? 'success' : status === 'warning' ? 'warning' : 'destructive'
return (
<Card className="p-4 space-y-2">
<div className="flex items-center justify-between">
<span className="font-medium">{title}</span>
<Badge variant={badgeVariant}>{status}</Badge>
</div>
<p className="text-sm text-foreground-light">{description}</p>
</Card>
)
}