Skip to content

Commit

Permalink
settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
sinamics committed Apr 6, 2023
1 parent b35c34a commit 84dd59e
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 79 deletions.
34 changes: 34 additions & 0 deletions src/components/modules/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,40 @@ const Sidebar = (): JSX.Element => {
<span className="ml-3">ZT Controller</span>
</Link>
</li>
<li className="my-px">
<Link
href="/admin/settings"
className={`flex h-10 flex-row items-center rounded-lg px-3
${
router.pathname === "/admin/settings"
? "bg-gray-100 text-gray-700"
: "hover:bg-slate-700"
}`}
>
<span className="flex items-center justify-center text-lg text-gray-400">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
className="h-6 w-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M10.343 3.94c.09-.542.56-.94 1.11-.94h1.093c.55 0 1.02.398 1.11.94l.149.894c.07.424.384.764.78.93.398.164.855.142 1.205-.108l.737-.527a1.125 1.125 0 011.45.12l.773.774c.39.389.44 1.002.12 1.45l-.527.737c-.25.35-.272.806-.107 1.204.165.397.505.71.93.78l.893.15c.543.09.94.56.94 1.109v1.094c0 .55-.397 1.02-.94 1.11l-.893.149c-.425.07-.765.383-.93.78-.165.398-.143.854.107 1.204l.527.738c.32.447.269 1.06-.12 1.45l-.774.773a1.125 1.125 0 01-1.449.12l-.738-.527c-.35-.25-.806-.272-1.203-.107-.397.165-.71.505-.781.929l-.149.894c-.09.542-.56.94-1.11.94h-1.094c-.55 0-1.019-.398-1.11-.94l-.148-.894c-.071-.424-.384-.764-.781-.93-.398-.164-.854-.142-1.204.108l-.738.527c-.447.32-1.06.269-1.45-.12l-.773-.774a1.125 1.125 0 01-.12-1.45l.527-.737c.25-.35.273-.806.108-1.204-.165-.397-.505-.71-.93-.78l-.894-.15c-.542-.09-.94-.56-.94-1.109v-1.094c0-.55.398-1.02.94-1.11l.894-.149c.424-.07.765-.383.93-.78.165-.398.143-.854-.107-1.204l-.527-.738a1.125 1.125 0 01.12-1.45l.773-.773a1.125 1.125 0 011.45-.12l.737.527c.35.25.807.272 1.204.107.397-.165.71-.505.78-.929l.15-.894z"
/>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
/>
</svg>
</span>
<span className="ml-3">Settings</span>
</Link>
</li>
</>
) : null}
<li className="my-px">
Expand Down
65 changes: 61 additions & 4 deletions src/pages/admin/controller/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,75 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { clearConfigCache } from "prettier";
import { type ReactElement } from "react";
import { LayoutAuthenticated } from "~/components/layouts/layout";
import { api } from "~/utils/api";

const Controller = () => {
const { data: controllerStats } = api.admin.getControllerStats.useQuery({});
const { data: controllerData, isLoading } =
api.admin.getControllerStats.useQuery();

if (isLoading) {
return <div>Loading...</div>;
}

const { networkCount, totalMembers, controllerStatus } = controllerData;

const { allowManagementFrom, allowTcpFallbackRelay, listeningOn } =
controllerStatus?.config?.settings;

const { online, tcpFallbackActive, version } = controllerStatus;

return (
<div>
Controller
<pre>{JSON.stringify(controllerStats, null, 2)}</pre>
<div className="flex items-center justify-center ">
<div className="grid grid-cols-1 gap-5 space-y-4 pt-10 md:space-y-0 lg:grid-cols-2 xl:grid-cols-3">
<div className="card card-normal w-60 bg-base-300 sm:w-96">
<div className="card-body flex-grow-0">
<h2 className="card-title flex justify-center">Networks</h2>
<p className="">Network Count: {networkCount}</p>
<p className="">Total Members: {totalMembers}</p>
</div>
</div>
<div className="card card-normal w-60 bg-base-300 sm:w-96">
<div className="card-body">
<h2 className="card-title flex justify-center">Controller TCP</h2>
<p className="">Allow Management From:</p>
<ul className="list-inside list-disc">
{allowManagementFrom.map((address, index) => (
<li key={index}>{address}</li>
))}
</ul>
<p className="">
Allow TCP Fallback Relay: {allowTcpFallbackRelay ? "Yes" : "No"}
</p>
<p className="">Listening On:</p>
<ul className="list-inside list-disc">
{listeningOn.map((address, index) => (
<li key={index}>{address}</li>
))}
</ul>
</div>
</div>

<div className="card card-normal w-60 bg-base-300 sm:w-96">
<div className="card-body flex-grow-0">
<h2 className="card-title flex justify-center">
Controller Stats
</h2>
<p className="">Online: {online ? "Yes" : "No"}</p>
<p className="">
TCP Fallback Active: {tcpFallbackActive ? "Yes" : "No"}
</p>
<p className="">Version: {version}</p>
</div>
</div>
</div>
</div>
</div>
);
};

