'use client'; import { useEffect, useMemo, useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Copy } from 'lucide-react'; import { useTranslations } from 'next-intl'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { type NodeItem, StatusService } from '@/lib/services/openflare'; import { buildEdgeDockerInstallCommand, buildRelayDockerInstallCommand, buildRelayInstallCommand, buildTunnelDockerInstallCommand, buildTunnelInstallCommand, getServerUrl, } from './node-utils'; type InstallVariant = 'edge' | 'relay' | 'tunnel'; export function InstallCommand({ node, variant, }: { node: NodeItem; variant: InstallVariant; }) { const t = useTranslations('nodes.install'); const tn = useTranslations('nodes'); const [serverUrl, setServerUrl] = useState(''); const variantMeta: Record< InstallVariant, { title: string; description: string; tokenLabel: string; scriptLabel?: string; dockerLabel: string; } > = { edge: { title: t('edgeTitle'), description: t('edgeDesc'), tokenLabel: t('agentToken'), dockerLabel: t('dockerLabel'), }, relay: { title: t('relayTitle'), description: t('relayDesc'), tokenLabel: t('discoveryToken'), scriptLabel: t('scriptLabel'), dockerLabel: t('dockerLabel'), }, tunnel: { title: t('tunnelTitle'), description: t('tunnelDesc'), tokenLabel: t('tunnelToken'), scriptLabel: t('scriptLabel'), dockerLabel: t('dockerLabel'), }, }; const meta = variantMeta[variant]; const statusQuery = useQuery({ queryKey: ['openflare', 'public-status'], queryFn: () => StatusService.getPublicStatus(), staleTime: 5 * 60 * 1000, }); const serverVersion = statusQuery.data?.version; useEffect(() => { if (typeof window !== 'undefined' && !serverUrl) { setServerUrl(window.location.origin); } }, [serverUrl]); const normalizedServerUrl = getServerUrl(serverUrl); const scriptCommand = useMemo(() => { if (!normalizedServerUrl || !node.access_token || variant === 'edge') { return ''; } return variant === 'relay' ? buildRelayInstallCommand(normalizedServerUrl, node.access_token) : buildTunnelInstallCommand(normalizedServerUrl, node.access_token); }, [normalizedServerUrl, node.access_token, variant]); const dockerCommand = useMemo(() => { if (!normalizedServerUrl || !node.access_token) { return ''; } if (variant === 'edge') { return buildEdgeDockerInstallCommand( normalizedServerUrl, node.access_token, serverVersion, ); } return variant === 'relay' ? buildRelayDockerInstallCommand( normalizedServerUrl, node.access_token, serverVersion, ) : buildTunnelDockerInstallCommand( normalizedServerUrl, node.access_token, serverVersion, ); }, [normalizedServerUrl, node.access_token, variant, serverVersion]); const handleCopy = async (value: string, message: string) => { try { await navigator.clipboard.writeText(value); toast.success(message); } catch { toast.error(t('copyFailed')); } }; return (
{meta.title} {meta.description}
{scriptCommand ? ( ) : null} {dockerCommand ? ( ) : null}

{t('nodeId')}

{node.node_id}

{meta.tokenLabel}

{node.access_token || tn('na')}

setServerUrl(event.target.value)} placeholder='https://openflare.example.com' />

{t('serverUrlHint')}

{!node.access_token ? (

{t('noToken')}

) : !normalizedServerUrl ? (

{t('needServerUrl')}

) : ( <> {scriptCommand && meta.scriptLabel ? (

{meta.scriptLabel}

                  {scriptCommand}
                
) : null}

{meta.dockerLabel}

                {dockerCommand}
              
)}
); }