Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 30 additions & 33 deletions apps/web/src/features/earn/components/earn-page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@workspace/ui/components/tabs"
import { Heading, Text } from "@workspace/ui/components/text"
import { AppShell } from "@workspace/ui/components/app-shell"
import { PageHeader } from "@workspace/ui/components/page-header"
import { Navbar } from "../../../ui/Navbar"
import { PortfolioTab } from "./portfolio/portfolio-tab"
import { DiscoverTab } from "./discover/discover-tab"
Expand All @@ -8,38 +9,34 @@ import { DistributionsTab } from "./distributions/distributions-tab"

export function EarnPage() {
return (
<div className="flex min-h-svh flex-col bg-background text-foreground">
<Navbar variant="app" />
<div className="mx-auto w-full max-w-260 px-4 pb-16 pt-8 sm:px-6 lg:px-12">
<header className="mb-7">
<h1 className="text-22 font-semibold tracking-tight">Earn</h1>
<p className="mt-1 text-sm text-muted-foreground">
Stake SO4 and buy GLV or GM to earn rewards
</Text>
</header>
<AppShell navbar={<Navbar variant="app" />} maxWidth="260">
<PageHeader
title="Earn"
description="Stake SO4 and buy GLV or GM to earn rewards"
tabs={
<Tabs defaultValue="portfolio" className="gap-6">
<TabsList className="h-9">
<TabsTrigger value="portfolio">Portfolio</TabsTrigger>
<TabsTrigger value="discover">Discover</TabsTrigger>
<TabsTrigger value="additional">Additional opportunities</TabsTrigger>
<TabsTrigger value="distributions">Distributions</TabsTrigger>
</TabsList>

<Tabs defaultValue="portfolio" className="gap-6">
<TabsList className="h-9">
<TabsTrigger value="portfolio">Portfolio</TabsTrigger>
<TabsTrigger value="discover">Discover</TabsTrigger>
<TabsTrigger value="additional">Additional opportunities</TabsTrigger>
<TabsTrigger value="distributions">Distributions</TabsTrigger>
</TabsList>

<TabsContent value="portfolio">
<PortfolioTab />
</TabsContent>
<TabsContent value="discover">
<DiscoverTab />
</TabsContent>
<TabsContent value="additional">
<AdditionalOpportunitiesTab />
</TabsContent>
<TabsContent value="distributions">
<DistributionsTab />
</TabsContent>
</Tabs>
</div>
</div>
<TabsContent value="portfolio">
<PortfolioTab />
</TabsContent>
<TabsContent value="discover">
<DiscoverTab />
</TabsContent>
<TabsContent value="additional">
<AdditionalOpportunitiesTab />
</TabsContent>
<TabsContent value="distributions">
<DistributionsTab />
</TabsContent>
</Tabs>
}
/>
</AppShell>
)
}
47 changes: 23 additions & 24 deletions apps/web/src/features/faucet/components/faucet-page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Alert, AlertDescription } from "@workspace/ui/components/alert"
import { Badge } from "@workspace/ui/components/badge"
import { AppShell } from "@workspace/ui/components/app-shell"
import { Card, CardContent } from "@workspace/ui/components/card"
import { LoadingButton } from "@workspace/ui/components/loading-button"
import { NumericText } from "@workspace/ui/components/numeric"
import { Stat } from "@workspace/ui/components/stat"
import { Heading, Text } from "@workspace/ui/components/text"
import { PageHeader } from "@workspace/ui/components/page-header"
import { Text } from "@workspace/ui/components/text"
import { FAUCET_TOKENS, type FaucetTokenConfig } from "../data/tokens" // eslint-disable-line import/consistent-type-specifier-style
import { FAUCET_CONTRACT_ID } from "../lib/clients"
import { useFaucetData } from "../hooks/useFaucetData"
Expand Down Expand Up @@ -121,24 +120,25 @@ export function FaucetPage() {
const claimDisabled = !isConnected || mismatch

return (
<div className="flex min-h-svh flex-col bg-background text-foreground">
<Navbar variant="app" />
<NetworkMismatchBanner />

<div className="mx-auto w-full max-w-2xl px-4 pb-16 pt-8 sm:px-6">
{/* Header */}
<header className="mb-8">
<AppShell
navbar={<Navbar variant="app" />}
banner={<NetworkMismatchBanner />}
maxWidth="2xl"
>
<PageHeader
title={
<div className="flex items-center gap-3">
<h1 className="text-22 font-semibold tracking-tight">Testnet Faucet</h1>
<span className="inline-flex items-center gap-1.5 rounded-full border border-yellow-500/30 bg-yellow-500/10 px-2.5 py-0.5 text-11 font-medium text-yellow-600 dark:text-yellow-400">
<span className="h-1.5 w-1.5 rounded-full bg-yellow-500" />
Stellar Testnet
</Badge>
<span>Testnet Faucet</span>
</div>
<Text size="base" tone="muted" className="mt-1.5">
Claim test tokens to try trading on SO4. Tokens have no real value.
</Text>
</header>
}
description="Claim test tokens to try trading on SO4. Tokens have no real value."
metadata={
<span className="inline-flex items-center gap-1.5 rounded-full border border-yellow-500/30 bg-yellow-500/10 px-2.5 py-0.5 text-11 font-medium text-yellow-600 dark:text-yellow-400">
<span className="h-1.5 w-1.5 rounded-full bg-yellow-500" />
Stellar Testnet
</span>
}
/>

{!isTestnet ? (
<Card>
Expand Down Expand Up @@ -176,7 +176,7 @@ export function FaucetPage() {
<p className="mt-0.5 text-13 text-muted-foreground">
Receive TUSDC, TWBTC, TETH, and TXLM in a single transaction. A cooldown
applies between claims.
</Text>
</p>
</div>

{mismatch && (
Expand Down Expand Up @@ -209,7 +209,7 @@ export function FaucetPage() {
{data?.cooldownLedgers != null && data.cooldownLedgers > 0 && (
<p className="text-center text-xs text-muted-foreground">
Cooldown: {data.cooldownLedgers.toLocaleString()} ledgers between claims
</Text>
</p>
)}
</CardContent>
</Card>
Expand Down Expand Up @@ -238,7 +238,6 @@ export function FaucetPage() {
</div>
</div>
)}
</div>
</div>
</AppShell>
)
}
119 changes: 119 additions & 0 deletions apps/web/src/features/gallery/components/gallery-page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useState } from "react"
import { AppShell } from "@workspace/ui/components/app-shell"
import { Badge } from "@workspace/ui/components/badge"
import { Button } from "@workspace/ui/components/button"
import { Input } from "@workspace/ui/components/input"
import { PageHeader } from "@workspace/ui/components/page-header"
import { Separator } from "@workspace/ui/components/separator"
import { Skeleton } from "@workspace/ui/components/skeleton"
import { Slider } from "@workspace/ui/components/slider"
Expand Down Expand Up @@ -139,6 +141,123 @@ export function GalleryPage() {
<TooltipContent>A tooltip, positioned automatically.</TooltipContent>
</Tooltip>
</Section>

<Section title="AppShell">
<div className="space-y-4">
<p className="text-13 text-muted-foreground">
Constrained layout (default) — used for Pools, Earn, Referrals, Faucet
</p>
<div className="overflow-hidden rounded-lg border border-border">
<AppShell
variant="constrained"
maxWidth="full"
navbar={
<div className="flex h-10 items-center border-b border-border bg-muted/30 px-4">
<span className="text-13 font-medium text-foreground">Navbar slot</span>
</div>
}
banner={
<div className="bg-warning/10 px-4 py-2 text-13 text-warning">
Banner slot
</div>
}
>
<div className="rounded-lg border border-dashed border-border bg-muted/10 p-8 text-center text-13 text-muted-foreground">
Content area
</div>
</AppShell>
</div>

<p className="mt-4 text-13 text-muted-foreground">
Full layout — used for Trade (fills viewport)
</p>
<div className="overflow-hidden rounded-lg border border-border">
<AppShell
variant="full"
navbar={
<div className="flex h-10 items-center border-b border-border bg-muted/30 px-4">
<span className="text-13 font-medium text-foreground">Navbar slot</span>
</div>
}
>
<div className="flex flex-1 items-center justify-center rounded-lg border border-dashed border-border bg-muted/10 p-8 text-13 text-muted-foreground">
Full-viewport content area
</div>
</AppShell>
</div>
</div>
</Section>

<Section title="PageHeader">
<div className="space-y-6">
<div>
<p className="mb-2 text-13 text-muted-foreground">Minimal — title + description</p>
<div className="rounded-lg border border-border bg-muted/10 p-4">
<PageHeader title="Pools" description="Provide liquidity to SO4 GM markets." />
</div>
</div>

<div>
<p className="mb-2 text-13 text-muted-foreground">With actions slot</p>
<div className="rounded-lg border border-border bg-muted/10 p-4">
<PageHeader
title="Earn"
description="Stake SO4 and earn rewards."
actions={
<div className="flex gap-2">
<Button variant="outline" size="sm">
Filter
</Button>
<Button size="sm">Claim all</Button>
</div>
}
/>
</div>
</div>

<div>
<p className="mb-2 text-13 text-muted-foreground">With metadata + tabs slot</p>
<div className="rounded-lg border border-border bg-muted/10 p-4">
<PageHeader
title="Referrals"
description="Get fee discounts and earn up to 15% commission."
metadata={
<>
<Badge variant="success">Active</Badge>
<span className="text-13 text-muted-foreground">Tier 3</span>
</>
}
tabs={
<Tabs defaultValue="traders">
<TabsList className="h-9">
<TabsTrigger value="traders">Traders</TabsTrigger>
<TabsTrigger value="affiliates">Affiliates</TabsTrigger>
<TabsTrigger value="distributions">Distributions</TabsTrigger>
</TabsList>
</Tabs>
}
/>
</div>
</div>

<div>
<p className="mb-2 text-13 text-muted-foreground">With breadcrumbs slot</p>
<div className="rounded-lg border border-border bg-muted/10 p-4">
<PageHeader
title="Settings"
description="Manage your account settings."
breadcrumbs={
<nav className="flex items-center gap-1.5 text-13 text-muted-foreground">
<span>Home</span>
<span aria-hidden="true">/</span>
<span className="text-foreground">Settings</span>
</nav>
}
/>
</div>
</div>
</div>
</Section>
</main>
)
}
29 changes: 14 additions & 15 deletions apps/web/src/features/pools/components/pools-page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Link } from "@tanstack/react-router"
import { AppShell } from "@workspace/ui/components/app-shell"
import { PageHeader } from "@workspace/ui/components/page-header"
import { usePoolsData } from "../hooks/use-pools-data"
import { usePoolsTimeRange } from "../hooks/use-pools-time-range"
import { PoolsCard } from "./pools-card"
Expand All @@ -13,26 +15,24 @@ export function PoolsPage() {
const { markets, glvEnabled } = usePoolsData(timeRange)

return (
<div className="flex min-h-svh flex-col bg-background text-foreground">
<Navbar variant="app" />
<NetworkMismatchBanner />

<main className="mx-auto w-full max-w-320 px-4 pb-16 pt-8 sm:px-6 lg:px-8">
<header className="mb-6 flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between">
<div>
<h1 className="text-22 font-semibold tracking-tight">Pools</h1>
<p className="mt-1.5 max-w-160 text-sm text-muted-foreground">
Provide liquidity to bootstrapped SO4 GM markets on Stellar testnet.
</p>
</div>
<AppShell
navbar={<Navbar variant="app" />}
banner={<NetworkMismatchBanner />}
maxWidth="320"
>
<PageHeader
title="Pools"
description="Provide liquidity to bootstrapped SO4 GM markets on Stellar testnet."
actions={
<div className="grid grid-cols-2 gap-3 sm:flex sm:items-center">
<div className="rounded-lg border border-border bg-card px-4 py-3">
<p className="text-11 uppercase text-muted-foreground">Total pool TVL</p>
<p className="mt-1 font-mono text-lg text-foreground">{formatUsd(0)}</p>
</div>
<PoolsTimeRangeFilter value={timeRange} options={options} onChange={setTimeRange} />
</div>
</header>
}
/>

<div className="mb-5 rounded-lg border border-yellow-500/30 bg-yellow-500/10 px-4 py-3 text-sm text-yellow-700 dark:text-yellow-300">
Deposit and withdrawal transactions are disabled until liquidity seeding and oracle
Expand Down Expand Up @@ -65,7 +65,6 @@ export function PoolsPage() {
GLV vaults are hidden because GLV contracts are not deployed for this testnet.
</div>
) : null}
</main>
</div>
</AppShell>
)
}
32 changes: 14 additions & 18 deletions apps/web/src/features/referrals/components/referrals-page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from "react"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@workspace/ui/components/tabs"
import { Heading, Text } from "@workspace/ui/components/text"
import { AppShell } from "@workspace/ui/components/app-shell"
import { PageHeader } from "@workspace/ui/components/page-header"
import { useQueryClient } from "@tanstack/react-query"
import { Navbar } from "../../../ui/Navbar"
import { useTraderStats } from "../hooks/use-referrals-data"
Expand Down Expand Up @@ -46,21 +47,16 @@ export function ReferralsPage() {
const hasAffiliateCode = Boolean(affiliateCode)

return (
<div className="flex min-h-svh flex-col bg-background text-foreground">
<Navbar variant="app" />
<div className="mx-auto w-full max-w-260 px-4 pb-16 pt-8 sm:px-6 lg:px-12">
<header className="mb-8">
<h1 className="text-22 font-semibold tracking-tight">Referrals</h1>
<p className="mt-1 text-sm text-muted-foreground">
Get fee discounts and earn up to 15% commission through the SO4 referral program
</Text>
</header>

<Tabs
value={tab}
onValueChange={(v) => setTab(v as ReferralsTab)}
className="gap-6"
>
<AppShell navbar={<Navbar variant="app" />} maxWidth="260">
<PageHeader
title="Referrals"
description="Get fee discounts and earn up to 15% commission through the SO4 referral program"
tabs={
<Tabs
value={tab}
onValueChange={(v) => setTab(v as ReferralsTab)}
className="gap-6"
>
<TabsList className="h-9 w-full overflow-x-auto sm:w-fit">
<TabsTrigger value="traders">Traders</TabsTrigger>
<TabsTrigger value="affiliates">Affiliates</TabsTrigger>
Expand Down Expand Up @@ -102,7 +98,7 @@ export function ReferralsPage() {
/>
</div>
</Tabs>
</div>
</div>
</PageHeader>
</AppShell>
)
}
Loading
Loading