import AppLayout from '@/Layouts/AppLayout'; import { Head, router } from '@inertiajs/react'; import { Cloud, Plus, RefreshCw, Server, HardDrive, Database, Globe } from 'lucide-react'; import { GlassCard, StatCard } from '@/Components/ui/GlassCard'; import { StatusBadge } from '@/Components/ui/StatusBadge'; import { Button } from '@/Components/ui/Button'; import { DataTable } from '@/Components/ui/DataTable'; import { timeAgo } from '@/lib/utils'; import { motion } from 'framer-motion'; import { useState } from 'react'; const PROVIDERS = { aws: { label: 'Amazon Web Services', color: '#FF9900', icon: '☁' }, alibaba: { label: 'Alibaba Cloud', color: '#FF6A00', icon: '☁' }, tencent: { label: 'Tencent Cloud', color: '#00A3FF', icon: '☁' }, gcp: { label: 'Google Cloud', color: '#4285F4', icon: '☁' }, azure: { label: 'Microsoft Azure', color: '#0078D4', icon: '☁' }, digitalocean: { label: 'DigitalOcean', color: '#0080FF', icon: '☁' }, vultr: { label: 'Vultr', color: '#007BFC', icon: '☁' }, hetzner: { label: 'Hetzner', color: '#D50C2D', icon: '☁' }, }; const RESOURCE_ICONS = { ec2: Server, s3: HardDrive, rds: Database, vpc: Globe }; export default function CloudIndex({ accounts, resources, stats }) { const [syncLoading, setSyncLoading] = useState(null); const [selectedAccount, setSelectedAccount] = useState(null); const sync = (id) => { setSyncLoading(id); router.post(`/cloud/accounts/${id}/sync`, {}, { onFinish: () => setSyncLoading(null) }); }; const accountColumns = [ { header: 'Account', accessor: 'name', render: row => { const p = PROVIDERS[row.provider] ?? {}; return (
{row.provider?.toUpperCase().slice(0, 2)}

{row.name}

{p.label ?? row.provider}

); }}, { header: 'Account ID', accessor: 'account_id', render: row => ( {row.account_id ?? '—'} )}, { header: 'Region', accessor: 'region', render: row => ( {row.region ?? '—'} )}, { header: 'Status', accessor: 'status', render: row => }, { header: 'Last Sync', accessor: 'last_sync_at', render: row => ( {timeAgo(row.last_sync_at)} )}, { header: '', key: 'actions', render: row => (
e.stopPropagation()}>
)}, ]; const resourceColumns = [ { header: 'Resource', accessor: 'name', render: row => { const Icon = RESOURCE_ICONS[row.resource_type] ?? Cloud; return (

{row.name}

{row.resource_id}

); }}, { header: 'Type', accessor: 'resource_type', render: row => ( {row.resource_type} )}, { header: 'Region', accessor: 'region', render: row => ( {row.region} )}, { header: 'Status', accessor: 'status', render: row => }, { header: 'Cost/mo', accessor: 'monthly_cost', render: row => ( row.monthly_cost ? ${row.monthly_cost} : — )}, ]; return (

Cloud Management

AWS, Alibaba, Tencent, GCP, Azure and more

{/* Provider cards */}
{Object.entries(PROVIDERS).slice(0, 4).map(([key, p]) => { const count = accounts?.filter(a => a.provider === key).length ?? 0; return (
{key.toUpperCase().slice(0, 2)}

{key.toUpperCase()}

{count} account{count !== 1 ? 's' : ''}

); })}
{/* Accounts */}

Cloud Accounts

router.visit(`/cloud/accounts/${row.id}`)} emptyMessage="No cloud accounts. Add your first account to get started." />
{/* Resources */}

Cloud Resources

); }