Browse Source

Type Definitions completed

main
sina_sajjadi 2 months ago
parent
commit
b3aae1d173
  1. 8
      src/app/(account-pages)/account/page.tsx
  2. 27
      src/app/signup/otp-code/page.tsx
  3. 53
      src/app/signup/page.tsx
  4. 20
      src/hooks/FormValidation.ts
  5. 2
      src/shared/Button.tsx

8
src/app/(account-pages)/account/page.tsx

@ -27,12 +27,12 @@ interface LoadingState {
} }
interface APIResponse { interface APIResponse {
data: {
avatar: string; avatar: string;
email: string; email: string;
fullname: string; fullname: string;
phone_number: string; phone_number: string;
};
} }
const AccountPage: FC<AccountPageProps> = () => { const AccountPage: FC<AccountPageProps> = () => {
@ -133,12 +133,12 @@ const AccountPage: FC<AccountPageProps> = () => {
}; };
const handleFileChange = async (e: ChangeEvent<HTMLInputElement>): Promise<void> => { const handleFileChange = async (e: ChangeEvent<HTMLInputElement>): Promise<void> => {
const file = e.target.files?.[0];
const file : File | undefined = e.target.files?.[0];
if (file) { if (file) {
const uploadedFile = await getImageURL(file); const uploadedFile = await getImageURL(file);
setImageURL(uploadedFile.url); setImageURL(uploadedFile.url);
setImage(file);
} }
setImage(file);
}; };
return ( return (

27
src/app/signup/otp-code/page.tsx

@ -4,15 +4,14 @@ import React, { FC, useContext, useState, useEffect, useRef } from "react";
import ButtonPrimary from "@/shared/ButtonPrimary"; import ButtonPrimary from "@/shared/ButtonPrimary";
import axiosInstance from "@/components/api/axios"; import axiosInstance from "@/components/api/axios";
import { useUserContext } from "@/components/contexts/userContext"; import { useUserContext } from "@/components/contexts/userContext";
import useFormValidation from "@/hooks/FormValidation";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
export interface PageSignUpProps {} export interface PageSignUpProps {}
const PageSignUp: FC<PageSignUpProps> = () => { const PageSignUp: FC<PageSignUpProps> = () => {
const router = useRouter(); const router = useRouter();
const { form } = useUserContext();
const { user, setUser } = useUserContext();
const { form, user, setUser } = useUserContext();
useEffect(() => { useEffect(() => {
if (Object.keys(user).length) { if (Object.keys(user).length) {
router.replace("/"); router.replace("/");
@ -21,7 +20,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
const [otp, setOtp] = useState(["", "", "", "", ""]); const [otp, setOtp] = useState(["", "", "", "", ""]);
const [time, setTime] = useState(30); const [time, setTime] = useState(30);
const [error, setError] = useState("");
const [error, setError] = useState<string>("");
const otpRefs = useRef<(HTMLInputElement | null)[]>([]); const otpRefs = useRef<(HTMLInputElement | null)[]>([]);
const handleOtpChange = (value: string, index: number) => { const handleOtpChange = (value: string, index: number) => {
@ -46,10 +45,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
useEffect(() => { useEffect(() => {
if (time > 0) { if (time > 0) {
const timer = setInterval(
() => setTime((prevTime) => prevTime - 1),
1000
);
const timer = setInterval(() => setTime((prevTime) => prevTime - 1), 1000);
return () => clearInterval(timer); return () => clearInterval(timer);
} }
}, [time]); }, [time]);
@ -57,7 +53,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
const handleResend = () => { const handleResend = () => {
if (time === 0) { if (time === 0) {
setTime(30); setTime(30);
// Add logic to resend OTP here if needed
// Logic to resend OTP can be added here
} }
}; };
@ -75,7 +71,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
} else { } else {
setError("Something went wrong. Please try again."); setError("Something went wrong. Please try again.");
} }
} catch (error) {
} catch (error: any) { // Cast to 'any' or a specific error type
setError(error.response?.data?.message || "An error occurred."); setError(error.response?.data?.message || "An error occurred.");
} }
}; };
@ -87,8 +83,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
Verification Code Verification Code
</h2> </h2>
<p className="text-center text-sm text-neutral-500 mb-4"> <p className="text-center text-sm text-neutral-500 mb-4">
Enter the 5-digit code that we sent to complete your account
registration
Enter the 5-digit code that we sent to complete your account registration
</p> </p>
<div className="max-w-sm mx-auto space-y-6"> <div className="max-w-sm mx-auto space-y-6">
<div className="flex justify-center space-x-2 mb-4"> <div className="flex justify-center space-x-2 mb-4">
@ -108,17 +103,13 @@ const PageSignUp: FC<PageSignUpProps> = () => {
<p className="text-center text-sm text-neutral-500 mb-4"> <p className="text-center text-sm text-neutral-500 mb-4">
Haven't got the confirmation code yet?{" "} Haven't got the confirmation code yet?{" "}
<button <button
className={`text-primary-600 hover:underline ${
time > 0 ? "cursor-not-allowed opacity-50" : "cursor-pointer"
}`}
className={`text-primary-600 hover:underline ${time > 0 ? "cursor-not-allowed opacity-50" : "cursor-pointer"}`}
onClick={handleResend} onClick={handleResend}
disabled={time > 0} disabled={time > 0}
> >
Resend Resend
</button> </button>
{time > 0 && (
<span className="text-xs text-neutral-400">({time} Seconds)</span>
)}
{time > 0 && <span className="text-xs text-neutral-400">({time} Seconds)</span>}
</p> </p>
{error && <p className="text-red-500 text-xs">{error}</p>} {error && <p className="text-red-500 text-xs">{error}</p>}
<ButtonPrimary <ButtonPrimary

53
src/app/signup/page.tsx

@ -1,6 +1,6 @@
"use client"; "use client";
import React, { FC, useContext, useState } from "react";
import React, { FC, useState, useEffect } from "react";
import Input from "@/shared/Input"; import Input from "@/shared/Input";
import ButtonPrimary from "@/shared/ButtonPrimary"; import ButtonPrimary from "@/shared/ButtonPrimary";
import Link from "next/link"; import Link from "next/link";
@ -13,27 +13,28 @@ export interface PageSignUpProps {}
const PageSignUp: FC<PageSignUpProps> = () => { const PageSignUp: FC<PageSignUpProps> = () => {
const router = useRouter(); const router = useRouter();
const {user} = useUserContext()
const { user, setForm, setMethod } = useUserContext();
if (Object.keys(user).length) {
router.replace("/");
return null;
}
// Redirect if user is already logged in
useEffect(() => {
if (Object.keys(user).length) {
router.replace("/");
}
}, [user, router]);
const { setForm, setMethod } = useUserContext();
const [name, setName] = useState("");
const [countryCode, setCountryCode] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [loading, setLoading] = useState(false);
const [failed , setFailed ] =useState("")
const [name, setName] = useState<string>("");
const [countryCode, setCountryCode] = useState<string>("");
const [phoneNumber, setPhoneNumber] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [confirmPassword, setConfirmPassword] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
const [failed, setFailed] = useState<string>("");
const { errors, validateForm } = useFormValidation(); const { errors, validateForm } = useFormValidation();
const countryCodeHandler = (e) => {
const countryCodeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value.length <= 3) { if (e.target.value.length <= 3) {
setCountryCode(e.target.value); setCountryCode(e.target.value);
} }
@ -46,7 +47,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
phoneNumber, phoneNumber,
password, password,
confirmPassword, confirmPassword,
verification_methodes : "" ,
verification_methodes: "",
method: "register", method: "register",
}; };
@ -57,18 +58,16 @@ const PageSignUp: FC<PageSignUpProps> = () => {
const response = await axiosInstance.get( const response = await axiosInstance.get(
`/api/account/verfication/?range_phone=${countryCode}&phone_number=${phoneNumber}` `/api/account/verfication/?range_phone=${countryCode}&phone_number=${phoneNumber}`
); );
form.verification_methodes = response.data.verification_method ;
form.verification_methodes = response.data.verification_method;
router.push("/signup/methodes"); router.push("/signup/methodes");
} catch (error) {
} catch (error: any) {
console.error("Error fetching data:", error); console.error("Error fetching data:", error);
setFailed(error.message)
setFailed(error.message || "An error occurred.");
} finally { } finally {
setLoading(false); setLoading(false);
} }
} else { } else {
console.log("Form has errors:", errors); console.log("Form has errors:", errors);
} }
}; };
@ -92,7 +91,7 @@ const PageSignUp: FC<PageSignUpProps> = () => {
{errors.name && <p className="text-xs text-red-600">{errors.name}</p>} {errors.name && <p className="text-xs text-red-600">{errors.name}</p>}
</label> </label>
<label className="block"> <label className="block">
<span className=" text-neutral-800 dark:text-neutral-200">Phone Number</span>
<span className="text-neutral-800 dark:text-neutral-200">Phone Number</span>
<div className="flex items-center mt-1 rounded-2xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-900 focus-within:ring-0"> <div className="flex items-center mt-1 rounded-2xl border border-neutral-200 bg-white dark:border-neutral-700 dark:bg-neutral-900 focus-within:ring-0">
<span className="px-2 mr-[-15px] text-neutral-800 dark:text-neutral-200">+</span> <span className="px-2 mr-[-15px] text-neutral-800 dark:text-neutral-200">+</span>
<input <input
@ -108,7 +107,6 @@ const PageSignUp: FC<PageSignUpProps> = () => {
value={phoneNumber} value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)} onChange={(e) => setPhoneNumber(e.target.value)}
type="text" type="text"
placeholder=""
className="flex-1 p-2 no-border-on-focus border-none outline-none bg-transparent text-neutral-800 dark:text-neutral-200" className="flex-1 p-2 no-border-on-focus border-none outline-none bg-transparent text-neutral-800 dark:text-neutral-200"
/> />
</div> </div>
@ -122,9 +120,8 @@ const PageSignUp: FC<PageSignUpProps> = () => {
<Input <Input
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
type="password" // Changed to password type for security
type="password"
className="secure-input mt-1" className="secure-input mt-1"
onCopy={(e) => e.preventDefault()}
/> />
{errors.password && <p className="text-xs text-red-600">{errors.password}</p>} {errors.password && <p className="text-xs text-red-600">{errors.password}</p>}
</label> </label>
@ -135,16 +132,14 @@ const PageSignUp: FC<PageSignUpProps> = () => {
<Input <Input
value={confirmPassword} value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)} onChange={(e) => setConfirmPassword(e.target.value)}
placeholder="Password"
type="password" // Changed to password type for security
type="password"
className="secure-input mt-1" className="secure-input mt-1"
onCopy={(e) => e.preventDefault()}
/> />
{errors.confirmPassword && ( {errors.confirmPassword && (
<p className="text-xs text-red-600">{errors.confirmPassword}</p> <p className="text-xs text-red-600">{errors.confirmPassword}</p>
)} )}
</label> </label>
{failed && (<p><p className="text-xs text-red-600">{failed}</p></p>)}
{failed && <p className="text-xs text-red-600">{failed}</p>}
<ButtonPrimary <ButtonPrimary
loading={loading} loading={loading}
onClick={submitHandler} onClick={submitHandler}

20
src/hooks/FormValidation.ts

@ -1,12 +1,20 @@
// hooks/FormValidation.js
// hooks/FormValidation.ts
import { useState } from 'react'; import { useState } from 'react';
// Validation function for the signup form
// Define a type for the form structure
interface SignUpForm {
name: string;
countryCode: string;
phoneNumber: string;
password: string;
confirmPassword: string;
}
const useFormValidation = () => { const useFormValidation = () => {
const [errors, setErrors] = useState({});
const [errors, setErrors] = useState<Record<string, string>>({});
const validateForm = (form) => {
let newErrors = {};
const validateForm = (form: SignUpForm) => {
let newErrors: Record<string, string> = {};
if (!form.name) { if (!form.name) {
newErrors.name = 'Full Name is required'; newErrors.name = 'Full Name is required';
@ -36,7 +44,7 @@ const useFormValidation = () => {
return Object.keys(newErrors).length === 0; return Object.keys(newErrors).length === 0;
}; };
return { errors, validateForm };
return { errors, validateForm, setErrors }; // Optionally return setErrors
}; };
export default useFormValidation; export default useFormValidation;

2
src/shared/Button.tsx

@ -15,7 +15,7 @@ export interface ButtonProps {
type?: ButtonHTMLAttributes<HTMLButtonElement>["type"]; type?: ButtonHTMLAttributes<HTMLButtonElement>["type"];
href?: Route<string>; href?: Route<string>;
targetBlank?: boolean; targetBlank?: boolean;
onClick?: () => void;
onClick?: (e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => void;
children?: React.ReactNode; children?: React.ReactNode;
} }

Loading…
Cancel
Save