diff --git a/server/routers/site/listSites.ts b/server/routers/site/listSites.ts index f449b7c4..83adefa2 100644 --- a/server/routers/site/listSites.ts +++ b/server/routers/site/listSites.ts @@ -76,7 +76,7 @@ export async function listSites( return next( createHttpError( HttpCode.BAD_REQUEST, - parsedParams.error.errors.map((e) => e.message).join(", ") + fromError(parsedParams.error) ) ); } diff --git a/src/app/[orgId]/settings/access/users/[userId]/access-controls/page.tsx b/src/app/[orgId]/settings/access/users/[userId]/access-controls/page.tsx index e9d54c5a..62992860 100644 --- a/src/app/[orgId]/settings/access/users/[userId]/access-controls/page.tsx +++ b/src/app/[orgId]/settings/access/users/[userId]/access-controls/page.tsx @@ -118,7 +118,7 @@ export default function AccessControlsPage() {
; } diff --git a/src/app/[orgId]/settings/resources/[resourceId]/components/CreateResource.tsx b/src/app/[orgId]/settings/resources/[resourceId]/components/CreateResource.tsx index 75b6080e..eaba41c9 100644 --- a/src/app/[orgId]/settings/resources/[resourceId]/components/CreateResource.tsx +++ b/src/app/[orgId]/settings/resources/[resourceId]/components/CreateResource.tsx @@ -118,7 +118,7 @@ export function CreateResourceForm() { - + ; - -const defaultValues: Partial = { - name: "", - method: "wg", -}; - -export function CreateSiteForm() { - const params = useParams(); - const orgId = params.orgId; - const router = useRouter(); - - const [keypair, setKeypair] = useState<{ - publicKey: string; - privateKey: string; - } | null>(null); - const [isLoading, setIsLoading] = useState(true); - const [isChecked, setIsChecked] = useState(false); - const [siteDefaults, setSiteDefaults] = - useState(null); - - const handleCheckboxChange = (checked: boolean) => { - setIsChecked(checked); - }; - - const form = useForm({ - resolver: zodResolver(accountFormSchema), - defaultValues, - }); - - useEffect(() => { - if (typeof window !== "undefined") { - const generatedKeypair = generateKeypair(); - setKeypair(generatedKeypair); - setIsLoading(false); - - api.get(`/org/${orgId}/pick-site-defaults`) - .catch((e) => { - toast({ - title: "Error creating site...", - }); - }) - .then((res) => { - if (res && res.status === 200) { - setSiteDefaults(res.data.data); - } - }); - } - }, []); - - async function onSubmit(data: AccountFormValues) { - const res = await api - .put(`/org/${orgId}/site/`, { - name: data.name, - subnet: siteDefaults?.subnet, - exitNodeId: siteDefaults?.exitNodeId, - pubKey: keypair?.publicKey, - }) - .catch((e) => { - toast({ - title: "Error creating site...", - }); - }); - - if (res && res.status === 201) { - const niceId = res.data.data.niceId; - // navigate to the site page - router.push(`/${orgId}/settings/sites/${niceId}`); - } - } - - const wgConfig = - keypair && siteDefaults - ? `[Interface] -Address = ${siteDefaults.subnet} -ListenPort = 51820 -PrivateKey = ${keypair.privateKey} - -[Peer] -PublicKey = ${siteDefaults.publicKey} -AllowedIPs = ${siteDefaults.address.split("/")[0]}/32 -Endpoint = ${siteDefaults.endpoint}:${siteDefaults.listenPort} -PersistentKeepalive = 5` - : ""; - - const newtConfig = `curl -fsSL https://get.docker.com -o get-docker.sh -sh get-docker.sh`; - - return ( - <> - - - ( - - Name - - - - - This is the name that will be displayed for - this site. - - - - )} - /> - ( - - Method -
- - - - -
- - This is how you will connect your site to - Fossorial. - - -
- )} - /> - {form.watch("method") === "wg" && !isLoading ? ( - - ) : form.watch("method") === "wg" && isLoading ? ( -

Loading WireGuard configuration...

- ) : ( - - )} -
- - -
- - - - - ); -} diff --git a/src/app/[orgId]/settings/sites/[niceId]/components/GeneralForm.tsx b/src/app/[orgId]/settings/sites/[niceId]/components/GeneralForm.tsx deleted file mode 100644 index 1af7c03b..00000000 --- a/src/app/[orgId]/settings/sites/[niceId]/components/GeneralForm.tsx +++ /dev/null @@ -1,80 +0,0 @@ -"use client"; - -import { zodResolver } from "@hookform/resolvers/zod"; -import { z } from "zod"; -import { Button } from "@/components/ui/button"; -import { - Form, - FormControl, - FormDescription, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form"; -import { Input } from "@/components/ui/input"; -import { useSiteContext } from "@app/hooks/useSiteContext"; -import { useForm } from "react-hook-form"; -import api from "@app/api"; -import { useToast } from "@app/hooks/useToast"; - -const GeneralFormSchema = z.object({ - name: z.string(), -}); - -type GeneralFormValues = z.infer; - -export function GeneralForm() { - const { site, updateSite } = useSiteContext(); - const { toast } = useToast(); - - const form = useForm({ - resolver: zodResolver(GeneralFormSchema), - defaultValues: { - name: site?.name, - }, - mode: "onChange", - }); - - async function onSubmit(data: GeneralFormValues) { - updateSite({ name: data.name }); - - await api - .post(`/site/${site?.siteId}`, { - name: data.name, - }) - .catch((e) => { - toast({ - variant: "destructive", - title: "Failed to update site", - description: - e.message || - "An error occurred while updating the site.", - }); - }); - } - - return ( -
- - ( - - Name - - - - - This is the display name of the site. - - - - )} - /> - - - - ); -} diff --git a/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx b/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx new file mode 100644 index 00000000..ae5f28c4 --- /dev/null +++ b/src/app/[orgId]/settings/sites/[niceId]/general/page.tsx @@ -0,0 +1,99 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { z } from "zod"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { useSiteContext } from "@app/hooks/useSiteContext"; +import { useForm } from "react-hook-form"; +import api from "@app/api"; +import { useToast } from "@app/hooks/useToast"; +import { useRouter } from "next/navigation"; + +const GeneralFormSchema = z.object({ + name: z.string(), +}); + +type GeneralFormValues = z.infer; + +export default function GeneralPage() { + const { site, updateSite } = useSiteContext(); + const { toast } = useToast(); + + const router = useRouter(); + + const form = useForm({ + resolver: zodResolver(GeneralFormSchema), + defaultValues: { + name: site?.name, + }, + mode: "onChange", + }); + + async function onSubmit(data: GeneralFormValues) { + await api + .post(`/site/${site?.siteId}`, { + name: data.name, + }) + .catch((e) => { + toast({ + variant: "destructive", + title: "Failed to update site", + description: + e.message || + "An error occurred while updating the site.", + }); + }); + + updateSite({ name: data.name }); + + router.refresh(); + } + + return ( + <> +
+

+ General Settings +

+

+ Configure the general settings for this site +

+
+ +
+ + ( + + Name + + + + + This is the display name of the site + + + + )} + /> + + + + + ); +} diff --git a/src/app/[orgId]/settings/sites/[niceId]/layout.tsx b/src/app/[orgId]/settings/sites/[niceId]/layout.tsx index 972177ed..2b3da1f1 100644 --- a/src/app/[orgId]/settings/sites/[niceId]/layout.tsx +++ b/src/app/[orgId]/settings/sites/[niceId]/layout.tsx @@ -5,6 +5,8 @@ import { AxiosResponse } from "axios"; import { redirect } from "next/navigation"; import { authCookieHeader } from "@app/api/cookies"; import { SidebarSettings } from "@app/components/SidebarSettings"; +import Link from "next/link"; +import { ArrowLeft } from "lucide-react"; interface SettingsLayoutProps { children: React.ReactNode; @@ -17,50 +19,53 @@ export default async function SettingsLayout(props: SettingsLayoutProps) { const { children } = props; let site = null; - - if (params.niceId !== "create") { - try { - const res = await internal.get>( - `/org/${params.orgId}/site/${params.niceId}`, - await authCookieHeader() - ); - site = res.data.data; - } catch { - redirect(`/${params.orgId}/settings/sites`); - } + try { + const res = await internal.get>( + `/org/${params.orgId}/site/${params.niceId}`, + await authCookieHeader() + ); + site = res.data.data; + } catch { + redirect(`/${params.orgId}/settings/sites`); } const sidebarNavItems = [ { title: "General", - href: "/{orgId}/settings/sites/{niceId}", + href: "/{orgId}/settings/sites/{niceId}/general", }, ]; - const isCreate = params.niceId === "create"; - return ( <> +
+ +
+ All Sites +
+ +
+

- {isCreate ? "New Site" : site?.name + " Settings"} + {site?.name + " Settings"}

- {isCreate - ? "Create a new site" - : "Configure the settings on your site: " + - site?.name || ""} - . + Configure the settings on your site

- - {children} - + + + {children} + + ); } diff --git a/src/app/[orgId]/settings/sites/[niceId]/page.tsx b/src/app/[orgId]/settings/sites/[niceId]/page.tsx index e611c73e..045b762e 100644 --- a/src/app/[orgId]/settings/sites/[niceId]/page.tsx +++ b/src/app/[orgId]/settings/sites/[niceId]/page.tsx @@ -1,29 +1,8 @@ -import React from "react"; -import { Separator } from "@/components/ui/separator"; -import { CreateSiteForm } from "./components/CreateSite"; -import { GeneralForm } from "./components/GeneralForm"; +import { redirect } from "next/navigation"; export default async function SitePage(props: { - params: Promise<{ niceId: string }>; + params: Promise<{ orgId: string; niceId: string }>; }) { const params = await props.params; - const isCreate = params.niceId === "create"; - - return ( -
-
-

- {isCreate ? "Create Site" : "General"} -

-

- {isCreate - ? "Create a new site" - : "Edit basic site settings"} -

-
- - - {isCreate ? : } -
- ); + redirect(`/${params.orgId}/settings/sites/${params.niceId}/general`); } diff --git a/src/app/[orgId]/settings/sites/components/CreateSiteForm.tsx b/src/app/[orgId]/settings/sites/components/CreateSiteForm.tsx index da3fe58f..10a864c6 100644 --- a/src/app/[orgId]/settings/sites/components/CreateSiteForm.tsx +++ b/src/app/[orgId]/settings/sites/components/CreateSiteForm.tsx @@ -133,6 +133,9 @@ export default function CreateSiteForm({ open, setOpen }: CreateSiteFormProps) { const niceId = res.data.data.niceId; // navigate to the site page router.push(`/${orgId}/settings/sites/${niceId}`); + + // close the modal + setOpen(false); } setLoading(false); @@ -258,6 +261,11 @@ sh get-docker.sh`; )} + + You will only be able to see the + configuration once. + +
{ - // router.push(`/${orgId}/settings/sites/create`); setIsCreateModalOpen(true); }} /> diff --git a/src/app/profile/account/account-form.tsx b/src/app/profile/account/account-form.tsx index a3f48044..25b22370 100644 --- a/src/app/profile/account/account-form.tsx +++ b/src/app/profile/account/account-form.tsx @@ -88,7 +88,7 @@ export function AccountForm() { return (
- + - + - +
-
+
diff --git a/src/app/profile/notifications/notifications-form.tsx b/src/app/profile/notifications/notifications-form.tsx index 0eb215b5..a5e8ab8c 100644 --- a/src/app/profile/notifications/notifications-form.tsx +++ b/src/app/profile/notifications/notifications-form.tsx @@ -60,7 +60,7 @@ export function NotificationsForm() { return ( - + - + - + - + - + - + - +