🔎 Search page scaffold
This commit is contained in:
@@ -60,13 +60,12 @@ $border-color: red;
|
||||
// max-width: 500px;
|
||||
margin: 0 0 15px 0;
|
||||
.card-image {
|
||||
img {
|
||||
border-top-left-radius: 0.3rem;
|
||||
border-top-right-radius: 0.3rem;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
border-top-left-radius: 0.3rem;
|
||||
border-top-right-radius: 0.3rem;
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.is-horizontal {
|
||||
@@ -124,7 +123,17 @@ $border-color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search
|
||||
.search {
|
||||
.main-search-bar {
|
||||
border: 0;
|
||||
border-bottom: 1px solid #999;
|
||||
border-radius: 0;
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
// Library
|
||||
.library {
|
||||
table {
|
||||
|
||||
@@ -5,6 +5,7 @@ import Dashboard from "./Dashboard";
|
||||
import Import from "./Import";
|
||||
import { ComicDetail } from "./ComicDetail";
|
||||
import Library from "./Library";
|
||||
import Search from "./Search";
|
||||
|
||||
import { Switch, Route } from "react-router";
|
||||
import Navbar from "./Navbar";
|
||||
@@ -25,6 +26,9 @@ class App extends React.Component {
|
||||
<Route path="/library">
|
||||
<Library />
|
||||
</Route>
|
||||
<Route path="/search">
|
||||
<Search />
|
||||
</Route>
|
||||
<Route
|
||||
path={"/comic/details/:comicObjectId"}
|
||||
component={ComicDetail}
|
||||
|
||||
@@ -61,54 +61,68 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
||||
};
|
||||
|
||||
const [active, setActive] = useState(0);
|
||||
|
||||
const createDescriptionMarkup = (html) => {
|
||||
return { __html: html };
|
||||
};
|
||||
// Tab groups for ComicVine metadata
|
||||
const tabGroup = [
|
||||
{
|
||||
id: 0,
|
||||
name: "Volume Information",
|
||||
content: !isNil(comicBookDetailData.sourcedMetadata) && (
|
||||
<div className="columns">
|
||||
<div className="column is-narrow">
|
||||
<figure className="card-image">
|
||||
<img
|
||||
src={
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.image.thumb_url
|
||||
}
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
<div className="column is-4">
|
||||
<dl>
|
||||
<dt>
|
||||
Is a part of{" "}
|
||||
<span className="has-text-info">
|
||||
<>
|
||||
<div className="columns">
|
||||
<div className="column is-narrow">
|
||||
<figure className="card-image">
|
||||
<img
|
||||
src={
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.image.thumb_url
|
||||
}
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
<div className="column is-4">
|
||||
<dl>
|
||||
<dt>
|
||||
Is a part of{" "}
|
||||
<span className="has-text-info">
|
||||
{
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.name
|
||||
}
|
||||
</span>
|
||||
</dt>
|
||||
<dd>
|
||||
Published by
|
||||
<span className="has-text-weight-semibold">
|
||||
{" "}
|
||||
{
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.publisher.name
|
||||
}
|
||||
</span>
|
||||
</dd>
|
||||
<dd>
|
||||
Total issues in this volume:{" "}
|
||||
{
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.name
|
||||
.volumeInformation.count_of_issues
|
||||
}
|
||||
</span>
|
||||
</dt>
|
||||
<dd>
|
||||
Published by
|
||||
<span className="has-text-weight-semibold">
|
||||
{" "}
|
||||
{
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.publisher.name
|
||||
}
|
||||
</span>
|
||||
</dd>
|
||||
<dd>
|
||||
Total issues in this volume:{" "}
|
||||
{
|
||||
comicBookDetailData.sourcedMetadata.comicvine
|
||||
.volumeInformation.count_of_issues
|
||||
}
|
||||
</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="columns">
|
||||
<div
|
||||
className="column is-three-quarters"
|
||||
dangerouslySetInnerHTML={createDescriptionMarkup(
|
||||
comicBookDetailData.sourcedMetadata.comicvine.volumeInformation
|
||||
.description,
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useMemo,
|
||||
ReactElement,
|
||||
} from "react";
|
||||
import React, { useState, useEffect, useMemo, ReactElement } from "react";
|
||||
import {
|
||||
removeLeadingPeriod,
|
||||
escapePoundSymbol,
|
||||
@@ -12,14 +6,27 @@ import {
|
||||
import { useTable } from "react-table";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import ellipsize from "ellipsize";
|
||||
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { getComicBooks } from "../actions/fileops.actions";
|
||||
|
||||
interface IComicBookLibraryProps {
|
||||
matches: unknown;
|
||||
matches?: unknown;
|
||||
}
|
||||
|
||||
export const Library = ({}: IComicBookLibraryProps): ReactElement => {
|
||||
const [page, setPage] = useState(1);
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
dispatch(
|
||||
getComicBooks({
|
||||
paginationOptions: {
|
||||
page: 0,
|
||||
limit: 15,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}, [page, dispatch]);
|
||||
|
||||
const data = useSelector(
|
||||
(state: RootState) => state.fileOps.recentComics.docs,
|
||||
);
|
||||
|
||||
@@ -50,7 +50,7 @@ const Navbar: React.FunctionComponent = (props) => {
|
||||
<Link to="/library" className="navbar-item">
|
||||
Library
|
||||
</Link>
|
||||
<Link to="/library" className="navbar-item">
|
||||
<Link to="/search" className="navbar-item">
|
||||
Search
|
||||
</Link>
|
||||
<div className="navbar-item has-dropdown is-hoverable">
|
||||
|
||||
47
src/client/components/Search.tsx
Normal file
47
src/client/components/Search.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, { useMemo, ReactElement } from "react";
|
||||
import {
|
||||
removeLeadingPeriod,
|
||||
escapePoundSymbol,
|
||||
} from "../shared/utils/formatting.utils";
|
||||
import { useTable } from "react-table";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import ellipsize from "ellipsize";
|
||||
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
interface ISearchProps {}
|
||||
|
||||
export const Search = ({}: ISearchProps): ReactElement => {
|
||||
return (
|
||||
<>
|
||||
<section className="container">
|
||||
<div className="section search">
|
||||
<div className="columns">
|
||||
<div className="column is-half">
|
||||
<h1 className="title">Search</h1>
|
||||
<input
|
||||
className="main-search-bar input is-large"
|
||||
type="text"
|
||||
placeholder="Enter a title, ComicVine ID or a series name"
|
||||
></input>
|
||||
</div>
|
||||
</div>
|
||||
<article className="message is-dark is-half">
|
||||
<div className="message-body">
|
||||
<p className="mb-2">
|
||||
<span className="tag is-medium is-info is-light">
|
||||
Search the ComicVine database
|
||||
</span>
|
||||
Search and add issues, series and trade paperbacks to your
|
||||
library. Then, download them using the configured AirDC++ or
|
||||
torrent clients.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Search;
|
||||
Reference in New Issue
Block a user