diff --git a/app/api/profile/[id]/route.js b/app/api/profile/[id]/route.js new file mode 100644 index 0000000..ab619a3 --- /dev/null +++ b/app/api/profile/[id]/route.js @@ -0,0 +1,21 @@ +import { NextResponse } from "next/server"; +import { fetchDataViaGet } from "@/app/api/utils"; +import { ENDPOINTS } from "@/app/api/config"; + +export async function GET(request, params) { + const token = request.nextUrl.searchParams.get(["token"]) || null; + let url = new URL(`${ENDPOINTS.profile}/${params["params"]["id"]}`); + if (token) { + url.searchParams.set("token", token); + } + + const response = await fetchDataViaGet(url.toString()); + if (!response) { + return NextResponse.json({ message: "Server Error" }, { status: 500 }); + } + if (!response.profile) { + return NextResponse.json({ message: "Profile not found" }, { status: 404 }); + } + + return NextResponse.json(response); +} diff --git a/app/api/profile/login/route.js b/app/api/profile/login/route.js new file mode 100644 index 0000000..aabbee9 --- /dev/null +++ b/app/api/profile/login/route.js @@ -0,0 +1,15 @@ +import { NextResponse } from "next/server"; +import { authorize } from "@/app/api/utils"; +import { ENDPOINTS } from "@/app/api/config"; + +export async function POST(request) { + const response = await authorize(ENDPOINTS.auth, await request.json()); + if (!response) { + return NextResponse.json({ message: "Server Error" }, { status: 500 }); + } + if (!response.profile) { + return NextResponse.json({ message: "Profile not found" }, { status: 404 }); + } + + return NextResponse.json(response); + } \ No newline at end of file diff --git a/app/api/search/route.js b/app/api/search/route.js index b7d4212..f96747d 100644 --- a/app/api/search/route.js +++ b/app/api/search/route.js @@ -6,11 +6,11 @@ export async function GET(request) { const page = parseInt(request.nextUrl.searchParams.get(["page"])) || 0; const query = request.nextUrl.searchParams.get(["q"]) || null; const token = request.nextUrl.searchParams.get(["token"]) || null; + let url = new URL(`${ENDPOINTS.search}/${page}`); if (token) { url.searchParams.set("token", token); } const data = { query, searchBy: 0 }; - let url = new URL(`${ENDPOINTS.search}/${page}`); const response = await fetchDataViaPost(url.toString(), data); if (!response) { diff --git a/app/api/utils.js b/app/api/utils.js index 1e7d667..3d44158 100644 --- a/app/api/utils.js +++ b/app/api/utils.js @@ -9,6 +9,9 @@ export const fetchDataViaGet = async (url) => { const response = await fetch(url, { headers: HEADERS, }); + if (response.status !== 200) { + throw new Error("Error fetching data"); + } const data = await response.json(); return data; } catch (error) { @@ -23,9 +26,43 @@ export const fetchDataViaPost = async (url, body) => { headers: HEADERS, body: JSON.stringify(body), }); + if (response.status !== 200) { + throw new Error("Error fetching data"); + } const data = await response.json(); return data; } catch (error) { console.log(error); } }; + +export const authorize = async (url, data) => { + try { + const response = await fetch(`${url}?login=${data.login}&password=${data.password}`, { + method: "POST", + headers: { + "User-Agent": USER_AGENT, + Sign: "9aa5c7af74e8cd70c86f7f9587bde23d", + "Content-Type": "application/x-www-form-urlencoded", + }, + }); + if (response.status !== 200) { + throw new Error("Error authorizing user"); + } + return await response.json(); + } catch (error) { + return error; + } +}; + +export function setJWT(user_id, jwt) { + const data = { jwt: jwt, user_id: user_id }; + localStorage.setItem("JWT", JSON.stringify(data)); +} +export function getJWT() { + const data = localStorage.getItem("JWT"); + return JSON.parse(data); +} +export function removeJWT() { + localStorage.removeItem("JWT"); +} diff --git a/app/login/page.js b/app/login/page.js new file mode 100644 index 0000000..2eb561a --- /dev/null +++ b/app/login/page.js @@ -0,0 +1,4 @@ +import { LoginPage } from "@/app/pages/Login"; +export default function Login() { + return ; +} diff --git a/app/pages/Login.jsx b/app/pages/Login.jsx new file mode 100644 index 0000000..3b001c3 --- /dev/null +++ b/app/pages/Login.jsx @@ -0,0 +1,138 @@ +"use client"; +import { useState, useEffect } from "react"; +import { useUserStore } from "@/app/store/auth"; +import { setJWT } from "@/app/api/utils"; +import { useRouter } from "next/navigation"; + +export function LoginPage() { + const [login, setLogin] = useState(""); + const [password, setPassword] = useState(""); + const [remember, setRemember] = useState(false); + const userStore = useUserStore(); + const router = useRouter(); + + function submit(e) { + e.preventDefault(); + fetch("/api/profile/login", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + login: login, + password: password, + }), + }) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + alert("Ошибка получения пользователя."); + } + }) + .then((data) => { + if (data.profileToken) { + userStore.login(data.profile, data.profileToken.token); + if (remember) { + setJWT(data.profile.id, data.profileToken.token); + } + router.push("/"); + } else { + alert("Неверные данные."); + } + }); + } + + useEffect(() => { + if (userStore.user) { + router.push("/"); + } + }, [userStore.user]); + + return ( +
+
+
+
+
+

+ Вход в аккаунт Anixart +

+
+
+ + setLogin(e.target.value)} + required="" + /> +
+
+ + setPassword(e.target.value)} + /> +
+
+
+
+ setRemember(e.target.checked)} + /> +
+
+ +
+
+
+ +
+
+
+
+
+
+ ); +} diff --git a/app/store/auth.js b/app/store/auth.js index e69de29..2e436d5 100644 --- a/app/store/auth.js +++ b/app/store/auth.js @@ -0,0 +1,32 @@ +"use client"; +import { create } from "zustand"; +import { getJWT, setJWT, removeJWT, fetchDataViaGet } from "@/app/api/utils"; + +export const useUserStore = create((set, get) => ({ + isAuth: false, + user: null, + token: null, + + login: (user, token) => { + set({ isAuth: true, user, token }); + }, + logout: () => { + set({ isAuth: false, user: null, token: null }); + removeJWT(); + }, + checkAuth: async () => { + const jwt = getJWT(); + if (jwt) { + const data = await fetchDataViaGet( + `/api/profile/${jwt.user_id}?token=${jwt.jwt}` + ); + if (data && data.is_my_profile) { + get().login(data, jwt.user_id, jwt.jwt); + } else { + get().logout(); + } + } else { + get().logout(); + } + }, +}));