Controller.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};

export default Controller;
45 changes: 45 additions & 0 deletions src/pages/admin/settings/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { clearConfigCache } from "prettier";
import { type ReactElement } from "react";
import { LayoutAuthenticated } from "~/components/layouts/layout";
import { api } from "~/utils/api";

const Settings = () => {
const { mutate: setOptions } = api.options.update.useMutation();

const { data: options, refetch: refetchOptions } =
api.options.getAll.useQuery();

return (
<div>
<div className="flex items-center justify-center pt-10">
<div className="flex space-x-4">
<div className="card card-normal w-96 bg-base-300">
<div className="card-body">
<h2 className="card-title flex justify-center">Site Settings</h2>
<div className="flex items-center">
<p>Enable user registration?</p>
<input
type="checkbox"
checked={options?.enableRegistration}
className="checkbox-primary checkbox"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setOptions(
{ enableRegistration: e.target.checked },
{ onSuccess: () => void refetchOptions() }
);
}}
/>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
Settings.getLayout = function getLayout(page: ReactElement) {
return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};

export default Settings;
2 changes: 2 additions & 0 deletions src/server/api/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { authRouter } from "./routers/authRouter";
import { networkMemberRouter } from "./routers/networkMemberRouter";
import { networkRouter } from "./routers/networkRouter";
import { adminRouter } from "./routers/adminRoute";
import { globalOptionsRouter } from "./routers/globalOptions";

/**
* This is the primary router for your server.
Expand All @@ -14,6 +15,7 @@ export const appRouter = createTRPCRouter({
networkMember: networkMemberRouter,
auth: authRouter,
admin: adminRouter,
options: globalOptionsRouter,
});

// export type definition of API
Expand Down
55 changes: 15 additions & 40 deletions src/server/api/routers/adminRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,50 +33,25 @@ export const adminRouter = createTRPCRouter({
}),

getControllerStats: adminRoleProtectedRoute
.input(
z.object({
userid: z.number().optional(),
})
)
.query(async ({ ctx, input }) => {
const controllerVersion = await ztController.get_controller_version();

// .input(
// z.object({
// userid: z.number().optional(),
// })
// )
.query(async () => {
const networks = await ztController.get_controller_networks();

const nodes = [];
let totalNodes = 0;
for (let index = 0; index < networks.length; index++) {
const networkMembers = await ctx.prisma.network.findFirst({
where: {
nwid: networks[index],
},
include: {
nw_userid: true,
},
});

// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
const nDet = await ztController.network_detail(networks[index]);
totalNodes += nDet.members.length;
nodes.push({ ...nDet, author: { ...networkMembers } });
}
// admin wants networks for a specific user
if (input.userid && !isNaN(input.userid)) {
const filterNodes = nodes.filter(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
(u: any) => u.author.authorId === input.userid
);
return {
controllerVersion,
nodes: filterNodes,
stats: { totalNodes, totalNetworks: nodes.length },
};
const networkCount = networks.length;
let totalMembers = 0;
for (const network of networks) {
const members = await ztController.network_members(network);
totalMembers += Object.keys(members).length;
}

const controllerStatus = await ztController.get_controller_status();
return {
controllerVersion,
nodes,
stats: { totalNodes, totalNetworks: nodes.length },
networkCount,
totalMembers,
controllerStatus,
};
}),
});
2 changes: 1 addition & 1 deletion src/server/api/routers/authRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export const authRouter = createTRPCRouter({
if (!settings.enableRegistration) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Registration is disabled!`,
message: `Registration is disabled! Please contact the administrator.`,
});
}

Expand Down
25 changes: 0 additions & 25 deletions src/server/api/routers/example.ts

This file was deleted.

29 changes: 29 additions & 0 deletions src/server/api/routers/globalOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { z } from "zod";
import { createTRPCRouter, adminRoleProtectedRoute } from "~/server/api/trpc";

export const globalOptionsRouter = createTRPCRouter({
update: adminRoleProtectedRoute
.input(
z.object({
enableRegistration: z.boolean().optional(),
firstUserRegistration: z.boolean().optional(),
})
)
.mutation(async ({ ctx, input }) => {
return await ctx.prisma.globalOptions.update({
where: {
id: 1,
},
data: {
...input,
},
});
}),
getAll: adminRoleProtectedRoute.query(async ({ ctx }) => {
return await ctx.prisma.globalOptions.findFirst({
where: {
id: 1,
},
});
}),
});
Loading

0 comments on commit 84dd59e

Please sign in to comment.