feat: replace ghost buttons with underline tab bar for site navigation
Dashboard, Uptime, Funnels, and Settings now use a consistent underline tab bar with orange active indicator, matching the existing panel tab design language.
This commit is contained in:
@@ -6,6 +6,7 @@ import { listFunnels, deleteFunnel, type Funnel } from '@/lib/api/funnels'
|
||||
import { toast, PlusIcon, ArrowRightIcon, ChevronLeftIcon, TrashIcon, Button } from '@ciphera-net/ui'
|
||||
import { FunnelsListSkeleton, useMinimumLoading } from '@/components/skeletons'
|
||||
import Link from 'next/link'
|
||||
import SiteNav from '@/components/dashboard/SiteNav'
|
||||
|
||||
export default function FunnelsPage() {
|
||||
const params = useParams()
|
||||
@@ -52,14 +53,10 @@ export default function FunnelsPage() {
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-6xl mx-auto px-4 sm:px-6 py-8">
|
||||
<SiteNav siteId={siteId} />
|
||||
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<Link
|
||||
href={`/sites/${siteId}`}
|
||||
className="p-2 -ml-2 text-neutral-500 hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-white rounded-xl hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
|
||||
>
|
||||
<ChevronLeftIcon className="w-5 h-5" />
|
||||
</Link>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-neutral-900 dark:text-white">
|
||||
Funnels
|
||||
@@ -68,14 +65,12 @@ export default function FunnelsPage() {
|
||||
Track user journeys and identify drop-off points
|
||||
</p>
|
||||
</div>
|
||||
<div className="ml-auto">
|
||||
<Link href={`/sites/${siteId}/funnels/new`}>
|
||||
<Button variant="primary" className="inline-flex items-center gap-2">
|
||||
<PlusIcon className="w-4 h-4" />
|
||||
<span>Create Funnel</span>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<Link href={`/sites/${siteId}/funnels/new`}>
|
||||
<Button variant="primary" className="inline-flex items-center gap-2">
|
||||
<PlusIcon className="w-4 h-4" />
|
||||
<span>Create Funnel</span>
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{funnels.length === 0 ? (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import { useAuth } from '@/lib/auth/context'
|
||||
|
||||
import { logger } from '@/lib/utils/logger'
|
||||
import { useCallback, useEffect, useState, useMemo } from 'react'
|
||||
import { useParams, useRouter, useSearchParams } from 'next/navigation'
|
||||
@@ -34,6 +34,7 @@ import PerformanceStats from '@/components/dashboard/PerformanceStats'
|
||||
import GoalStats from '@/components/dashboard/GoalStats'
|
||||
import ScrollDepth from '@/components/dashboard/ScrollDepth'
|
||||
import Campaigns from '@/components/dashboard/Campaigns'
|
||||
import SiteNav from '@/components/dashboard/SiteNav'
|
||||
import FilterBar from '@/components/dashboard/FilterBar'
|
||||
import AddFilterDropdown, { type FilterSuggestion, type FilterSuggestions } from '@/components/dashboard/AddFilterDropdown'
|
||||
import EventProperties from '@/components/dashboard/EventProperties'
|
||||
@@ -79,8 +80,8 @@ function getInitialDateRange(): { start: string; end: string } {
|
||||
}
|
||||
|
||||
export default function SiteDashboardPage() {
|
||||
const { user } = useAuth()
|
||||
const canEdit = user?.role === 'owner' || user?.role === 'admin'
|
||||
|
||||
|
||||
|
||||
const params = useParams()
|
||||
const router = useRouter()
|
||||
@@ -494,39 +495,12 @@ export default function SiteDashboardPage() {
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="h-6 w-px bg-neutral-200 dark:bg-neutral-700 flex-shrink-0"
|
||||
aria-hidden
|
||||
/>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
onClick={() => router.push(`/sites/${siteId}/uptime`)}
|
||||
variant="ghost"
|
||||
className="text-sm"
|
||||
>
|
||||
Uptime
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => router.push(`/sites/${siteId}/funnels`)}
|
||||
variant="ghost"
|
||||
className="text-sm"
|
||||
>
|
||||
Funnels
|
||||
</Button>
|
||||
{canEdit && (
|
||||
<Button
|
||||
onClick={() => router.push(`/sites/${siteId}/settings`)}
|
||||
variant="ghost"
|
||||
className="text-sm"
|
||||
>
|
||||
Settings
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SiteNav siteId={siteId} />
|
||||
|
||||
{/* Dimension Filters */}
|
||||
<div className="flex items-center gap-2 flex-wrap mb-2">
|
||||
<AddFilterDropdown onAdd={handleAddFilter} suggestions={filterSuggestions} onFetchSuggestions={handleFetchSuggestions} />
|
||||
|
||||
@@ -15,6 +15,7 @@ import { APP_URL } from '@/lib/api/client'
|
||||
import { generatePrivacySnippet } from '@/lib/utils/privacySnippet'
|
||||
import { useUnsavedChanges } from '@/lib/hooks/useUnsavedChanges'
|
||||
import { getSubscription, type SubscriptionDetails } from '@/lib/api/billing'
|
||||
import SiteNav from '@/components/dashboard/SiteNav'
|
||||
import { getRetentionOptionsForPlan, formatRetentionMonths } from '@/lib/plans'
|
||||
import { motion, AnimatePresence } from 'framer-motion'
|
||||
import { useAuth } from '@/lib/auth/context'
|
||||
@@ -403,6 +404,8 @@ export default function SiteSettingsPage() {
|
||||
|
||||
return (
|
||||
<div className="w-full max-w-6xl mx-auto px-4 sm:px-6 py-8">
|
||||
<SiteNav siteId={siteId} />
|
||||
|
||||
<div className="space-y-8">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-neutral-900 dark:text-white">Site Settings</h1>
|
||||
|
||||
@@ -21,6 +21,7 @@ import { toast } from '@ciphera-net/ui'
|
||||
import { useTheme } from '@ciphera-net/ui'
|
||||
import { getAuthErrorMessage } from '@ciphera-net/ui'
|
||||
import { Button, Modal } from '@ciphera-net/ui'
|
||||
import SiteNav from '@/components/dashboard/SiteNav'
|
||||
import { UptimeSkeleton, ChecksSkeleton, useMinimumLoading } from '@/components/skeletons'
|
||||
import {
|
||||
AreaChart,
|
||||
@@ -723,21 +724,14 @@ export default function UptimePage() {
|
||||
transition={{ duration: 0.2 }}
|
||||
className="w-full max-w-6xl mx-auto px-4 sm:px-6 py-8"
|
||||
>
|
||||
<SiteNav siteId={siteId} />
|
||||
|
||||
{/* Header */}
|
||||
<div className="mb-8 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<button
|
||||
onClick={() => router.push(`/sites/${siteId}`)}
|
||||
className="text-sm text-neutral-500 dark:text-neutral-400 hover:text-neutral-700 dark:hover:text-neutral-200 transition-colors"
|
||||
>
|
||||
{site.name}
|
||||
</button>
|
||||
<span className="text-neutral-300 dark:text-neutral-600">/</span>
|
||||
<h1 className="text-2xl font-bold text-neutral-900 dark:text-white">
|
||||
Uptime
|
||||
</h1>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-neutral-900 dark:text-white mb-1">
|
||||
Uptime
|
||||
</h1>
|
||||
<p className="text-sm text-neutral-500 dark:text-neutral-400">
|
||||
Monitor your endpoints and track availability over time
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user