mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-30 09:59:41 +05:00
feat(deploy): allow deploying on deta.space
- **BREAKING CHANGE**: Api url now /api/v1 \n **Fix**: Frontend build. \n **Fix**: errors about unknown styles BREAKING CHANGE:
This commit is contained in:
parent
d85ce45989
commit
d97ad7dbfe
19 changed files with 504 additions and 412 deletions
117
frontend/app/components/Pages/BookmarksPage.jsx
Normal file
117
frontend/app/components/Pages/BookmarksPage.jsx
Normal file
|
@ -0,0 +1,117 @@
|
|||
"use client";
|
||||
|
||||
import { getData } from "@/app/api/api-utils";
|
||||
import { endpoints } from "@/app/api/config";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import ReleasesOverview from "@/app/components/ReleasesOverview/ReleasesOverview";
|
||||
import { useUserStore } from "@/app/store/user-store";
|
||||
|
||||
export default function BookmarksPage() {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const [list, setList] = useState();
|
||||
const [releases, setReleases] = useState();
|
||||
const [page, setPage] = useState(0);
|
||||
|
||||
const [isNextPage, setIsNextPage] = useState(true);
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const createQueryString = useCallback(
|
||||
(name, value) => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set(name, value);
|
||||
|
||||
return params.toString();
|
||||
},
|
||||
[searchParams],
|
||||
);
|
||||
|
||||
// set list on initial page load
|
||||
useEffect(() => {
|
||||
const query = searchParams.get("list");
|
||||
if (query) {
|
||||
setList(query);
|
||||
} else {
|
||||
setList("watching");
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
async function fetchData(list, page = 0) {
|
||||
if (userStore.token) {
|
||||
const url = `${endpoints.user.bookmarks[list]}?page=${page}&token=${userStore.token}`;
|
||||
const data = await getData(url);
|
||||
|
||||
if (data.content.length < 25) {
|
||||
setIsNextPage(false);
|
||||
} else {
|
||||
setIsNextPage(true);
|
||||
}
|
||||
|
||||
// Handle initial load (page 0) or subsequent pagination
|
||||
if (page === 0) {
|
||||
setReleases(data.content);
|
||||
} else {
|
||||
setReleases([...releases, ...data.content]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (list) {
|
||||
router.push(pathname + "?" + createQueryString("list", list));
|
||||
setReleases(null);
|
||||
setPage(0);
|
||||
fetchData(list); // Call fetchData here
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [list, userStore.token]);
|
||||
|
||||
useEffect(() => {
|
||||
if (list && releases) {
|
||||
fetchData(list, page); // Use fetchData for pagination
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [page]);
|
||||
|
||||
const chips = [
|
||||
{
|
||||
title: "Смотрю",
|
||||
list: "watching",
|
||||
},
|
||||
{
|
||||
title: "В планах",
|
||||
list: "planned",
|
||||
},
|
||||
{
|
||||
title: "Просмотрено",
|
||||
list: "watched",
|
||||
},
|
||||
{
|
||||
title: "Отложено",
|
||||
list: "delayed",
|
||||
},
|
||||
{
|
||||
title: "Заброшено",
|
||||
list: "abandoned",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ReleasesOverview
|
||||
chips={chips}
|
||||
setList={setList}
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
list={list}
|
||||
releases={releases}
|
||||
isNextPage={isNextPage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
107
frontend/app/components/Pages/IndexPage.jsx
Normal file
107
frontend/app/components/Pages/IndexPage.jsx
Normal file
|
@ -0,0 +1,107 @@
|
|||
"use client";
|
||||
|
||||
import { getData } from "@/app/api/api-utils";
|
||||
import { endpoints } from "@/app/api/config";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import ReleasesOverview from "@/app/components/ReleasesOverview/ReleasesOverview";
|
||||
|
||||
export default function IndexPage() {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const [list, setList] = useState();
|
||||
const [releases, setReleases] = useState();
|
||||
const [page, setPage] = useState(0);
|
||||
|
||||
const [isNextPage, setIsNextPage] = useState(true);
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const createQueryString = useCallback(
|
||||
(name, value) => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set(name, value);
|
||||
|
||||
return params.toString();
|
||||
},
|
||||
[searchParams],
|
||||
);
|
||||
|
||||
// set list on initial page load
|
||||
useEffect(() => {
|
||||
const query = searchParams.get("list");
|
||||
if (query) {
|
||||
setList(query);
|
||||
} else {
|
||||
setList("last");
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
async function fetchData(list, page = 0) {
|
||||
const url = `${endpoints.index[list]}?page=${page}`;
|
||||
const data = await getData(url);
|
||||
|
||||
if (data.content.length < 25) {
|
||||
setIsNextPage(false);
|
||||
} else {
|
||||
setIsNextPage(true);
|
||||
}
|
||||
|
||||
// Handle initial load (page 0) or subsequent pagination
|
||||
if (page === 0) {
|
||||
setReleases(data.content);
|
||||
} else {
|
||||
setReleases([...releases, ...data.content]);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (list) {
|
||||
router.push(pathname + "?" + createQueryString("list", list));
|
||||
setReleases(null);
|
||||
setPage(0);
|
||||
fetchData(list); // Call fetchData here
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [list]);
|
||||
|
||||
useEffect(() => {
|
||||
if (list && releases) {
|
||||
fetchData(list, page); // Use fetchData for pagination
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [page]);
|
||||
|
||||
const chips = [
|
||||
{
|
||||
title: "последнее",
|
||||
list: "last",
|
||||
},
|
||||
{
|
||||
title: "в эфире",
|
||||
list: "ongoing",
|
||||
},
|
||||
{
|
||||
title: "анонсировано",
|
||||
list: "announce",
|
||||
},
|
||||
{
|
||||
title: "завершено",
|
||||
list: "finished",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<ReleasesOverview
|
||||
chips={chips}
|
||||
setList={setList}
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
list={list}
|
||||
releases={releases}
|
||||
isNextPage={isNextPage}
|
||||
/>
|
||||
);
|
||||
}
|
150
frontend/app/components/Pages/SearchPage.jsx
Normal file
150
frontend/app/components/Pages/SearchPage.jsx
Normal file
|
@ -0,0 +1,150 @@
|
|||
"use client";
|
||||
|
||||
import { getData } from "@/app/api/api-utils";
|
||||
import { endpoints } from "@/app/api/config";
|
||||
import { useEffect, useState, useCallback } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import ReleasesOverview from "@/app/components/ReleasesOverview/ReleasesOverview";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
|
||||
function saveSearches(search) {
|
||||
localStorage.setItem("searches", search);
|
||||
}
|
||||
function getSearches() {
|
||||
return localStorage.getItem("searches");
|
||||
}
|
||||
|
||||
export default function SearchPage() {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
|
||||
const [releases, setReleases] = useState();
|
||||
const [page, setPage] = useState(0);
|
||||
const [query, setQuery] = useState("");
|
||||
const [isNextPage, setIsNextPage] = useState(true);
|
||||
|
||||
const [searches, setSearches] = useState(JSON.parse(getSearches()));
|
||||
|
||||
const searchParams = useSearchParams();
|
||||
const createQueryString = useCallback(
|
||||
(name, value) => {
|
||||
const params = new URLSearchParams(searchParams.toString());
|
||||
params.set(name, value);
|
||||
|
||||
return params.toString();
|
||||
},
|
||||
[searchParams],
|
||||
);
|
||||
|
||||
async function fetchData(query, page = 0) {
|
||||
const url = `${endpoints.search}?query=${query}&page=${page}`;
|
||||
const data = await getData(url);
|
||||
|
||||
if (data.content.length < 25) {
|
||||
setIsNextPage(false);
|
||||
} else {
|
||||
setIsNextPage(true);
|
||||
}
|
||||
|
||||
// Handle initial load (page 0) or subsequent pagination
|
||||
if (page === 0) {
|
||||
setReleases(data.content);
|
||||
} else {
|
||||
setReleases([...releases, ...data.content]);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const query = searchParams.get("query");
|
||||
if (query) {
|
||||
setQuery(query);
|
||||
fetchData(query, 0);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (releases) {
|
||||
fetchData(query, page); // Use fetchData for pagination
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [page]);
|
||||
|
||||
const handleInput = (e) => {
|
||||
setQuery(e.target.value);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
if (query != "") {
|
||||
router.push(pathname + "?" + createQueryString("query", query));
|
||||
setReleases(null);
|
||||
setPage(0);
|
||||
fetchData(query);
|
||||
|
||||
// save searches and update search history
|
||||
if (!searches) {
|
||||
setSearches([query]);
|
||||
saveSearches(JSON.stringify([query]));
|
||||
} else {
|
||||
console.log(searches);
|
||||
if (!searches.find((element) => element == query)) {
|
||||
setSearches([query, ...searches.slice(0, 5)]);
|
||||
saveSearches(JSON.stringify([query, ...searches.slice(0, 5)]));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<form className="field large prefix round fill" onSubmit={handleSubmit}>
|
||||
<i className="front">search</i>
|
||||
<input name="query" onInput={handleInput} value={query} />
|
||||
<menu className="min" style={{ marginTop: "64px" }}>
|
||||
{searches
|
||||
? searches.map((item) => {
|
||||
return (
|
||||
<a
|
||||
key={item}
|
||||
onClick={() => {
|
||||
setQuery(item);
|
||||
}}
|
||||
className="row"
|
||||
>
|
||||
<i>history</i>
|
||||
<div>{item}</div>
|
||||
</a>
|
||||
);
|
||||
})
|
||||
: ""}
|
||||
</menu>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{releases ? (
|
||||
releases.length > 0 ? (
|
||||
<ReleasesOverview
|
||||
page={page}
|
||||
setPage={setPage}
|
||||
releases={releases}
|
||||
isNextPage={isNextPage}
|
||||
/>
|
||||
) : (
|
||||
<div className="absolute padding primary center middle small-round">
|
||||
<i className="extra">search</i>
|
||||
<h5>Ничего не найдено.</h5>
|
||||
<p>Введите другой поисковой запрос.</p>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div className="absolute padding primary center middle small-round">
|
||||
<i className="extra">search</i>
|
||||
<h5>Здесь пока ничего нет.</h5>
|
||||
<p>Введите поисковой запрос для начала поиска.</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue