diff --git a/app/notifications/page.tsx b/app/notifications/page.tsx index eb31ee3..417fc0c 100644 --- a/app/notifications/page.tsx +++ b/app/notifications/page.tsx @@ -16,6 +16,7 @@ import { import { getAuthErrorMessage } from '@ciphera-net/ui' import { formatTimeAgo, getTypeIcon } from '@/lib/utils/notifications' import { Button, ArrowLeftIcon } from '@ciphera-net/ui' +import { useUnifiedSettings } from '@/lib/unified-settings-context' import { NotificationsListSkeleton, useMinimumLoading, useSkeletonFade } from '@/components/skeletons' import { toast } from '@ciphera-net/ui' @@ -23,6 +24,7 @@ const PAGE_SIZE = 50 export default function NotificationsPage() { const { user } = useAuth() + const { openUnifiedSettings } = useUnifiedSettings() const [notifications, setNotifications] = useState([]) const [unreadCount, setUnreadCount] = useState(0) const [loading, setLoading] = useState(true) @@ -125,9 +127,9 @@ export default function NotificationsPage() {

Notifications

Manage which notifications you receive in{' '} - +

{showSkeleton ? ( @@ -141,9 +143,9 @@ export default function NotificationsPage() {

No notifications yet

Manage which notifications you receive in{' '} - +

) : ( diff --git a/app/page.tsx b/app/page.tsx index fda9c5f..22c4b7c 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -24,11 +24,13 @@ import { toast } from '@ciphera-net/ui' import { getAuthErrorMessage } from '@ciphera-net/ui' import { getSitesLimitForPlan } from '@/lib/plans' import { formatDate } from '@/lib/utils/formatDate' +import { useUnifiedSettings } from '@/lib/unified-settings-context' type SiteStatsMap = Record export default function HomePage() { const { user, loading: authLoading } = useAuth() + const { openUnifiedSettings } = useUnifiedSettings() const [sites, setSites] = useState([]) const [sitesLoading, setSitesLoading] = useState(true) const [siteStats, setSiteStats] = useState({}) @@ -355,9 +357,9 @@ export default function HomePage() { )}
{subscription.has_payment_method ? ( - + ) : ( Upgrade diff --git a/app/sites/[id]/cdn/page.tsx b/app/sites/[id]/cdn/page.tsx index 594c431..25e2e68 100644 --- a/app/sites/[id]/cdn/page.tsx +++ b/app/sites/[id]/cdn/page.tsx @@ -3,7 +3,7 @@ import { useEffect, useState } from 'react' import dynamic from 'next/dynamic' import { useParams } from 'next/navigation' -import Link from 'next/link' +import { useUnifiedSettings } from '@/lib/unified-settings-context' import * as Flags from 'country-flag-icons/react/3x2' const DottedMap = dynamic(() => import('@/components/dashboard/DottedMap'), { ssr: false }) @@ -115,6 +115,8 @@ export default function CDNPage() { const [period, setPeriod] = useState('7') const [dateRange, setDateRange] = useState(() => getDateRange(7)) + const { openUnifiedSettings } = useUnifiedSettings() + // Data fetching const { data: bunnyStatus } = useBunnyStatus(siteId) const { data: dashboard } = useDashboard(siteId, dateRange.start, dateRange.end) @@ -183,13 +185,13 @@ export default function CDNPage() {

Monitor your CDN performance including bandwidth usage, cache hit rates, request volumes, and geographic distribution.

- openUnifiedSettings({ context: 'site', tab: 'integrations' })} + className="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-brand-orange hover:bg-brand-orange/90 text-white text-sm font-medium transition-colors cursor-pointer" > Connect in Settings - +
) diff --git a/app/sites/[id]/search/page.tsx b/app/sites/[id]/search/page.tsx index bc2a444..4f1dd5f 100644 --- a/app/sites/[id]/search/page.tsx +++ b/app/sites/[id]/search/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' import { useParams } from 'next/navigation' -import Link from 'next/link' +import { useUnifiedSettings } from '@/lib/unified-settings-context' import { Select, DatePicker } from '@ciphera-net/ui' import { getDateRange, formatDate, getThisWeekRange, getThisMonthRange } from '@/lib/utils/dateRanges' import { CaretDown, CaretUp, MagnifyingGlass, ArrowSquareOut } from '@phosphor-icons/react' @@ -36,6 +36,7 @@ const PAGE_SIZE = 50 export default function SearchConsolePage() { const params = useParams() const siteId = params.id as string + const { openUnifiedSettings } = useUnifiedSettings() // Date range const [period, setPeriod] = useState('28') @@ -172,13 +173,13 @@ export default function SearchConsolePage() {

See how your site performs in Google Search. View top queries, pages, click-through rates, and average position data.

- openUnifiedSettings({ context: 'site', tab: 'integrations' })} + className="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-brand-orange hover:bg-brand-orange/90 text-white text-sm font-medium transition-colors cursor-pointer" > Connect in Settings - + ) diff --git a/components/dashboard/Sidebar.tsx b/components/dashboard/Sidebar.tsx index 0f5b7d9..e365f53 100644 --- a/components/dashboard/Sidebar.tsx +++ b/components/dashboard/Sidebar.tsx @@ -327,6 +327,38 @@ function NavLink({ ) } +// ─── Settings Button (opens unified modal instead of navigating) ───── + +function SettingsButton({ + item, collapsed, onClick, +}: { + item: NavItem; collapsed: boolean; onClick?: () => void +}) { + const { openUnifiedSettings } = useUnifiedSettings() + + return ( +
+ + {collapsed && ( + + {item.label} + + )} +
+ ) +} + // ─── Sidebar Content ──────────────────────────────────────── interface SidebarContentProps { @@ -401,7 +433,7 @@ function SidebarContent({ ))} {group.label === 'Infrastructure' && canEdit && ( - + )} diff --git a/components/dashboard/SiteNav.tsx b/components/dashboard/SiteNav.tsx index e8eb496..0ee505f 100644 --- a/components/dashboard/SiteNav.tsx +++ b/components/dashboard/SiteNav.tsx @@ -4,7 +4,6 @@ import Link from 'next/link' import { usePathname } from 'next/navigation' import { motion } from 'framer-motion' import { useTabListKeyboard } from '@/lib/hooks/useTabListKeyboard' -import { useAuth } from '@/lib/auth/context' interface SiteNavProps { siteId: string @@ -13,8 +12,6 @@ interface SiteNavProps { export default function SiteNav({ siteId }: SiteNavProps) { const pathname = usePathname() const handleTabKeyDown = useTabListKeyboard() - const { user } = useAuth() - const canEdit = user?.role === 'owner' || user?.role === 'admin' const tabs = [ { label: 'Dashboard', href: `/sites/${siteId}` }, @@ -24,7 +21,6 @@ export default function SiteNav({ siteId }: SiteNavProps) { { label: 'Search', href: `/sites/${siteId}/search` }, { label: 'CDN', href: `/sites/${siteId}/cdn` }, { label: 'Uptime', href: `/sites/${siteId}/uptime` }, - ...(canEdit ? [{ label: 'Settings', href: `/sites/${siteId}/settings` }] : []), ] const isActive = (href: string) => { diff --git a/components/notifications/NotificationCenter.tsx b/components/notifications/NotificationCenter.tsx index 749979c..cf7f00c 100644 --- a/components/notifications/NotificationCenter.tsx +++ b/components/notifications/NotificationCenter.tsx @@ -12,6 +12,7 @@ import { listNotifications, markNotificationRead, markAllNotificationsRead, type import { getAuthErrorMessage } from '@ciphera-net/ui' import { formatTimeAgo, getTypeIcon } from '@/lib/utils/notifications' import { SettingsIcon } from '@ciphera-net/ui' +import { useUnifiedSettings } from '@/lib/unified-settings-context' import { SkeletonLine, SkeletonCircle } from '@/components/skeletons' // * Bell icon (simple SVG, no extra deps) @@ -58,6 +59,7 @@ export default function NotificationCenter({ anchor = 'bottom', variant = 'defau const panelRef = useRef(null) const buttonRef = useRef(null) const [fixedPos, setFixedPos] = useState<{ left: number; top?: number; bottom?: number } | null>(null) + const { openUnifiedSettings } = useUnifiedSettings() const updatePosition = useCallback(() => { if (anchor === 'right' && buttonRef.current) { @@ -319,14 +321,16 @@ export default function NotificationCenter({ anchor = 'bottom', variant = 'defau > View all - setOpen(false)} - className="flex items-center gap-2 text-sm text-neutral-400 hover:text-brand-orange dark:hover:text-brand-orange transition-colors" + )}