Skip to content

Commit 91e2465

Browse files
signUpForm use-form hook set up
1 parent e0c75e0 commit 91e2465

File tree

4 files changed

+28
-29
lines changed

4 files changed

+28
-29
lines changed

frontend/eslint.config.mjs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@ const eslintConfig = [
1313
{
1414
ignores: ["src/client/**"], // ✅ Ignore generated OpenAPI client
1515
},
16-
...compat.extends("next/core-web-vitals", "next/typescript"),
16+
...compat.config({
17+
extends: ["next/core-web-vitals", "next/typescript"],
18+
19+
rules: {
20+
"@typescript-eslint/no-explicit-any": "warn",
21+
},
22+
}),
1723
];
1824

1925
export default eslintConfig;

frontend/src/app/layout.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
'use client';
2-
3-
import { Outfit } from 'next/font/google';
42
import './globals.css';
53

64
import { SidebarProvider } from '@/context/SidebarContext';
75
import { ThemeProvider } from '@/context/ThemeContext';
86
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
97

10-
const outfit = Outfit({
11-
subsets: ["latin"],
12-
});
13-
148
const queryClient = new QueryClient();
159

1610

frontend/src/components/auth/SignUpForm.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ export default function SignUpForm() {
1919
register,
2020
handleSubmit,
2121
formState: { errors },
22-
} = useForm<FormData>();
23-
22+
} = useForm<FormData>({
23+
mode: "onChange"
24+
});
2425
const onSubmit = (data: FormData) => {
2526
console.log("Form data:", data);
2627
};
Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { FC } from "react";
1+
import React, { forwardRef } from "react";
22

33
interface InputProps {
44
type?: "text" | "number" | "email" | "password" | "date" | "time" | string;
@@ -7,23 +7,25 @@ interface InputProps {
77
placeholder?: string;
88
defaultValue?: string | number;
99
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
10+
onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void; // new
1011
className?: string;
1112
min?: string | number;
1213
max?: string | number;
1314
step?: number;
1415
disabled?: boolean;
1516
success?: boolean;
1617
error?: boolean;
17-
hint?: string; // Optional hint text
18+
hint?: string;
1819
}
1920

20-
const Input: FC<InputProps> = ({
21+
const Input = forwardRef<HTMLInputElement, InputProps>(({
2122
type = "text",
2223
id,
2324
name,
2425
placeholder,
2526
defaultValue,
2627
onChange,
28+
onBlur, // new
2729
className = "",
2830
min,
2931
max,
@@ -32,53 +34,49 @@ const Input: FC<InputProps> = ({
3234
success = false,
3335
error = false,
3436
hint,
35-
}) => {
36-
// Determine input styles based on state (disabled, success, error)
37+
...rest // catch other props (like ref will be forwarded automatically)
38+
}, ref) => {
3739
let inputClasses = `h-11 w-full rounded-lg border appearance-none px-4 py-2.5 text-sm shadow-theme-xs placeholder:text-gray-400 focus:outline-hidden focus:ring-3 dark:bg-gray-900 dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800 ${className}`;
3840

39-
// Add styles for the different states
4041
if (disabled) {
4142
inputClasses += ` text-gray-500 border-gray-300 cursor-not-allowed dark:bg-gray-800 dark:text-gray-400 dark:border-gray-700`;
4243
} else if (error) {
43-
inputClasses += ` text-error-800 border-error-500 focus:ring-3 focus:ring-error-500/10 dark:text-error-400 dark:border-error-500`;
44+
inputClasses += ` text-error-800 border-error-500 focus:ring-3 focus:ring-error-500/10 dark:text-error-400 dark:border-error-500`;
4445
} else if (success) {
45-
inputClasses += ` text-success-500 border-success-400 focus:ring-success-500/10 focus:border-success-300 dark:text-success-400 dark:border-success-500`;
46+
inputClasses += ` text-success-500 border-success-400 focus:ring-success-500/10 focus:border-success-300 dark:text-success-400 dark:border-success-500`;
4647
} else {
4748
inputClasses += ` bg-transparent text-gray-800 border-gray-300 focus:border-brand-300 focus:ring-3 focus:ring-brand-500/10 dark:border-gray-700 dark:bg-gray-900 dark:text-white/90 dark:focus:border-brand-800`;
4849
}
4950

5051
return (
5152
<div className="relative">
5253
<input
54+
ref={ref}
5355
type={type}
5456
id={id}
5557
name={name}
5658
placeholder={placeholder}
5759
defaultValue={defaultValue}
5860
onChange={onChange}
61+
onBlur={onBlur}
5962
min={min}
6063
max={max}
6164
step={step}
6265
disabled={disabled}
6366
className={inputClasses}
67+
{...rest}
6468
/>
65-
66-
{/* Optional Hint Text */}
6769
{hint && (
68-
<p
69-
className={`mt-1.5 text-xs ${
70-
error
71-
? "text-error-500"
72-
: success
73-
? "text-success-500"
74-
: "text-gray-500"
75-
}`}
76-
>
70+
<p className={`mt-1.5 text-xs ${
71+
error ? "text-error-500" : success ? "text-success-500" : "text-gray-500"
72+
}`}>
7773
{hint}
7874
</p>
7975
)}
8076
</div>
8177
);
82-
};
78+
});
79+
80+
Input.displayName = "Input";
8381

8482
export default Input;

0 commit comments

Comments
 (0)