Files
dokploy/apps/dokploy/pages/reset-password.tsx
T
Mauricio Siu 8ab6d6b282 chore: clean up unused variables and improve error handling across codebase
This commit focuses on removing unused variables, adding placeholder error handling, and generally tidying up various files across the Dokploy application. Changes include:

- Removing unused imports and variables
- Adding placeholder error handling in catch blocks
- Cleaning up commented-out code
- Removing deprecated utility files
- Improving type safety and code consistency
2025-02-22 20:35:21 -06:00

229 lines
5.3 KiB
TypeScript

import { OnboardingLayout } from "@/components/layouts/onboarding-layout";
import { AlertBlock } from "@/components/shared/alert-block";
import { Logo } from "@/components/shared/logo";
import { Button } from "@/components/ui/button";
import { CardContent, CardDescription, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { db } from "@/server/db";
import { auth } from "@/server/db/schema";
import { api } from "@/utils/api";
import { IS_CLOUD } from "@dokploy/server";
import { zodResolver } from "@hookform/resolvers/zod";
import { isBefore } from "date-fns";
import { eq } from "drizzle-orm";
import type { GetServerSidePropsContext } from "next";
import Link from "next/link";
import { useRouter } from "next/router";
import { type ReactElement, useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const loginSchema = z
.object({
password: z
.string()
.min(1, {
message: "Password is required",
})
.min(8, {
message: "Password must be at least 8 characters",
}),
confirmPassword: z
.string()
.min(1, {
message: "Password is required",
})
.min(8, {
message: "Password must be at least 8 characters",
}),
})
.refine((data) => data.password === data.confirmPassword, {
message: "Passwords do not match",
path: ["confirmPassword"],
});
type Login = z.infer<typeof loginSchema>;
interface Props {
token: string;
}
export default function Home({ token }: Props) {
const { mutateAsync, isLoading, isError, error } =
api.auth.resetPassword.useMutation();
const router = useRouter();
const form = useForm<Login>({
defaultValues: {
password: "",
confirmPassword: "",
},
resolver: zodResolver(loginSchema),
});
useEffect(() => {
form.reset();
}, [form, form.reset, form.formState.isSubmitSuccessful]);
const onSubmit = async (values: Login) => {
await mutateAsync({
resetPasswordToken: token,
password: values.password,
})
.then((_data) => {
toast.success("Password reset successfully", {
duration: 2000,
});
router.push("/");
})
.catch(() => {
toast.error("Error resetting password", {
duration: 2000,
});
});
};
return (
<div className="flex h-screen w-full items-center justify-center ">
<div className="flex flex-col items-center gap-4 w-full">
<CardTitle className="text-2xl font-bold flex flex-row gap-2 items-center">
<Link href="/" className="flex flex-row items-center gap-2">
<Logo className="size-12" />
</Link>
Reset Password
</CardTitle>
<CardDescription>
Enter your email to reset your password
</CardDescription>
<div className="w-full">
<CardContent className="p-0">
{isError && (
<AlertBlock type="error" className="my-2">
{error?.message}
</AlertBlock>
)}
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid gap-4"
>
<div className="space-y-4">
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input
type="password"
placeholder="Password"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="confirmPassword"
render={({ field }) => (
<FormItem>
<FormLabel>Confirm Password</FormLabel>
<FormControl>
<Input
type="password"
placeholder="Password"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
type="submit"
isLoading={isLoading}
className="w-full"
>
Confirm
</Button>
</div>
<div className="text-center text-sm flex gap-2 text-muted-foreground">
<Link href="/">Sign in</Link>
</div>
</form>
</Form>
</CardContent>
</div>
</div>
</div>
);
}
Home.getLayout = (page: ReactElement) => {
return <OnboardingLayout>{page}</OnboardingLayout>;
};
export async function getServerSideProps(context: GetServerSidePropsContext) {
if (!IS_CLOUD) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
const { token } = context.query;
if (typeof token !== "string") {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
const authR = await db.query.auth.findFirst({
where: eq(auth.resetPasswordToken, token),
});
if (!authR || authR?.resetPasswordExpiresAt === null) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
const isExpired = isBefore(
new Date(authR.resetPasswordExpiresAt),
new Date(),
);
if (isExpired) {
return {
redirect: {
permanent: true,
destination: "/",
},
};
}
return {
props: {
token: authR.resetPasswordToken,
},
};
}