+
{
- event.preventDefault()
- togglePassword()
- }}>
+ event.preventDefault();
+ togglePassword();
+ }}
+ >
{inputMask === "text" ? visible : hidden}
diff --git a/frontend/src/components/RegisterForm.tsx b/frontend/src/components/RegisterForm.tsx
index 50b13e2..6a413a5 100644
--- a/frontend/src/components/RegisterForm.tsx
+++ b/frontend/src/components/RegisterForm.tsx
@@ -1,4 +1,3 @@
-
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
@@ -20,6 +19,7 @@ import { passwordSchema, nameSchema } from "@/lib/utils/schemas";
import { Card, CardContent, CardFooter, CardHeader } from "./ui/card";
import { AxiosError } from "axios";
import type { ActiveTab } from "./AuthenticationTabs";
+import type React from "react";
const FormSchema = z
.object({
@@ -63,9 +63,7 @@ const RegisterForm = ({ setActiveTab }: RegisterFormProps) => {
toast({
variant: "destructive",
title: "Error during registration",
- description: (
-
{error.response.data?.error || "Unknown error"}
- ),
+ description:
{error.response.data?.error || "Unknown error"}
,
});
}
}
@@ -78,7 +76,8 @@ const RegisterForm = ({ setActiveTab }: RegisterFormProps) => {
Registration
- Make changes to your account here. Click 'Register' when you're done.
+ Make changes to your account here. Click 'Register' when you're
+ done.
@@ -149,13 +148,24 @@ const RegisterForm = ({ setActiveTab }: RegisterFormProps) => {
/>
-
- - or if you already have and account -
-
+
+
+ {" "}
+ - or if you already have and account -{" "}
+
+
-
-
+
+
);
};
diff --git a/frontend/src/components/ui/card.tsx b/frontend/src/components/ui/card.tsx
index 77e9fb7..75cc369 100644
--- a/frontend/src/components/ui/card.tsx
+++ b/frontend/src/components/ui/card.tsx
@@ -1,6 +1,6 @@
-import * as React from "react"
+import * as React from "react";
-import { cn } from "@/lib/utils"
+import { cn } from "@/lib/utils";
const Card = React.forwardRef<
HTMLDivElement,
@@ -10,12 +10,12 @@ const Card = React.forwardRef<
ref={ref}
className={cn(
"rounded-xl border bg-card text-card-foreground shadow",
- className
+ className,
)}
{...props}
/>
-))
-Card.displayName = "Card"
+));
+Card.displayName = "Card";
const CardHeader = React.forwardRef<
HTMLDivElement,
@@ -26,8 +26,8 @@ const CardHeader = React.forwardRef<
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
-))
-CardHeader.displayName = "CardHeader"
+));
+CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<
HTMLParagraphElement,
@@ -38,8 +38,8 @@ const CardTitle = React.forwardRef<
className={cn("font-semibold leading-none tracking-tight", className)}
{...props}
/>
-))
-CardTitle.displayName = "CardTitle"
+));
+CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<
HTMLParagraphElement,
@@ -50,16 +50,16 @@ const CardDescription = React.forwardRef<
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
-))
-CardDescription.displayName = "CardDescription"
+));
+CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes
>(({ className, ...props }, ref) => (
-))
-CardContent.displayName = "CardContent"
+));
+CardContent.displayName = "CardContent";
const CardFooter = React.forwardRef<
HTMLDivElement,
@@ -70,7 +70,14 @@ const CardFooter = React.forwardRef<
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
-))
-CardFooter.displayName = "CardFooter"
+));
+CardFooter.displayName = "CardFooter";
-export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardDescription,
+ CardContent,
+};
diff --git a/frontend/src/lib/utils/schemas.ts b/frontend/src/lib/utils/schemas.ts
index fc3599c..0b3daa9 100644
--- a/frontend/src/lib/utils/schemas.ts
+++ b/frontend/src/lib/utils/schemas.ts
@@ -1,28 +1,40 @@
-import { z } from "zod";
+import { z, ZodIssueCode } from "zod";
const nameSchema = z
.string()
.min(2, { message: "Name must be at least 2 characters long." })
.max(40, { message: "Name must be at most 40 characters long." });
-const passwordSchema = z
- .string()
- .min(4, { message: "Password must be at least 4 characters long." })
- .max(40, { message: "Password must be at most 40 characters long." })
- .refine((v) => !/\s/.test(v), {
- message: "Password cannot contain whitespace.",
- })
- .refine((v) => /[A-Z]/.test(v), {
- message: "Password must contain at least one uppercase letter.",
- })
- .refine((v) => /\d/.test(v), {
- message: "Password must contain at least one digit.",
- })
- .refine((v) => /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/.test(v), {
- message: "Password must contain at least one special character.",
- })
- .refine((v) => /[a-z]/.test(v), {
- message: "Password must contain at least one lowercase letter.",
- });
+const passwordSchema = z.string().superRefine((val, ctx): val is string => {
+ const issues: string[] = [];
+ if (val.length < 4) {
+ issues.push("at least 4 characters");
+ }
+ if (val.length > 40) {
+ issues.push("less then 40 characters");
+ }
+ if (/\s/.test(val)) {
+ issues.push("no whitespace");
+ }
+ if (!/[A-Z]/.test(val)) {
+ issues.push("at least one uppercase letter");
+ }
+ if (!/\d/.test(val)) {
+ issues.push("at least one digit");
+ }
+ if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/.test(val)) {
+ issues.push("at least one special character");
+ }
+ if (!/[a-z]/.test(val)) {
+ issues.push("at least one lowercase letter");
+ }
+ if (issues.length) {
+ ctx.addIssue({
+ code: ZodIssueCode.custom,
+ message: `Password must contain ${issues.join(", ")}.`,
+ });
+ }
+ return false;
+});
export { passwordSchema, nameSchema };
diff --git a/frontend/src/pages/Main.tsx b/frontend/src/pages/Main.tsx
index 1ca83b3..e0ccafc 100644
--- a/frontend/src/pages/Main.tsx
+++ b/frontend/src/pages/Main.tsx
@@ -2,7 +2,6 @@ import { Link } from "react-router-dom";
import { usePetClinicState } from "../state";
import { AuthenticationTabs } from "@/components/AuthenticationTabs";
-
export function Main() {
const { auth } = usePetClinicState();
const isAuthenticated = auth.token !== null;