From 474bc7997e04f52cb2ccdb33ca7df2e074abdc61 Mon Sep 17 00:00:00 2001
From: Owen Schwartz
Date: Sat, 19 Oct 2024 12:48:07 -0400
Subject: [PATCH 1/2] Fix naming and add update to site provider?
---
server/routers/external.ts | 8 +-
.../{create-site.tsx => CreateSite.tsx} | 2 +-
.../sites/[niceId]/components/GeneralForm.tsx | 174 ++++++++++++++++++
.../{newt-config.tsx => NewtConfig.tsx} | 0
...wireguard-config.ts => wireguardConfig.ts} | 0
src/app/[orgId]/sites/[niceId]/layout.tsx | 5 +-
src/app/[orgId]/sites/[niceId]/page.tsx | 6 +-
src/contexts/siteContext.ts | 9 +-
src/hooks/useSiteContext.ts | 11 +-
src/providers/SiteProvider.tsx | 46 ++++-
10 files changed, 238 insertions(+), 23 deletions(-)
rename src/app/[orgId]/sites/[niceId]/components/{create-site.tsx => CreateSite.tsx} (99%)
create mode 100644 src/app/[orgId]/sites/[niceId]/components/GeneralForm.tsx
rename src/app/[orgId]/sites/[niceId]/components/{newt-config.tsx => NewtConfig.tsx} (100%)
rename src/app/[orgId]/sites/[niceId]/components/{wireguard-config.ts => wireguardConfig.ts} (100%)
diff --git a/server/routers/external.ts b/server/routers/external.ts
index 7fd0c69..2cb7ba6 100644
--- a/server/routers/external.ts
+++ b/server/routers/external.ts
@@ -46,10 +46,10 @@ authenticated.put("/org/:orgId/site", verifyOrgAccess, site.createSite);
authenticated.get("/org/:orgId/sites", verifyOrgAccess, site.listSites);
authenticated.get("/org/:orgId/site/:niceId", verifyOrgAccess, site.getSite);
-authenticated.get("/site/siteId/:siteId", verifySiteAccess, site.getSite);
-authenticated.get("/site/siteId/:siteId/roles", verifySiteAccess, site.listSiteRoles);
-authenticated.post("/site/siteId/:siteId", verifySiteAccess, site.updateSite);
-authenticated.delete("/site/siteId/:siteId", verifySiteAccess, site.deleteSite);
+authenticated.get("/site/:siteId", verifySiteAccess, site.getSite);
+authenticated.get("/site/:siteId/roles", verifySiteAccess, site.listSiteRoles);
+authenticated.post("/site/:siteId", verifySiteAccess, site.updateSite);
+authenticated.delete("/site/:siteId", verifySiteAccess, site.deleteSite);
authenticated.put(
"/org/:orgId/site/:siteId/resource",
diff --git a/src/app/[orgId]/sites/[niceId]/components/create-site.tsx b/src/app/[orgId]/sites/[niceId]/components/CreateSite.tsx
similarity index 99%
rename from src/app/[orgId]/sites/[niceId]/components/create-site.tsx
rename to src/app/[orgId]/sites/[niceId]/components/CreateSite.tsx
index 936506e..cc6fd96 100644
--- a/src/app/[orgId]/sites/[niceId]/components/create-site.tsx
+++ b/src/app/[orgId]/sites/[niceId]/components/CreateSite.tsx
@@ -18,7 +18,7 @@ import {
FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
-import { generateKeypair } from "./wireguard-config";
+import { generateKeypair } from "./wireguardConfig";
import React, { useState, useEffect } from "react";
import { api } from "@/api";
import { useParams } from "next/navigation";
diff --git a/src/app/[orgId]/sites/[niceId]/components/GeneralForm.tsx b/src/app/[orgId]/sites/[niceId]/components/GeneralForm.tsx
new file mode 100644
index 0000000..d2fd5f2
--- /dev/null
+++ b/src/app/[orgId]/sites/[niceId]/components/GeneralForm.tsx
@@ -0,0 +1,174 @@
+"use client"
+
+import Link from "next/link"
+import { zodResolver } from "@hookform/resolvers/zod"
+import { useFieldArray, useForm } from "react-hook-form"
+import { z } from "zod"
+
+import { cn } from "@/lib/utils"
+import { toast } from "@/hooks/use-toast"
+
+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 {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select"
+import { Textarea } from "@/components/ui/textarea"
+import { useSiteContext } from "@app/hooks/useSiteContext"
+import api from "@app/api"
+
+const GeneralFormSchema = z.object({
+ name: z.string()
+ // email: z
+ // .string({
+ // required_error: "Please select an email to display.",
+ // })
+ // .email(),
+ // bio: z.string().max(160).min(4),
+ // urls: z
+ // .array(
+ // z.object({
+ // value: z.string().url({ message: "Please enter a valid URL." }),
+ // })
+ // )
+ // .optional(),
+})
+
+type GeneralFormValues = z.infer
+
+export function GeneralForm() {
+ const { site, updateSite } = useSiteContext();
+
+ const form = useForm({
+ resolver: zodResolver(GeneralFormSchema),
+ defaultValues: {
+ name: site?.name
+ },
+ mode: "onChange",
+ })
+
+ // const { fields, append } = useFieldArray({
+ // name: "urls",
+ // control: form.control,
+ // })
+
+ async function onSubmit(data: GeneralFormValues) {
+ await updateSite({ name: data.name });
+ }
+
+ return (
+
+
+ )
+}
diff --git a/src/app/[orgId]/sites/[niceId]/components/newt-config.tsx b/src/app/[orgId]/sites/[niceId]/components/NewtConfig.tsx
similarity index 100%
rename from src/app/[orgId]/sites/[niceId]/components/newt-config.tsx
rename to src/app/[orgId]/sites/[niceId]/components/NewtConfig.tsx
diff --git a/src/app/[orgId]/sites/[niceId]/components/wireguard-config.ts b/src/app/[orgId]/sites/[niceId]/components/wireguardConfig.ts
similarity index 100%
rename from src/app/[orgId]/sites/[niceId]/components/wireguard-config.ts
rename to src/app/[orgId]/sites/[niceId]/components/wireguardConfig.ts
diff --git a/src/app/[orgId]/sites/[niceId]/layout.tsx b/src/app/[orgId]/sites/[niceId]/layout.tsx
index 9a56761..a2278f4 100644
--- a/src/app/[orgId]/sites/[niceId]/layout.tsx
+++ b/src/app/[orgId]/sites/[niceId]/layout.tsx
@@ -11,6 +11,8 @@ import { redirect } from "next/navigation";
import { authCookieHeader } from "@app/api/cookies";
import Link from "next/link";
import { ArrowLeft, ChevronLeft } from "lucide-react";
+import { useEffect, useState } from "react";
+import { toast } from "@app/hooks/use-toast";
export const metadata: Metadata = {
title: "Forms",
@@ -46,6 +48,7 @@ export default async function SettingsLayout({
params,
}: SettingsLayoutProps) {
let site = null;
+
if (params.niceId !== "create") {
try {
const res = await internal.get>(
@@ -96,7 +99,7 @@ export default async function SettingsLayout({
{params.niceId == "create"
? "Create a new site"
: "Configure the settings on your site: " +
- site?.name || ""}
+ site?.name || ""}
.
diff --git a/src/app/[orgId]/sites/[niceId]/page.tsx b/src/app/[orgId]/sites/[niceId]/page.tsx
index 7bb23a9..c6147ec 100644
--- a/src/app/[orgId]/sites/[niceId]/page.tsx
+++ b/src/app/[orgId]/sites/[niceId]/page.tsx
@@ -1,7 +1,7 @@
import React from "react";
import { Separator } from "@/components/ui/separator";
-import { ProfileForm } from "@app/components/profile-form";
-import { CreateSiteForm } from "./components/create-site";
+import { CreateSiteForm } from "./components/CreateSite";
+import { GeneralForm } from "./components/GeneralForm";
export default function SettingsProfilePage({
params,
@@ -24,7 +24,7 @@ export default function SettingsProfilePage({
- {isCreateForm ? : }
+ {isCreateForm ? : }
);
}
diff --git a/src/contexts/siteContext.ts b/src/contexts/siteContext.ts
index e8e5612..0e35b8b 100644
--- a/src/contexts/siteContext.ts
+++ b/src/contexts/siteContext.ts
@@ -1,4 +1,11 @@
import { GetSiteResponse } from "@server/routers/site/getSite";
import { createContext } from "react";
-export const SiteContext = createContext(null);
+interface SiteContextType {
+ site: GetSiteResponse | null;
+ updateSite: (updatedSite: Partial) => Promise;
+}
+
+const SiteContext = createContext(undefined);
+
+export default SiteContext;
\ No newline at end of file
diff --git a/src/hooks/useSiteContext.ts b/src/hooks/useSiteContext.ts
index d944dc4..7397c47 100644
--- a/src/hooks/useSiteContext.ts
+++ b/src/hooks/useSiteContext.ts
@@ -1,7 +1,10 @@
-import { SiteContext } from "@app/contexts/siteContext";
+import SiteContext from "@app/contexts/siteContext";
import { useContext } from "react";
export function useSiteContext() {
- const site = useContext(SiteContext);
- return site;
-}
+ const context = useContext(SiteContext);
+ if (context === undefined) {
+ throw new Error('useSiteContext must be used within a SiteProvider');
+ }
+ return context;
+}
\ No newline at end of file
diff --git a/src/providers/SiteProvider.tsx b/src/providers/SiteProvider.tsx
index 2a01bcb..e1ab7d2 100644
--- a/src/providers/SiteProvider.tsx
+++ b/src/providers/SiteProvider.tsx
@@ -1,16 +1,44 @@
"use client";
-import { SiteContext } from "@app/contexts/siteContext";
+import api from "@app/api";
+import SiteContext from "@app/contexts/siteContext";
+import { toast } from "@app/hooks/use-toast";
import { GetSiteResponse } from "@server/routers/site/getSite";
-import { ReactNode } from "react";
+import { AxiosResponse } from "axios";
+import { useState } from "react";
-type LandingProviderProps = {
+interface SiteProviderProps {
+ children: React.ReactNode;
site: GetSiteResponse | null;
- children: ReactNode;
-};
-
-export function SiteProvider({ site, children }: LandingProviderProps) {
- return {children};
}
-export default SiteProvider;
+export function SiteProvider({ children, site: serverSite }: SiteProviderProps) {
+ const [site, setSite] = useState(serverSite);
+
+ const updateSite = async (updatedSite: Partial) => {
+ try {
+ if (!site) {
+ throw new Error("No site to update");
+ }
+
+ const res = await api.post>(
+ `site/${site.siteId}`,
+ updatedSite,
+ );
+ setSite(res.data.data);
+ toast({
+ title: "Site updated!",
+ });
+ } catch (error) {
+ console.error(error);
+ toast({
+ title: "Error updating site...",
+ })
+ }
+ };
+
+
+ return {children};
+}
+
+export default SiteProvider;
\ No newline at end of file
From 23fa2399debeff0fb4a5b5c6c4900c7f83b6e9bb Mon Sep 17 00:00:00 2001
From: Owen Schwartz
Date: Sat, 19 Oct 2024 13:11:34 -0400
Subject: [PATCH 2/2] Update site
---
.../[niceId]/components/ClientLayout.tsx | 54 +++++++++++++++++++
src/app/[orgId]/sites/[niceId]/layout.tsx | 53 +++---------------
src/app/[orgId]/sites/[niceId]/page.tsx | 8 +--
3 files changed, 65 insertions(+), 50 deletions(-)
create mode 100644 src/app/[orgId]/sites/[niceId]/components/ClientLayout.tsx
diff --git a/src/app/[orgId]/sites/[niceId]/components/ClientLayout.tsx b/src/app/[orgId]/sites/[niceId]/components/ClientLayout.tsx
new file mode 100644
index 0000000..a06b740
--- /dev/null
+++ b/src/app/[orgId]/sites/[niceId]/components/ClientLayout.tsx
@@ -0,0 +1,54 @@
+"use client";
+
+import { SidebarNav } from "@app/components/sidebar-nav";
+import { useSiteContext } from "@app/hooks/useSiteContext";
+
+const sidebarNavItems = [
+ {
+ title: "Profile",
+ href: "/{orgId}/sites/{niceId}",
+ },
+ {
+ title: "Appearance",
+ href: "/{orgId}/sites/{niceId}/appearance",
+ },
+ {
+ title: "Notifications",
+ href: "/{orgId}/sites/{niceId}/notifications",
+ },
+ {
+ title: "Display",
+ href: "/{orgId}/sites/{niceId}/display",
+ },
+];
+
+export function ClientLayout({ isCreate, children }: { isCreate: boolean; children: React.ReactNode }) {
+ const { site } = useSiteContext();
+ return (
+
+
+ {isCreate
+ ? "New Site"
+ : site?.name + " Settings"}
+
+
+ {isCreate
+ ? "Create a new site"
+ : "Configure the settings on your site: " +
+ site?.name || ""}
+ .
+
+
+
+
);
+}
\ No newline at end of file
diff --git a/src/app/[orgId]/sites/[niceId]/layout.tsx b/src/app/[orgId]/sites/[niceId]/layout.tsx
index a2278f4..d54a757 100644
--- a/src/app/[orgId]/sites/[niceId]/layout.tsx
+++ b/src/app/[orgId]/sites/[niceId]/layout.tsx
@@ -13,31 +13,13 @@ import Link from "next/link";
import { ArrowLeft, ChevronLeft } from "lucide-react";
import { useEffect, useState } from "react";
import { toast } from "@app/hooks/use-toast";
+import { ClientLayout } from "./components/ClientLayout";
export const metadata: Metadata = {
title: "Forms",
description: "Advanced form example using react-hook-form and Zod.",
};
-const sidebarNavItems = [
- {
- title: "Profile",
- href: "/{orgId}/sites/{niceId}",
- },
- {
- title: "Appearance",
- href: "/{orgId}/sites/{niceId}/appearance",
- },
- {
- title: "Notifications",
- href: "/{orgId}/sites/{niceId}/notifications",
- },
- {
- title: "Display",
- href: "/{orgId}/sites/{niceId}/display",
- },
-];
-
interface SettingsLayoutProps {
children: React.ReactNode;
params: { niceId: string; orgId: string };
@@ -88,33 +70,12 @@ export default async function SettingsLayout({
-
-
-
- {params.niceId == "create"
- ? "New Site"
- : site?.name + " Settings" || "Site Settings"}
-
-
- {params.niceId == "create"
- ? "Create a new site"
- : "Configure the settings on your site: " +
- site?.name || ""}
- .
-
-
-
-
+
+
+ {children}
+
>
);
}
diff --git a/src/app/[orgId]/sites/[niceId]/page.tsx b/src/app/[orgId]/sites/[niceId]/page.tsx
index c6147ec..43bb4d8 100644
--- a/src/app/[orgId]/sites/[niceId]/page.tsx
+++ b/src/app/[orgId]/sites/[niceId]/page.tsx
@@ -8,23 +8,23 @@ export default function SettingsProfilePage({
}: {
params: { niceId: string };
}) {
- const isCreateForm = params.niceId === "create";
+ const isCreate = params.niceId === "create";
return (
- {isCreateForm ? "Create Site" : "Profile"}
+ {isCreate ? "Create Site" : "Profile"}
- {isCreateForm
+ {isCreate
? "Create a new site for your profile."
: "This is how others will see you on the site."}
- {isCreateForm ?
:
}
+ {isCreate ?
:
}
);
}