mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-03 09:16:40 +00:00
fix issues from test deploy
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
FormMessage
|
||||
} from "@app/components/ui/form";
|
||||
import { Input } from "@app/components/ui/input";
|
||||
import { useToast } from "@app/hooks/useToast";
|
||||
@@ -24,11 +24,15 @@ import {
|
||||
CredenzaDescription,
|
||||
CredenzaFooter,
|
||||
CredenzaHeader,
|
||||
CredenzaTitle,
|
||||
CredenzaTitle
|
||||
} from "@app/components/Credenza";
|
||||
import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { CreateSiteBody, PickSiteDefaultsResponse } from "@server/routers/site";
|
||||
import {
|
||||
CreateSiteBody,
|
||||
CreateSiteResponse,
|
||||
PickSiteDefaultsResponse
|
||||
} from "@server/routers/site";
|
||||
import { generateKeypair } from "../[niceId]/components/wireguardConfig";
|
||||
import CopyTextBox from "@app/components/CopyTextBox";
|
||||
import { Checkbox } from "@app/components/ui/checkbox";
|
||||
@@ -37,42 +41,49 @@ import {
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
SelectValue
|
||||
} from "@app/components/ui/select";
|
||||
import { formatAxiosError } from "@app/lib/utils";
|
||||
import { createApiClient } from "@app/api";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { SiteRow } from "./SitesTable";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
const method = [
|
||||
{ label: "Newt", value: "newt" },
|
||||
{ label: "Wireguard", value: "wireguard" },
|
||||
{ label: "WireGuard", value: "wireguard" }
|
||||
] as const;
|
||||
|
||||
const accountFormSchema = z.object({
|
||||
const createSiteFormSchema = z.object({
|
||||
name: z
|
||||
.string()
|
||||
.min(2, {
|
||||
message: "Name must be at least 2 characters.",
|
||||
message: "Name must be at least 2 characters."
|
||||
})
|
||||
.max(30, {
|
||||
message: "Name must not be longer than 30 characters.",
|
||||
message: "Name must not be longer than 30 characters."
|
||||
}),
|
||||
method: z.enum(["wireguard", "newt"]),
|
||||
method: z.enum(["wireguard", "newt"])
|
||||
});
|
||||
|
||||
type AccountFormValues = z.infer<typeof accountFormSchema>;
|
||||
type CreateSiteFormValues = z.infer<typeof createSiteFormSchema>;
|
||||
|
||||
const defaultValues: Partial<AccountFormValues> = {
|
||||
const defaultValues: Partial<CreateSiteFormValues> = {
|
||||
name: "",
|
||||
method: "newt",
|
||||
method: "newt"
|
||||
};
|
||||
|
||||
type CreateSiteFormProps = {
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
onCreate?: (site: SiteRow) => void;
|
||||
};
|
||||
|
||||
export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) {
|
||||
export default function CreateSiteForm({
|
||||
open,
|
||||
setOpen,
|
||||
onCreate
|
||||
}: CreateSiteFormProps) {
|
||||
const { toast } = useToast();
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
@@ -96,9 +107,9 @@ export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) {
|
||||
setIsChecked(checked);
|
||||
};
|
||||
|
||||
const form = useForm<AccountFormValues>({
|
||||
resolver: zodResolver(accountFormSchema),
|
||||
defaultValues,
|
||||
const form = useForm<CreateSiteFormValues>({
|
||||
resolver: zodResolver(createSiteFormSchema),
|
||||
defaultValues
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -114,7 +125,7 @@ export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error picking site defaults",
|
||||
description: formatAxiosError(e),
|
||||
description: formatAxiosError(e)
|
||||
});
|
||||
})
|
||||
.then((res) => {
|
||||
@@ -125,7 +136,7 @@ export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) {
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
async function onSubmit(data: AccountFormValues) {
|
||||
async function onSubmit(data: CreateSiteFormValues) {
|
||||
setLoading(true);
|
||||
if (!siteDefaults || !keypair) {
|
||||
return;
|
||||
@@ -135,29 +146,44 @@ export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) {
|
||||
subnet: siteDefaults.subnet,
|
||||
exitNodeId: siteDefaults.exitNodeId,
|
||||
pubKey: keypair.publicKey,
|
||||
type: data.method,
|
||||
type: data.method
|
||||
};
|
||||
if (data.method === "newt") {
|
||||
payload.secret = siteDefaults.newtSecret;
|
||||
payload.newtId = siteDefaults.newtId;
|
||||
}
|
||||
const res = await api
|
||||
.put(`/org/${orgId}/site/`, payload)
|
||||
.put<
|
||||
AxiosResponse<CreateSiteResponse>
|
||||
>(`/org/${orgId}/site/`, payload)
|
||||
.catch((e) => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error creating site",
|
||||
description: formatAxiosError(e),
|
||||
description: formatAxiosError(e)
|
||||
});
|
||||
});
|
||||
|
||||
if (res && res.status === 201) {
|
||||
const niceId = res.data.data.niceId;
|
||||
// navigate to the site page
|
||||
router.push(`/${orgId}/settings/sites/${niceId}`);
|
||||
// router.push(`/${orgId}/settings/sites/${niceId}`);
|
||||
|
||||
// close the modal
|
||||
setOpen(false);
|
||||
|
||||
const data = res.data.data;
|
||||
|
||||
onCreate?.({
|
||||
name: data.name,
|
||||
id: data.siteId,
|
||||
nice: data.niceId.toString(),
|
||||
mbIn: "0 MB",
|
||||
mbOut: "0 MB",
|
||||
orgId: orgId as string,
|
||||
type: data.type as any,
|
||||
online: false
|
||||
});
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
@@ -275,8 +301,8 @@ PersistentKeepalive = 5`
|
||||
{form.watch("method") === "wireguard" &&
|
||||
!isLoading ? (
|
||||
<CopyTextBox text={wgConfig} />
|
||||
) : form.watch("method") === "wireguard" &&
|
||||
isLoading ? (
|
||||
) : form.watch("method") ===
|
||||
"wireguard" && isLoading ? (
|
||||
<p>
|
||||
Loading WireGuard
|
||||
configuration...
|
||||
|
||||
@@ -6,10 +6,16 @@ import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuTrigger
|
||||
} from "@app/components/ui/dropdown-menu";
|
||||
import { Button } from "@app/components/ui/button";
|
||||
import { ArrowRight, ArrowUpDown, Check, MoreHorizontal, X } from "lucide-react";
|
||||
import {
|
||||
ArrowRight,
|
||||
ArrowUpDown,
|
||||
Check,
|
||||
MoreHorizontal,
|
||||
X
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { AxiosResponse } from "axios";
|
||||
@@ -45,14 +51,10 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
|
||||
const [rows, setRows] = useState<SiteRow[]>(sites);
|
||||
|
||||
const api = createApiClient(useEnvContext());
|
||||
|
||||
const callApi = async () => {
|
||||
const res = await api.put<AxiosResponse<any>>(`/newt`);
|
||||
console.log(res);
|
||||
};
|
||||
|
||||
const deleteSite = (siteId: number) => {
|
||||
api.delete(`/site/${siteId}`)
|
||||
.catch((e) => {
|
||||
@@ -60,7 +62,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Error deleting site",
|
||||
description: formatAxiosError(e, "Error deleting site"),
|
||||
description: formatAxiosError(e, "Error deleting site")
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
@@ -84,7 +86,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "nice",
|
||||
@@ -100,7 +102,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "mbIn",
|
||||
@@ -116,7 +118,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "mbOut",
|
||||
@@ -132,7 +134,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
<ArrowUpDown className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "type",
|
||||
@@ -167,7 +169,7 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
accessorKey: "online",
|
||||
@@ -187,23 +189,23 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
cell: ({ row }) => {
|
||||
const originalRow = row.original;
|
||||
console.log(originalRow.online);
|
||||
|
||||
|
||||
if (originalRow.online) {
|
||||
return (
|
||||
<span className="text-green-500 flex items-center space-x-2">
|
||||
<Check className="w-4 h-4" />
|
||||
<span>Online</span>
|
||||
<Check className="w-4 h-4" />
|
||||
<span>Online</span>
|
||||
</span>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<span className="text-red-500 flex items-center space-x-2">
|
||||
<X className="w-4 h-4" />
|
||||
<span>Offline</span>
|
||||
<X className="w-4 h-4" />
|
||||
<span>Offline</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "actions",
|
||||
@@ -229,16 +231,13 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
View settings
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSelectedSite(siteRow);
|
||||
setIsDeleteModalOpen(true);
|
||||
}}
|
||||
className="text-red-500"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
setSelectedSite(siteRow);
|
||||
setIsDeleteModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="text-red-500">Delete</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
@@ -252,8 +251,8 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -261,6 +260,9 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
<CreateSiteForm
|
||||
open={isCreateModalOpen}
|
||||
setOpen={setIsCreateModalOpen}
|
||||
onCreate={(val) => {
|
||||
setRows([val, ...rows]);
|
||||
}}
|
||||
/>
|
||||
|
||||
{selectedSite && (
|
||||
@@ -302,12 +304,11 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
|
||||
|
||||
<SitesDataTable
|
||||
columns={columns}
|
||||
data={sites}
|
||||
data={rows}
|
||||
addSite={() => {
|
||||
setIsCreateModalOpen(true);
|
||||
}}
|
||||
/>
|
||||
{/* <button onClick={callApi}>Create Newt</button> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user