production-evyos-systems-an.../docs/frontDocs/SingleWebPages.md

6.7 KiB
Raw Permalink Blame History

Web Pages

  • Web pages that are used in the project

Directories:

-| PageName
  -| hook.ts
  -| language.ts
  -| page.tsx
  -| schemas.ts
  -| types.ts

hook.ts:

export function loginHook(
  startTransition: any,
  data: any,
  setError: any,
  setJsonText: any,
  Router: any,
  lang: LanguageTypes
) {
  try {
    const sendData = { ...data };
    startTransition(() => {
      fetch("/api/login/email", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(sendData),
      })
        .then((response) => {
          if (response.status === 200) {
            response.json().then((data) => {
              setTimeout(() => {
                Router.push(`/panel/dashboard`);
              }, 100);
            });
          } else {
            response.json().then((data) => {
              setError(data?.message);
            });
          }
        })
        .catch(() => {});
    });
  } catch (error) {
    setError("An error occurred during login");
  }
}

language.ts:

export const loginTranslation = {
  tr: {
    email: "E-Posta",
    password: "Şifre",
    rememberMe: "Beni Hatırla",
    login: "Giriş Yap",
    successMessage: "Giriş Yapıldı",
    errorMessage: "Giriş Yapılmadı",
    pendingMessage: "Giriş Yapılıyor...",
    responseData: "Giriş Verileri",
  },
  en: {
    email: "Email",
    password: "Password",
    rememberMe: "Remember Me",
    login: "Login",
    successMessage: "Login completed successfully",
    errorMessage: "Login failed",
    pendingMessage: "Logging in...",
    responseData: "Response Data",
  },
};

page.tsx:

"use client";
import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { LoginFormData } from "./types";
import { loginSchemaEmail } from "./schemas";
import { loginTranslation } from "./language";
import { loginHook } from "./hook";
import { AuthPageProps } from "@/validations/mutual/auth/props";

function Login({ language }: AuthPageProps) {
  const Router = useRouter();
  const translation = loginTranslation[language];

  const [isPending, startTransition] = useTransition();
  const [error, setError] = useState<string | null>(null);
  const [jsonText, setJsonText] = useState<string | null>(null);

  const {
    register,
    formState: { errors },
    handleSubmit,
  } = useForm<LoginFormData>({ resolver: zodResolver(loginSchemaEmail) });
  const onSubmit = async (data: LoginFormData) => {
    loginHook(startTransition, data, setError, setJsonText, Router, language);
  };

  return (
    <>
      <div className="flex h-full min-h-[inherit] flex-col items-center justify-center gap-4">
        <div className="w-full max-w-md rounded-lg bg-white p-8 shadow-md">
          <h2 className="mb-6 text-center text-2xl font-bold text-gray-900">
            {translation.login}
          </h2>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            <div>
              <label
                htmlFor="email"
                className="block text-sm font-medium text-gray-700"
              >
                {translation.email}
              </label>
              <input
                {...register("email")}
                type="email"
                id="email"
                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-indigo-500"
              />
              {errors.email && (
                <p className="mt-1 text-sm text-red-600">
                  {errors.email.message}
                </p>
              )}
            </div>
            <div>
              <label
                htmlFor="password"
                className="block text-sm font-medium text-gray-700"
              >
                {translation.password}
              </label>
              <input
                {...register("password")}
                type="password"
                id="password"
                className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-indigo-500"
              />
              {errors.password && (
                <p className="mt-1 text-sm text-red-600">
                  {errors.password.message}
                </p>
              )}
            </div>
            {error && (
              <div className="rounded-md bg-red-50 p-4">
                <p className="text-sm text-red-700">{error}</p>
              </div>
            )}
            <button
              type="submit"
              disabled={isPending}
              className="w-full rounded-md bg-indigo-600 px-4 py-2 text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-50"
            >
              {isPending ? translation.pendingMessage : translation.login}
            </button>
          </form>
        </div>
        {jsonText && (
          <div className="w-full max-w-md rounded-lg bg-white p-8 shadow-md">
            <h2 className="mb-4 text-center text-xl font-bold text-gray-900">
              {translation.responseData}
            </h2>
            <div className="space-y-2">
              {Object.entries(JSON.parse(jsonText)).map(([key, value]) => (
                <div key={key} className="flex items-start gap-2">
                  <strong className="text-gray-700">{key}:</strong>
                  <span className="text-gray-600">
                    {typeof value === "object"
                      ? JSON.stringify(value)
                      : value?.toString() || "N/A"}
                  </span>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </>
  );
}

export default Login;

schemas.ts:

import { z } from "zod";

const loginSchemaEmail = z.object({
  email: z.string().email("Invalid email address"),
  password: z.string().min(5, "Password must be at least 5 characters"),
  rememberMe: z.boolean().optional().default(false),
});

const loginSchemaPhone = z.object({
  phone: z.string().regex(/^[0-9]{10}$/, "Invalid phone number"),
  password: z.string().min(5, "Password must be at least 5 characters"),
  rememberMe: z.boolean().optional().default(false),
});

export { loginSchemaEmail, loginSchemaPhone };

types.ts:

type LoginFormData = {
  email: string;
  password: string;
  rememberMe?: boolean;
};

type LoginFormDataPhone = {
  phone: string;
  password: string;
  rememberMe?: boolean;
};

export type { LoginFormData, LoginFormDataPhone };