Refine top section home new (#38802)

* refine activity

* make component

* Smol fix

* Nit

* add group

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Saxon FletcherandJoshen Lim authored and GitHub committed 2025-09-18 19:46:50 +10:00
1 parent 6cbc8b174b
commit dc41cfd7e1
3 files changed
+108 -69

No files matched your search

@@ -1,9 +1,9 @@
import dayjs from 'dayjs'
import { GitBranch } from 'lucide-react'
import Link from 'next/link'
import { Archive, Database, GitBranch } from 'lucide-react'
import { useMemo } from 'react'
import { useParams } from 'common'
import { SingleStat } from 'components/ui/SingleStat'
import { useBranchesQuery } from 'data/branches/branches-query'
import { useBackupsQuery } from 'data/database/backups-query'
import { useMigrationsQuery } from 'data/database/migrations-query'
@@ -55,17 +55,15 @@ export const ActivityStats = () => {
return (
<div className="@container">
<div className="grid grid-cols-2 xl:flex xl:gap-10 gap-4 flex-wrap">
<div className="block">
<p className="heading-meta text-foreground-light mb-1">Status</p>
<ServiceStatus />
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 flex-wrap">
<ServiceStatus />
<Link className="block" href={`/project/${ref}/database/migrations`}>
<h4 className="heading-meta text-foreground-light mb-1">Last migration</h4>
<div className={cn('h-[34px] flex items-center capitalize-sentence')}>
{isLoadingMigrations ? (
<SingleStat
href={`/project/${ref}/database/migrations`}
icon={<Database size={18} strokeWidth={1.5} className="text-foreground" />}
label={<span>Last migration</span>}
value={
isLoadingMigrations ? (
<Skeleton className="h-6 w-24" />
) : latestMigration ? (
<TimestampInfo
@@ -75,15 +73,16 @@ export const ActivityStats = () => {
/>
) : (
<p className="text-foreground-lighter">No migrations</p>
)}
</div>
</Link>
)
}
/>
<Link className="block" href={`/project/${ref}/database/backups/scheduled`}>
<h4 className="heading-meta text-foreground-light mb-1">Last backup</h4>
<div className={cn('h-[34px] flex items-center capitalize-sentence')}>
{isLoadingBackups ? (
<SingleStat
href={`/project/${ref}/database/backups/scheduled`}
icon={<Archive size={18} strokeWidth={1.5} className="text-foreground" />}
label={<span>Last backup</span>}
value={
isLoadingBackups ? (
<Skeleton className="h-6 w-24" />
) : backupsData?.pitr_enabled ? (
<p>PITR enabled</p>
@@ -95,25 +94,26 @@ export const ActivityStats = () => {
/>
) : (
<p className="text-foreground-lighter">No backups</p>
)}
</div>
</Link>
)
}
/>
<Link className="block" href={`/project/${ref}/branches`}>
<h4 className="heading-meta text-foreground-light mb-1">
{isDefaultProject ? 'Recent branch' : 'Branch Created'}
</h4>
<div className="text-foreground truncate h-[34px] flex items-center capitalize-sentence">
{isLoadingBranches ? (
<SingleStat
href={`/project/${ref}/branches`}
icon={<GitBranch size={18} strokeWidth={1.5} className="text-foreground" />}
label={<span>{isDefaultProject ? 'Recent branch' : 'Branch Created'}</span>}
value={
isLoadingBranches ? (
<Skeleton className="h-6 w-24" />
) : isDefaultProject ? (
<div className="flex items-center gap-2">
<GitBranch size={16} strokeWidth={1.5} className="text-foreground-lighter" />
<p className={cn('truncate', !latestNonDefaultBranch && 'text-foreground-lighter')}>
{latestNonDefaultBranch?.name ?? 'No branches'}
</p>
</div>
<p
className={cn(
'truncate',
!latestNonDefaultBranch && 'text-foreground-lighter truncate'
)}
>
{latestNonDefaultBranch?.name ?? 'No branches'}
</p>
) : currentBranch?.created_at ? (
<TimestampInfo
className="text-base"
@@ -122,9 +122,9 @@ export const ActivityStats = () => {
/>
) : (
<p className="text-foreground-lighter">Unknown</p>
)}
</div>
</Link>
)
}
/>
</div>
</div>
)
@@ -1,9 +1,9 @@
import { AlertTriangle, CheckCircle2, ChevronDown, ChevronRight, Loader2 } from 'lucide-react'
import { AlertTriangle, CheckCircle2, ChevronRight, Loader2 } from 'lucide-react'
import Link from 'next/link'
import { useState } from 'react'
import { PopoverSeparator } from '@ui/components/shadcn/ui/popover'
import { useParams } from 'common'
import { SingleStat } from 'components/ui/SingleStat'
import { useBranchesQuery } from 'data/branches/branches-query'
import { useEdgeFunctionServiceStatusQuery } from 'data/service-status/edge-functions-status-query'
import {
@@ -12,14 +12,7 @@ import {
} from 'data/service-status/service-status-query'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import {
Button,
InfoIcon,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
cn,
} from 'ui'
import { InfoIcon, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_, cn } from 'ui'
/**
* [Joshen] JFYI before we go live with this, we need to revisit the migrations section
@@ -85,7 +78,6 @@ const StatusIcon = ({
export const ServiceStatus = () => {
const { ref } = useParams()
const { data: project } = useSelectedProjectQuery()
const [open, setOpen] = useState(false)
const {
projectAuthAll: authEnabled,
@@ -262,27 +254,29 @@ export const ServiceStatus = () => {
: 'Healthy'
return (
<Popover_Shadcn_ modal={false} open={open} onOpenChange={setOpen}>
<PopoverTrigger_Shadcn_ asChild>
<Button
type="outline"
className="text-base h-auto px-2"
iconRight={<ChevronDown size={14} strokeWidth={1.5} />}
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_>
<SingleStat
icon={
isLoadingChecks || anyComingUp || isMigrationLoading ? (
<Loader2 className="animate-spin ml-1" size={12} strokeWidth={1.5} />
) : (
<div
className={cn(
'w-2 h-2 rounded-full ml-1.5',
allServicesOperational ? 'bg-brand' : 'bg-warning'
)}
/>
)
<div className="grid grid-cols-3 gap-1">
{services.map((service, index) => (
<div
key={`${service.name}-${index}`}
className={cn(
'w-1.5 h-1.5 rounded-full',
service.isLoading || service.status === 'COMING_UP'
? 'bg-foreground-lighter animate-pulse'
: service.isHealthy
? 'bg-brand'
: 'bg-selection'
)}
/>
))}
</div>
}
>
{overallStatusLabel}
</Button>
label={<span>Health</span>}
value={<span>{overallStatusLabel}</span>}
/>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ portal className="p-0 w-56" side="bottom" align="start">
{services.map((service) => (
+45
View File
@@ -0,0 +1,45 @@
import Link from 'next/link'
import type { ReactNode } from 'react'
type SingleStatProps = {
icon: ReactNode
label: ReactNode
value: ReactNode
className?: string
href?: string
onClick?: () => void
}
export const SingleStat = ({ icon, label, value, className, href, onClick }: SingleStatProps) => {
const content = (
<div className={`group flex items-center gap-4 p-0 text-base justify-start ${className || ''}`}>
<div className="w-16 h-16 rounded-md bg-surface-75 group-hover:bg-muted border flex items-center justify-center">
{icon}
</div>
<div>
<div className="text-left heading-meta text-foreground-light">{label}</div>
<div className="text-foreground truncate h-[34px] flex items-center capitalize-sentence">
{value}
</div>
</div>
</div>
)
if (href) {
return (
<Link className="group block" href={href}>
{content}
</Link>
)
}
if (onClick) {
return (
<button className="group" onClick={onClick}>
{content}
</button>
)
}
return content
}