diff --git a/tranga-website/src/Components/Loading.tsx b/tranga-website/src/Components/Loading.tsx
new file mode 100644
index 0000000..8f0c072
--- /dev/null
+++ b/tranga-website/src/Components/Loading.tsx
@@ -0,0 +1,32 @@
+import {Close, Done} from "@mui/icons-material";
+import {CircularProgress, ColorPaletteProp} from "@mui/joy";
+import {ReactNode} from "react";
+
+export enum LoadingState {
+ none,
+ loading,
+ success,
+ failure
+}
+
+export function StateIndicator(state : LoadingState) : ReactNode {
+ switch (state) {
+ case LoadingState.loading:
+ return ();
+ case LoadingState.failure:
+ return ();
+ case LoadingState.success:
+ return ();
+ default: return null;
+ }
+}
+
+export function StateColor(state : LoadingState) : ColorPaletteProp | undefined {
+ switch (state) {
+ case LoadingState.failure:
+ return "danger";
+ case LoadingState.success:
+ return "success";
+ default: return undefined;
+ }
+}
\ No newline at end of file
diff --git a/tranga-website/src/Components/Mangas/MangaCard.tsx b/tranga-website/src/Components/Mangas/MangaCard.tsx
index 72074e2..df11ee7 100644
--- a/tranga-website/src/Components/Mangas/MangaCard.tsx
+++ b/tranga-website/src/Components/Mangas/MangaCard.tsx
@@ -19,7 +19,6 @@ import ModalClose from "@mui/joy/ModalClose";
import {ApiContext} from "../../apiClient/ApiContext.tsx";
import MarkdownPreview from '@uiw/react-markdown-preview';
import {MangaContext} from "../../App.tsx";
-import MangaDownloadDialog from "./MangaDownloadDialog.tsx";
import {MangaConnectorLinkFromId} from "../MangaConnectorLink.tsx";
export function MangaCardFromId({mangaId} : {mangaId: string}) {
@@ -29,7 +28,7 @@ export function MangaCardFromId({mangaId} : {mangaId: string}) {
return
}
-export function MangaCard({manga} : {manga: Manga | undefined}) {
+export function MangaCard({manga, children} : {manga: Manga | undefined, children? : ReactNode}) {
if (manga === undefined)
return PlaceHolderCard();
@@ -47,7 +46,7 @@ export function MangaCard({manga} : {manga: Manga | undefined}) {
-
+ {children}
);
@@ -72,12 +71,12 @@ export function MangaModal({manga, open, setOpen, children}: {manga: Manga | und
{manga?.mangaTags?.map((tag) => {tag.tag})}
{manga?.links?.map((link) => {link.linkProvider})}
-
+
+ {children}
- {children}
);
diff --git a/tranga-website/src/Components/Mangas/MangaList.tsx b/tranga-website/src/Components/Mangas/MangaList.tsx
index 742901b..bd347f4 100644
--- a/tranga-website/src/Components/Mangas/MangaList.tsx
+++ b/tranga-website/src/Components/Mangas/MangaList.tsx
@@ -3,13 +3,25 @@ import {MangaCard} from "./MangaCard.tsx";
import {Stack} from "@mui/joy";
import "./MangaList.css";
import {Manga} from "../../apiClient/data-contracts.ts";
+import MangaDownloadDialog from "./MangaDownloadDialog.tsx";
+import MangaMerge from "./MangaMerge.tsx";
export default function MangaList ({mangas, children} : {mangas: Manga[], children?: ReactNode}) {
return (
-
+
{children}
- {mangas?.map(manga => )}
+ {mangas?.map(manga => (
+
+
+
+
+ ))}
);
diff --git a/tranga-website/src/Components/Mangas/MangaMerge.tsx b/tranga-website/src/Components/Mangas/MangaMerge.tsx
new file mode 100644
index 0000000..316bdad
--- /dev/null
+++ b/tranga-website/src/Components/Mangas/MangaMerge.tsx
@@ -0,0 +1,38 @@
+import {ReactNode, useContext, useEffect, useState} from "react";
+import {Manga} from "../../apiClient/data-contracts.ts";
+import Drawer from "@mui/joy/Drawer";
+import ModalClose from "@mui/joy/ModalClose";
+import {ApiContext} from "../../apiClient/ApiContext.tsx";
+import {MangaCard} from "./MangaCard.tsx";
+import {Button} from "@mui/joy";
+
+export default function ({manga} : {manga : Manga | undefined}) : ReactNode {
+ const Api = useContext(ApiContext);
+
+ const [similar, setSimilar] = useState([]);
+ const [open, setOpen] = useState(false);
+
+ useEffect(()=> {
+ if (manga === undefined || !open)
+ return;
+ Api.queryMangaSimilarNameList(manga.key as string).then(response => {
+ if (response.ok)
+ Api.mangaWithIDsCreate(response.data).then(response => {
+ if (response.ok)
+ setSimilar(response.data);
+ });
+ });
+ }, [open]);
+
+ return (
+ <>
+
+ setOpen(false)} anchor={"bottom"}>
+
+ {similar.map(manga => )}
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/tranga-website/src/Components/Search.tsx b/tranga-website/src/Components/Search.tsx
index 065dc9a..32107fe 100644
--- a/tranga-website/src/Components/Search.tsx
+++ b/tranga-website/src/Components/Search.tsx
@@ -1,12 +1,15 @@
import {Dispatch, KeyboardEventHandler, ReactNode, useContext, useState} from "react";
import {
- Badge, Button,
+ Badge,
+ Button,
Card,
CardContent,
- CardCover,
+ CardCover, Chip,
Input,
Modal,
- ModalDialog, Option, Select,
+ ModalDialog,
+ Option,
+ Select,
Step,
StepIndicator,
Stepper,
@@ -17,6 +20,7 @@ import {MangaConnectorContext} from "../App.tsx";
import {Manga, MangaConnector} from "../apiClient/data-contracts.ts";
import MangaList from "./Mangas/MangaList.tsx";
import {ApiContext} from "../apiClient/ApiContext.tsx";
+import {LoadingState, StateColor, StateIndicator} from "./Loading.tsx";
export default function () : ReactNode {
const [open, setOpen] = useState(false);
@@ -46,6 +50,8 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch(undefined);
const [searchTerm, setSearchTerm] = useState();
const [searchResults, setSearchResults] = useState([]);
+
+ const [loadingState, setLoadingState] = useState(LoadingState.none);
const doTheSearch = () => {
if (searchTerm === undefined || searchTerm.length < 1)
@@ -53,18 +59,26 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch {
- if (response.ok)
+ if (response.ok){
setSearchResults([response.data]);
- });
+ setLoadingState(LoadingState.success);
+ }else
+ setLoadingState(LoadingState.failure);
+ }).catch(() => setLoadingState(LoadingState.failure));
else
Api.searchDetail(selectedMangaConnector!.name, searchTerm)
.then(response => {
- if(response.ok)
+ if(response.ok){
setSearchResults(response.data);
- });
+ setLoadingState(LoadingState.success);
+ }else
+ setLoadingState(LoadingState.failure);
+ }).catch(() => setLoadingState(LoadingState.failure));
}
const isUrl = (url: string) => {
@@ -89,7 +103,9 @@ function SearchDialog ({open, setOpen} : {open: boolean, setOpen: Dispatch
1}>
Connector
-