once user put phonenumber and clicked signin i send a post request to get token from /api/generate_token then  i send another post request with otp number  and phonenumber which user is typed if otp is ok then i will get a jwt token from backend and now user is logged in using authjs:
curl -X 'POST' \
  'https://api.bimehtakmili.com/api/login/generate_token' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "mobile_no": "6588761007"
}'
curl -X 'POST' \
  'https://api.bimehtakmili.com/api/login/verify_otp' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "mobile_no": "3150744036",
  "otp": "26561"
}'
i want to do this flow with next-auth in next 14 with app router
once user put phonenumber and clicked signin i send a post request to get token from /api/generate_token then  i send another post request with otp number  and phonenumber which user is typed if otp is ok then i will get a jwt token from backend and now user is logged in using authjs:
curl -X 'POST' \
  'https://api.bimehtakmili.com/api/login/generate_token' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "mobile_no": "6588761007"
}'
curl -X 'POST' \
  'https://api.bimehtakmili.com/api/login/verify_otp' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "mobile_no": "3150744036",
  "otp": "26561"
}'
i want to do this flow with next-auth in next 14 with app router
"use client";

import { useCRUD } from "@/src/hooks/swr";
import { phoneAtom, stepAtom } from "@/src/store";
import { Button, Form, Input } from "antd";
import { useAtomValue, useSetAtom } from "jotai";
import { ChangeEvent, useState } from "react";
import toast from "react-hot-toast";
import { CiMobile3 } from "react-icons/ci";
import { signIn } from "@/auth";

const EnterPhone = () => {
  const setStep = useSetAtom(stepAtom);
  const phone = useAtomValue(phoneAtom);
  const setPhone = useSetAtom(phoneAtom);
  const [isLoginLoading, setIsLoginLoading] = useState(false);

  const { createItem } = useCRUD(
    `${process.env.NEXT_PUBLIC_BASE_URL}/login/generate_token`,
  );

  const handlePhoneChange = (e: ChangeEvent<HTMLInputElement>) => {
    setPhone(e.target.value);
  };

  const handleLogin = async (values: { phone: string }) => {
    setIsLoginLoading(true); // Set loading state before the API call
    try {
      signIn();
      // const { data } = result;
      // if (data?.statusCode === 10) {
      //   if (data?.token) {
      //     setCookie("token", data.token, {
      //       maxAge: 60 * 60 * 24,
      //       path: "/",
      //       secure: true,
      //       sameSite: "strict",
      //     });
      //   }
      //   signIn();
      //   toast.success("کد otp به شماره تلفن شما ارسال شد");
      //   setStep((prev) => prev + 1);
      // } else {
      //   toast.error("ساخت توکن با مشکل مواجه شد");
      // }
    } catch (error) {
      console.error("Error during login:", error); // Log the error for debugging
      toast.error("ساخت توکن با مشکل مواجه شد");
    } finally {
      setIsLoginLoading(false); // Reset loading state after the API call
    }
  };

  return (
    <>
      <h3 className="text-gray-600 text-sm leading-7 mb-4">
        با شماره تلفن وارد شوید
      </h3>

      <Form
        name="phoneForm"
        onFinish={handleLogin}
        initialValues={{ phone }}
        layout="vertical"
      >
        <Form.Item
          name="phone"
          rules={[
            { required: true, message: "شماره تلفن را وارد کنید" },
            {
              pattern: /^[1-9]\d{9}$/,
              message: "شماره تلفن باید ۱۰ رقم باشد و نباید با ۰ شروع شود",
            },
          ]}
        >
          <Input
            addonBefore={<span className="text-gray-600">+98</span>}
            prefix={<CiMobile3 size={24} className="text-gray-600" />}
            placeholder="شماره تلفن"
            maxLength={10}
            onChange={handlePhoneChange}
          />
        </Form.Item>

        <Form.Item className="mt-4">
          <Button
            className="bg-orange hover:bg-orange-800 duration-200 text-white rounded-md px-4 py-5 w-full"
            htmlType="submit"
            block
            loading={isLoginLoading}
          >
            {isLoginLoading ? "در حال ارسال" : "ورود"}
          </Button>
        </Form.Item>
      </Form>
    </>
  );
};

export default EnterPhone;
import { handlers } from "@/auth"; // Referring to the auth.ts we just created
export const { GET, POST } = handlers;
// export default async function middleware(req: NextRequest) {
//   try {
//     const url = req.nextUrl;
//     const path = url.pathname;
//
//     if (publicRoutes(path)) {
//       return NextResponse.next();
//     }
//
//     const token = req.headers.get("authorization")?.split(" ")[1];
//
//     if (!token) {
//       return new NextResponse("Unauthorized", { status: 401 });
//     }
//
//     const isValidToken = verifyJWT(token);
//
//     if (!isValidToken) {
//       return new NextResponse("Forbidden", { status: 403 });
//     }
//
//     return NextResponse.next();
//   } catch (error) {
//     console.error("Error handling middleware:", error);
//     return new NextResponse("Internal Server Error", { status: 500 });
//   }
// }
import { auth } from "@/auth";

export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname !== "/login") {
    const newUrl = new URL("/login", req.nextUrl.origin);
    return Response.redirect(newUrl);
  }
});
export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * - assets in the public folder
     */
    "/((?!api|_next/static|_next/image|favicon.ico|public|manifest.json).*)",
  ],
};
"use client";

import { SessionProvider, useSession } from "next-auth/react";
import { useEffect } from "react";
import { useSetAtom } from "jotai";
import { sessionAtom } from "@/src/store";

interface Props {
  children: React.ReactNode;
}
export const AuthjsProvider = ({ children }: Props) => {
  const session = useSession();
  const setSession = useSetAtom(sessionAtom);

  useEffect(() => {
    if (session.status === "authenticated") {
      setSession(session.data);
    }
  }, [session]);
  return <SessionProvider>{children}</SessionProvider>;
};