"use client";
import Link from "next/link";
import CommonGridShape from "@/components/common/CommonGridShape";
import { useEffect, useState } from "react";
import axios from '@/lib/axios';
import { useTranslations } from "next-intl";
interface CaCertificate {
name: string;
type: string;
serial: string;
expires_at: string;
last_synced_at?: string | null;
cdn_url?: string | null;
der_cdn_url?: string | null;
bat_cdn_url?: string | null;
mac_cdn_url?: string | null;
linux_cdn_url?: string | null;
}
// Simple internal ScrollToTop component
function ScrollToTop() {
const [show, setShow] = useState(false);
useEffect(() => {
const handleScroll = () => {
setShow(window.pageYOffset > 500);
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const scrollToTop = () => {
const element = document.querySelector('#home');
if (element) {
const navbarOffset = 80;
const elementPosition = element.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - navbarOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
});
}
};
if (!show) return null;
return (
);
}
// UI Sub-components
function Badge({ children, variant = 'brand' }: { children: React.ReactNode, variant?: 'brand' | 'blue' | 'purple' | 'green' | 'gray' }) {
const variants = {
brand: 'bg-brand-50 text-brand-700 dark:bg-brand-500/10 dark:text-brand-400 border-brand-100 dark:border-brand-500/20',
blue: 'bg-blue-50 text-blue-700 dark:bg-blue-500/10 dark:text-blue-400 border-blue-100 dark:border-blue-500/20',
purple: 'bg-purple-50 text-purple-700 dark:bg-purple-500/10 dark:text-purple-400 border-purple-100 dark:border-purple-500/20',
green: 'bg-green-50 text-green-700 dark:bg-green-500/10 dark:text-green-400 border-green-100 dark:border-green-500/20',
gray: 'bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-400 border-gray-200 dark:border-gray-700',
};
return (
{children}
);
}
function TabButton({ id, label, active, onClick, icon }: { id: string, label: string, active: boolean, onClick: () => void, icon?: React.ReactNode }) {
return (
);
}
function OsGuideContent({ title, steps }: { title: string, steps: string[] }) {
return (
{title}
{steps.map((step, idx) => {
const isCommand = step.includes('curl') || step.includes('bash') || step.includes('sudo');
return (
-
{idx + 1}
);
})}
);
}
function CaCard({ cert, isRoot, t, selectedOs, setSelectedOs }: { cert: CaCertificate, isRoot: boolean, t: any, selectedOs: string, setSelectedOs: (os: any) => void }) {
const [copied, setCopied] = useState(false);
const copyLinuxCli = () => {
if (!cert.linux_cdn_url) return;
const command = `curl -sL ${cert.linux_cdn_url} | sudo bash`;
navigator.clipboard.writeText(command);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
{/* Sync Status Badge */}
{cert.last_synced_at && (
{t('synced_to_cdn')}
)}
{isRoot ? t('root_ca') : t('intermediate_ca')}
{cert.name}
ID: {cert.serial}
}
onClick={() => {}}
/>
}
onClick={() => setSelectedOs('mobile')}
variant="green"
/>
}
onClick={() => setSelectedOs('windows')}
variant="blue"
/>
}
onClick={() => setSelectedOs('macos')}
variant="gray"
/>
{cert.linux_cdn_url && (
}
onClick={() => setSelectedOs('linux')}
variant="gray"
isFullWidth
/>
)}
);
}
function DownloadBtn({ href, label, icon, onClick, variant = 'white', isFullWidth = false }: { href: string, label: string, icon: React.ReactNode, onClick: () => void, variant?: 'white' | 'green' | 'blue' | 'gray', isFullWidth?: boolean }) {
const variants = {
white: 'bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700',
green: 'bg-green-50 dark:bg-green-500/10 text-green-700 dark:text-green-400 border-green-200 dark:border-green-500/20 hover:bg-green-100 dark:hover:bg-green-500/20',
blue: 'bg-blue-50 dark:bg-blue-500/10 text-blue-700 dark:text-blue-400 border-blue-200 dark:border-blue-500/20 hover:bg-blue-100 dark:hover:bg-blue-500/20',
gray: 'bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-100 border-gray-200 dark:border-gray-600 hover:bg-gray-200 dark:hover:bg-gray-600',
};
return (
{icon}
{label}
);
}
// Icons
const WindowsIcon = ({ className }: { className?: string }) => (
);
const AppleIcon = ({ className }: { className?: string }) => (
);
const LinuxIcon = ({ className }: { className?: string }) => (
);
const MobileIcon = ({ className }: { className?: string }) => (
);
const FileIcon = ({ className }: { className?: string }) => (
);
const CopyIcon = ({ className }: { className?: string }) => (
);
const CheckIcon = ({ className }: { className?: string }) => (
);
export default function HomeClient() {
const t = useTranslations("Home");
const [certificates, setCertificates] = useState([]);
const [loadingCerts, setLoadingCerts] = useState(true);
const [selectedOs, setSelectedOs] = useState<'windows' | 'macos' | 'linux' | 'mobile'>('windows');
useEffect(() => {
const fetchCertificates = async () => {
try {
const response = await axios.get('/api/public/ca-certificates');
if (response.data.success) {
setCertificates(response.data.data);
}
} catch (error) {
console.error("Failed to fetch certificates", error);
} finally {
setLoadingCerts(false);
}
};
fetchCertificates();
}, []);
const handleScroll = (e: React.MouseEvent, id: string) => {
e.preventDefault();
const element = document.querySelector(id);
if (element) {
const navbarOffset = 80;
const elementPosition = element.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - navbarOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth",
});
}
};
return (
{/* Hero Section */}
{/* Features Section */}
{t('features_title')}
{t('features_desc')}
{/* Feature 1 */}
{t('feature_1_title')}
{t('feature_1_desc')}
{/* Feature 2 */}
{t('feature_2_title')}
{t('feature_2_desc')}
{/* Feature 3 */}
{t('feature_3_title')}
{t('feature_3_desc')}
{/* Trust Store Section */}
{/* Gradient Background */}
{t('trust_store_title')}
{t('trust_store_desc')}
{loadingCerts ? (
) : (
{/* Root CA Section */}
{t('root_ca_hierarchy')}
{certificates.filter(c => c.type === 'root').map((cert) => (
))}
{/* Intermediate CAs Section */}
{t('intermediate_ca_hierarchy')}
{certificates.filter(c => c.type !== 'root').map((cert) => (
))}
{/* OS Selection Tabs for Global Guide */}
{t('install_guide_title')}
{t('install_guide_desc')}
setSelectedOs('windows')} icon={} />
setSelectedOs('macos')} icon={} />
setSelectedOs('linux')} icon={} />
setSelectedOs('mobile')} icon={} />
{selectedOs === 'windows' && }
{selectedOs === 'macos' && }
{selectedOs === 'linux' && }
{selectedOs === 'mobile' && }
)}
{/* CTA Section */}
{t('cta_ready_title')}
{t('cta_ready_desc')}
{t('cta_free_account')}
{t('cta_signin_portal')}
{/* Abstract Design */}
{/* Back to Top Button */}
);
}