Skip to content

Commit

Permalink
change network name, improved input element
Browse files Browse the repository at this point in the history
  • Loading branch information
sinamics committed Apr 7, 2023
1 parent 5c202e9 commit 1a06a12
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 44 deletions.
Empty file modified .devcontainer/init-cmd.sh
100644 → 100755
Empty file.
23 changes: 21 additions & 2 deletions src/components/elements/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { useEffect, useRef } from "react";

interface PasswordInputProps {
placeholder: string;
value: string;
value?: string;
name: string;
type: string;
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
focus?: boolean;
className?: string;
defaultValue?: string;
}

const Input = ({
Expand All @@ -15,6 +17,8 @@ const Input = ({
name,
onChange,
type,
className,
defaultValue,
focus = false,
...rest
}: PasswordInputProps) => {
Expand All @@ -25,14 +29,29 @@ const Input = ({
inputRef.current.focus();
}
}, [focus]);

useEffect(() => {
if (defaultValue && inputRef.current && onChange) {
const event = {
target: {
name: inputRef.current.name,
value: defaultValue,
},
};
onChange(event as React.ChangeEvent<HTMLInputElement>);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<input
type={type}
name={name}
placeholder={placeholder}
defaultValue={defaultValue}
value={value}
onChange={onChange}
className="input w-full max-w-xs"
className={`input w-full max-w-xs ${className}`}
ref={inputRef}
{...rest}
/>
Expand Down
3 changes: 3 additions & 0 deletions src/components/elements/inputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ interface FieldConfig {
type: string;
placeholder: string;
displayValue?: string;
defaultValue?: string;
}

interface FormProps {
label: string;
isLoading?: boolean;
placeholder?: string;
fields: FieldConfig[];

submitHandler: (formValues: {
[key: string]: string;
}) => Promise<unknown> | string | void;
Expand Down Expand Up @@ -71,6 +73,7 @@ const InputField = ({
value={formValues[field.name]}
onChange={handleChange}
name={field.name}
defaultValue={field.defaultValue}
/>
))}
<div className="flex gap-3">
Expand Down
29 changes: 29 additions & 0 deletions src/icons/copy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from "react";

interface Icon {
// add optional className prop
className?: string;
onClick?: () => void;
}

const CopyIcon = ({ className, onClick, ...rest }: Icon) => (
<span onClick={onClick}>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth="1.5"
stroke="currentColor"
className={`bg-op h-4 w-4 cursor-pointer text-primary ${className}`}
{...rest}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75"
/>
</svg>
</span>
);

export default CopyIcon;
4 changes: 2 additions & 2 deletions src/icons/edit.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
interface IeditIcon {
interface Icon {
// add optional className prop
className?: string;
onClick?: () => void;
}

const EditIcon = ({ className, onClick, ...rest }: IeditIcon) => {
const EditIcon = ({ className, onClick, ...rest }: Icon) => {
return (
<span onClick={onClick}>
<svg
Expand Down
84 changes: 73 additions & 11 deletions src/pages/network/[id].tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,103 @@
import { useRouter } from "next/router";
import { type ReactElement } from "react";
import { useState, type ReactElement } from "react";
import { LayoutAuthenticated } from "~/components/layouts/layout";
import { NettworkSettings } from "~/components/modules/networkRoutes";
import { NetworkMembersTable } from "~/components/modules/networkMembersTable";
import { api } from "~/utils/api";
import { NetworkIpAssignment } from "~/components/modules/networkIpAssignments";
import { NetworkPrivatePublic } from "~/components/modules/networkPrivatePublic";
import { AddMemberById } from "~/components/modules/addMemberById";
import CopyIcon from "~/icons/copy";
import { useCopyToClipboard } from "usehooks-ts";
import EditIcon from "~/icons/edit";
import Input from "~/components/elements/input";

const NetworkById = () => {
const [state, setState] = useState({
editNetworkName: false,
networkName: "",
});
const { query } = useRouter();
const { data: networkById, isLoading: loadingNetwork } =
api.network.getNetworkById.useQuery(
{
nwid: query.id as string,
},
{ enabled: !!query.id, refetchInterval: 10000 }
);
const {
data: networkById,
isLoading: loadingNetwork,
refetch: refetchNetwork,
} = api.network.getNetworkById.useQuery(
{
nwid: query.id as string,
},
{ enabled: !!query.id, refetchInterval: 10000 }
);
const { mutate: updateNetwork } = api.network.updateNetwork.useMutation();
const copy = useCopyToClipboard();

if (loadingNetwork) {
return <progress className="progress w-56"></progress>;
}

const { network, members } = networkById;
// console.log(zombieMembers);
const changeNameHandler = (e: React.ChangeEvent<HTMLFormElement>) => {
e.preventDefault();
updateNetwork(
{
nwid: network.nwid,
updateParams: { name: state.networkName },
},
{
onSuccess: () => {
void refetchNetwork();
setState({ ...state, editNetworkName: false });
},
}
);
};
const eventHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
setState({ ...state, [e.target.name]: e.target.value });
};
return (
<div>
<div className="w-5/5 mx-auto flex flex-row flex-wrap justify-between space-y-10 p-4 text-sm sm:w-4/5 sm:p-10 md:text-base xl:space-y-0">
<div className="w-5/5 h-fit w-full xl:w-2/6 ">
<div className="flex flex-col space-y-3 sm:space-y-0">
<div className="flex flex-col justify-between sm:flex-row">
<span className="font-semibold">Network ID:</span>
<span>{network?.nwid}</span>
<span className="relative left-7 flex items-center gap-2">
{network?.nwid}
<CopyIcon
className="hover:text-opacity-50"
onClick={() => void copy[1](network?.nwid)}
/>
</span>
</div>
<div className="flex flex-col justify-between sm:flex-row">
<span className="font-semibold">Network Name:</span>
<span>{network?.name}</span>
<span className="relative left-7 flex items-center gap-2">
{state.editNetworkName ? (
<form onSubmit={changeNameHandler}>
<Input
focus
name="networkName"
onChange={eventHandler}
// value={state.networkName}
defaultValue={network?.name}
type="text"
placeholder={network?.name}
className="input-bordered input-primary input-xs"
/>
</form>
) : (
network?.name
)}
<EditIcon
className="hover:text-opacity-50"
onClick={() =>
setState({
...state,
editNetworkName: !state.editNetworkName,
})
}
/>
</span>
</div>
<div className="flex flex-col justify-between sm:flex-row">
<span className="font-semibold">Network is</span>
Expand Down
2 changes: 2 additions & 0 deletions src/pages/profile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Profile = () => {
name: "name",
type: "text",
placeholder: session?.user?.name,
defaultValue: session?.user?.name,
},
]}
submitHandler={async (params) =>
Expand All @@ -52,6 +53,7 @@ const Profile = () => {
name: "email",
type: "text",
placeholder: session?.user?.email,
defaultValue: session?.user?.email,
},
]}
submitHandler={async (params) =>
Expand Down
40 changes: 16 additions & 24 deletions src/server/api/routers/adminRoute.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { z } from "zod";
import { createTRPCRouter, adminRoleProtectedRoute } from "~/server/api/trpc";
import * as ztController from "~/utils/ztApi";

Expand Down Expand Up @@ -28,30 +27,23 @@ export const adminRouter = createTRPCRouter({
},
});
return users;

// await ctx.prisma.user.findMany();
}),

getControllerStats: adminRoleProtectedRoute
// .input(
// z.object({
// userid: z.number().optional(),
// })
// )
.query(async () => {
const networks = await ztController.get_controller_networks();
const networkCount = networks.length;
let totalMembers = 0;
for (const network of networks) {
const members = await ztController.network_members(network);
totalMembers += Object.keys(members).length;
}
getControllerStats: adminRoleProtectedRoute.query(async () => {
const networks = await ztController.get_controller_networks();

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 {
networkCount,
totalMembers,
controllerStatus,
};
}),
const controllerStatus = await ztController.get_controller_status();
return {
networkCount,
totalMembers,
controllerStatus,
};
}),
});
33 changes: 28 additions & 5 deletions src/utils/ztApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,21 @@ export const get_controller_networks =
ZT_ADDR + "/controller/network",
options
);

return data;
} catch (err) {
throw err;
} catch (error) {
if (axios.isAxiosError(error)) {
const axiosError = error as AxiosError;
// eslint-disable-next-line no-console
console.error(`Axios error: ${axiosError.message}`);
// eslint-disable-next-line no-console
console.error(`Status code: ${axiosError.response?.status}`);
// eslint-disable-next-line no-console
console.error(`Status text: ${axiosError.response?.statusText}`);
throw axiosError;
}
// eslint-disable-next-line no-console
console.error(`Unknown error: ${error.message}`);
throw error;
}
};

Expand Down Expand Up @@ -119,8 +130,20 @@ export const get_controller_status = async function () {
try {
const { data } = await axios.get(ZT_ADDR + "/status", options);
return data as ZTControllerNodeStatus;
} catch (err) {
throw err;
} catch (error) {
if (axios.isAxiosError(error)) {
const axiosError = error as AxiosError;
// eslint-disable-next-line no-console
console.error(`Axios error: ${axiosError.message}`);
// eslint-disable-next-line no-console
console.error(`Status code: ${axiosError.response?.status}`);
// eslint-disable-next-line no-console
console.error(`Status text: ${axiosError.response?.statusText}`);
throw axiosError;
}
// eslint-disable-next-line no-console
console.error(`Unknown error: ${error.message}`);
throw error;
}
};

Expand Down

0 comments on commit 1a06a12

Please sign in to comment.