feat: updated admin dashboard to use zod and ts enum

This commit is contained in:
Akhil Mohan
2024-02-16 13:41:18 +05:30
parent a1cc118514
commit 97d2a15d3e
@@ -3,8 +3,8 @@ import { Controller, useForm } from "react-hook-form";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { faAt } from "@fortawesome/free-solid-svg-icons"; import { faAt } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { yupResolver } from "@hookform/resolvers/yup"; import { zodResolver } from "@hookform/resolvers/zod";
import * as yup from "yup"; import { z } from "zod";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import { import {
@@ -26,31 +26,42 @@ enum TabSections {
Settings = "settings" Settings = "settings"
} }
const formSchema = yup.object({ enum SignUpModes {
signUpMode: yup Disabled = "disabled",
.string() InviteOnly = "invite-only",
.oneOf(["disabled", "invite-only", "anyone"]) Anyone = "anyone"
.required(), }
allowedSignUpDomain: yup.string().optional()
const getSignUpMode = (isSignUpEnabled: boolean, isInviteOnly: boolean) => {
if (isSignUpEnabled) {
if (isInviteOnly) return SignUpModes.InviteOnly;
return SignUpModes.Anyone;
}
return SignUpModes.Disabled;
};
const formSchema = z.object({
signUpMode: z.nativeEnum(SignUpModes),
allowedSignUpDomain: z.string().optional()
}); });
type TDashboardForm = yup.InferType<typeof formSchema>; type TDashboardForm = z.infer<typeof formSchema>;
export const AdminDashboardPage = () => { export const AdminDashboardPage = () => {
const router = useRouter(); const router = useRouter();
const data = useServerConfig(); const data = useServerConfig();
const { config } = data; const { config } = data;
const signUpStatus = config.allowSignUp const {
? config.inviteOnlySignUp && "invite-only" control,
: "disabled"; handleSubmit,
watch,
const signUpType = signUpStatus || "anyone"; getValues,
formState: { isSubmitting, isDirty }
const { control, handleSubmit, watch } = useForm<TDashboardForm>({ } = useForm<TDashboardForm>({
resolver: yupResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { values: {
signUpMode: signUpType, // eslint-disable-next-line
signUpMode: getSignUpMode(config.allowSignUp, config.inviteOnlySignUp),
allowedSignUpDomain: config.allowedSignUpDomain allowedSignUpDomain: config.allowedSignUpDomain
} }
}); });
@@ -59,12 +70,13 @@ export const AdminDashboardPage = () => {
const { user, isLoading: isUserLoading } = useUser(); const { user, isLoading: isUserLoading } = useUser();
const { orgs } = useOrganization(); const { orgs } = useOrganization();
const { mutate: updateServerConfig } = useUpdateServerConfig(); const { mutateAsync: updateServerConfig } = useUpdateServerConfig();
const { createNotification } = useNotificationContext(); const { createNotification } = useNotificationContext();
const isNotAllowed = !user?.superAdmin; const isNotAllowed = !user?.superAdmin;
// TODO(akhilmhdh): on nextjs 14 roadmap this will be properly addressed with context split
useEffect(() => { useEffect(() => {
if (isNotAllowed && !isUserLoading) { if (isNotAllowed && !isUserLoading) {
if (orgs?.length) { if (orgs?.length) {
@@ -77,13 +89,11 @@ export const AdminDashboardPage = () => {
const onFormSubmit = async (formData: TDashboardForm) => { const onFormSubmit = async (formData: TDashboardForm) => {
try { try {
const { signUpMode, allowedSignUpDomain } = formData; const { signUpMode, allowedSignUpDomain } = formData;
await updateServerConfig({ await updateServerConfig({
allowSignUp: signUpMode !== "disabled", allowSignUp: signUpMode !== SignUpModes.Disabled,
inviteOnlySignUp: signUpMode === "invite-only", inviteOnlySignUp: signUpMode === SignUpModes.InviteOnly,
allowedSignUpDomain: signUpMode === "anyone" ? allowedSignUpDomain : "" allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : ""
}); });
createNotification({ createNotification({
text: "Successfully changed sign up setting.", text: "Successfully changed sign up setting.",
type: "success" type: "success"
@@ -97,8 +107,7 @@ export const AdminDashboardPage = () => {
} }
}; };
console.log(isDirty,getValues());
return ( return (
<div className="container mx-auto max-w-7xl px-4 pb-12 text-white dark:[color-scheme:dark]"> <div className="container mx-auto max-w-7xl px-4 pb-12 text-white dark:[color-scheme:dark]">
<div className="mx-auto mb-6 w-full max-w-7xl pt-6"> <div className="mx-auto mb-6 w-full max-w-7xl pt-6">
@@ -142,15 +151,14 @@ export const AdminDashboardPage = () => {
onValueChange={(e) => onChange(e)} onValueChange={(e) => onChange(e)}
{...field} {...field}
> >
<SelectItem value="disabled">Disabled</SelectItem> <SelectItem value={SignUpModes.Disabled}>Disabled</SelectItem>
<SelectItem value="invite-only">Invite Only</SelectItem> <SelectItem value={SignUpModes.InviteOnly}>Invite Only</SelectItem>
<SelectItem value="anyone">Anyone</SelectItem> <SelectItem value={SignUpModes.Anyone}>Anyone</SelectItem>
</Select> </Select>
</FormControl> </FormControl>
)} )}
/> />
</div> </div>
{signupMode === "anyone" && ( {signupMode === "anyone" && (
<div className="mt-4 flex items-center justify-between"> <div className="mt-4 flex items-center justify-between">
<div className="mb-4 flex text-mineshaft-100"> <div className="mb-4 flex text-mineshaft-100">
@@ -177,8 +185,11 @@ export const AdminDashboardPage = () => {
/> />
</div> </div>
)} )}
<Button
<Button colorSchema="primary" variant="outline_bg" type="submit"> type="submit"
isLoading={isSubmitting}
isDisabled={isSubmitting || !isDirty}
>
Save Save
</Button> </Button>
</form> </form>