Skip to content
9 changes: 7 additions & 2 deletions src/features/dashboard/layouts/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { usePathname } from 'next/navigation'
import { getDashboardLayoutConfig } from '@/configs/layout'
import { useDashboard } from '@/features/dashboard/context'
import TeamBlockedIndicator from './team-blocked-indicator'

interface DashboardLayoutFooterProps {
statusBanner: React.ReactNode
Expand All @@ -20,14 +21,18 @@ export default function DashboardLayoutFooter({
: config.title.map((segment) => segment.label).join('/')

return (
<footer className="flex h-protected-footer min-h-protected-footer shrink-0 items-center justify-between gap-2 border-t bg-bg px-3 md:px-6">
<footer className="flex h-protected-footer min-h-protected-footer shrink-0 items-center gap-2 border-t bg-bg px-3 md:px-6">
<span className="min-w-0 flex-1 truncate pr-2 font-mono text-xs text-fg-tertiary uppercase md:pr-4 md:prose-label">
{'>_'}
{user.email ?? 'ANONYMOUS@UNKNOWN.COM'}
{`:${footerTitle}`}
</span>

{statusBanner}
<TeamBlockedIndicator />

{statusBanner ? (
<div className="flex flex-1 justify-end">{statusBanner}</div>
) : null}
</footer>
)
}
68 changes: 68 additions & 0 deletions src/features/dashboard/layouts/team-blocked-indicator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client'

import Link from 'next/link'
import { useMemo } from 'react'
import { PROTECTED_URLS } from '@/configs/urls'
import { useDashboard } from '@/features/dashboard/context'
import { BlockIcon } from '@/ui/primitives/icons'

function useBlockedMessage(slug: string, blockedReason: string | null) {
return useMemo(() => {
const reason = blockedReason?.toLowerCase() ?? ''

if (reason.includes('billing limit')) {
return {
text: 'Billing limit reached.',
cta: 'Update limit.',
href: PROTECTED_URLS.LIMITS(slug),
}
}

if (reason.includes('missing payment method')) {
return {
text: 'Missing payment method.',
cta: 'Add payment method.',
href: PROTECTED_URLS.BILLING(slug),
}
}

if (reason.includes('verification required')) {
return {
text: 'Verification required.',
cta: 'Add payment method.',
href: PROTECTED_URLS.BILLING(slug),
}
}

return {
text: blockedReason ?? 'Team suspended.',
cta: null,
href: null,
}
}, [slug, blockedReason])
}

export default function TeamBlockedIndicator() {
const { team } = useDashboard()

const message = useBlockedMessage(team.slug, team.blockedReason)

if (!team.isBlocked) return null

return (
<div className="inline-flex shrink-0 items-center gap-1.5 text-accent-error-highlight max-md:max-w-[50%]">
<BlockIcon className="size-4 shrink-0" />
<span className="truncate text-xs uppercase md:prose-label">
{message.text}
{message.cta && message.href && (
<>
{' '}
<Link href={message.href} className="underline">
{message.cta}
</Link>
</>
)}
</span>
</div>
)
}
2 changes: 0 additions & 2 deletions src/features/dashboard/sidebar/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ import {
} from '@/ui/primitives/sidebar'
import DashboardSurveyPopover from '../navbar/dashboard-survey-popover'
import ContactSupportDialog from '../navbar/report-issue-dialog'
import TeamBlockageAlert from './blocked-banner'

export default function DashboardSidebarFooter() {
return (
<>
<SidebarFooter>
<SidebarGroup className="!p-0">
<SidebarMenu>
<TeamBlockageAlert className="mb-2" />
<SidebarMenuItem key="github">
<SidebarMenuButton asChild tooltip="GitHub">
<Link
Expand Down
Loading