gitea +
This commit is contained in:
65
frontend/components/layout/Footer.tsx
Normal file
65
frontend/components/layout/Footer.tsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
import { Globe } from 'lucide-react'
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="border-t border-border bg-background py-12 text-sm">
|
||||
<div className="mx-auto max-w-7xl px-6">
|
||||
<div className="grid gap-12 md:grid-cols-4 lg:grid-cols-5">
|
||||
<div className="md:col-span-2">
|
||||
<div className="mb-6 flex items-center gap-2">
|
||||
<div className="relative h-8 w-8">
|
||||
<Image src="/logo.png" alt="Alertify Logo" fill className="object-contain" />
|
||||
</div>
|
||||
<span className="text-lg font-bold text-foreground">Alertify</span>
|
||||
</div>
|
||||
<p className="text-muted-foreground max-w-xs mb-6">
|
||||
The modern platform for uptime monitoring, change detection, and performance tracking.
|
||||
</p>
|
||||
<div className="flex gap-4">
|
||||
{/* Social icons placeholders */}
|
||||
<div className="h-8 w-8 rounded-full bg-secondary hover:bg-border transition-colors cursor-pointer flex items-center justify-center text-muted-foreground hover:text-foreground">
|
||||
<Globe className="h-4 w-4" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="mb-4 font-semibold text-foreground">Product</h4>
|
||||
<ul className="space-y-3 text-muted-foreground">
|
||||
<li><Link href="/#features" className="hover:text-primary transition-colors">Features</Link></li>
|
||||
<li><Link href="/#use-cases" className="hover:text-primary transition-colors">Use Cases</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="mb-4 font-semibold text-foreground">Company</h4>
|
||||
<ul className="space-y-3 text-muted-foreground">
|
||||
<li><Link href="/blog" className="hover:text-primary transition-colors">Blog</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4 className="mb-4 font-semibold text-foreground">Legal</h4>
|
||||
<ul className="space-y-3 text-muted-foreground">
|
||||
<li><Link href="/privacy" className="hover:text-primary transition-colors">Privacy</Link></li>
|
||||
<li><Link href="/admin" className="hover:text-primary transition-colors opacity-50 text-xs">Admin</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 flex flex-col items-center justify-between gap-4 border-t border-border pt-8 text-sm text-muted-foreground sm:flex-row">
|
||||
<p>© 2026 Alertify. All rights reserved.</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="relative flex h-2 w-2">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
|
||||
</span>
|
||||
System Operational
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useState, useEffect } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { usePathname, useRouter } from 'next/navigation'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
@@ -86,8 +86,15 @@ export function Sidebar({ isOpen, onClose }: SidebarProps = {}) {
|
||||
},
|
||||
})
|
||||
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true)
|
||||
}, [])
|
||||
|
||||
// Default to stored user plan from localStorage if API fails or is loading
|
||||
const getStoredPlan = () => {
|
||||
if (!mounted) return 'free'
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
const userStr = localStorage.getItem('user');
|
||||
@@ -98,8 +105,8 @@ export function Sidebar({ isOpen, onClose }: SidebarProps = {}) {
|
||||
}
|
||||
|
||||
// Capitalize plan name
|
||||
const planName = (settingsData?.plan || getStoredPlan() || 'free').charAt(0).toUpperCase() +
|
||||
(settingsData?.plan || getStoredPlan() || 'free').slice(1);
|
||||
const currentPlan = settingsData?.plan || getStoredPlan() || 'free'
|
||||
const planName = currentPlan.charAt(0).toUpperCase() + currentPlan.slice(1);
|
||||
|
||||
// Determine badge color
|
||||
const getBadgeVariant = (plan: string) => {
|
||||
|
||||
Reference in New Issue
Block a user