import { Button, Card, List } from "antd"; import BasePage from "@ui/pages/BasePage"; import PageRouter from "@ui/pages/PageRouter"; import React from "react"; import { PlusOutlined } from "@ant-design/icons"; import useSWR from "swr"; import { APIResponse, Peer, WgServer } from "@lib/typings"; import useSWRMutation from "swr/mutation"; import { useRouter } from "next/router"; import { MiddleEllipsis } from "@ui/MiddleEllipsis"; import StatusBadge from "@ui/StatusBadge"; import { SmartModalRef } from "@ui/Modal/SmartModal"; import CreateClientModal from "@ui/Modal/CreateClientModal"; import { twMerge } from "tailwind-merge"; import QRCodeModal from "@ui/Modal/QRCodeModal"; import { getPeerConf } from "@lib/wireguard-utils"; import EditableText from "@ui/EditableText"; import { RLS_NAME_INPUT } from "@lib/form-rules"; import { UPDATE_CLIENT } from "@lib/swr-fetch"; import CopiableWrapper from "@ui/CopiableWrapper"; export async function getServerSideProps(context: any) { return { props: { serverId: context.params.serverId } } } type PageProps = { serverId: string } export default function ServerPage(props: PageProps) { const router = useRouter() const createClientRef = React.useRef(null) const { data, error, isLoading, mutate: refresh } = useSWR( `/api/wireguard/${props.serverId}`, async (url: string) => { const resp = await fetch(url, { method: 'GET', headers: { 'Content-Type': 'application/json' } }) if (resp.status === 404) { router.replace('/').catch() return false } const data = await resp.json() as APIResponse if (!data.ok) throw new Error('Server responded with error status') return data.result } ) const { isMutating: isChangingStatus, trigger: changeStatus } = useSWRMutation( `/api/wireguard/${props.serverId}`, async (url: string, { arg }: { arg: string }) => { const resp = await fetch(url, { method: arg === 'remove' ? 'DELETE' : 'PUT', headers: { 'Content-Type': 'application/json' }, body: arg === 'remove' ? undefined : JSON.stringify({ status: arg }) }) if (resp.status === 404) { router.replace('/').catch() return false } const data = await resp.json() as APIResponse if (!data.ok) throw new Error('Server responded with error status') return true }, { onSuccess: async () => await refresh(), onError: async () => await refresh(), } ) const lastChangeStatus = React.useRef(null) return ( refresh()} /> {error || (!isLoading && !data) ? ( ! ERROR ! ) : isLoading ? ( Loading... ) : data && (
.ant-card-body]:max-md:p1-2'}>
 {data.address}/24 
 {data.listen} 
{data.status === 'up' ? ( ) : ( )}
.ant-card-body]:p-0'} title={(
Clients {data && data.peers.length > 0 && (
)}
)} > {data && data.peers.length > 0 ? ( {data.peers.map((s) => ( refresh()} /> ))} ) : (

There are no clients yet!

)}
)}
); } interface ClientProps extends Peer, Pick { serverId: string serverPublicKey: string listenPort: number refreshTrigger: () => void } function Client(props: ClientProps) { const qrcodeRef = React.useRef(null) const [ conf, setConf ] = React.useState(null) React.useEffect(() => { getPeerConf({ ...props, serverPublicKey: props.serverPublicKey, port: props.listenPort, dns: props.dns, }) .then((s) => setConf(s)) }, [ props ]) const RefreshOptions = { onSuccess: () => props.refreshTrigger(), onError: () => props.refreshTrigger() } const { isMutating: removingClient, trigger: removeClient } = useSWRMutation( `/api/wireguard/${props.serverId}/${props.id}`, async (url: string,) => { const resp = await fetch(url, { method: 'DELETE', headers: { 'Content-Type': 'application/json' } }) const data = await resp.json() as APIResponse if (!data.ok) throw new Error('Server responded with error status') return true }, RefreshOptions ) const { isMutating, trigger } = useSWRMutation( `/api/wireguard/${props.serverId}/${props.id}`, UPDATE_CLIENT, RefreshOptions ) return (
trigger({ name: v })} /> {props.allowedIps}
{/* QRCode */} { qrcodeRef.current?.open() }}> {/* Download */} { if (!conf) { console.error('conf is null') return } console.log('conf', conf) // create a blob const blob = new Blob([ conf ], { type: 'text/plain' }) // create a link const link = document.createElement('a') link.href = window.URL.createObjectURL(blob) link.download = `${props.name}.conf` // click the link link.click() // remove the link link.remove() }}> {/* Remove */} removeClient()}>
) } function ClientBaseButton(props: { onClick: () => void loading?: boolean disabled?: boolean children: React.ReactNode }) { return (
{props.children}
) } function Row(props: { label: string children: React.ReactNode }) { return (
{props.label}
{props.children}
) }