🏓 Library page scaffold
This commit is contained in:
@@ -51,6 +51,7 @@
|
|||||||
"react-fast-compare": "^3.2.0",
|
"react-fast-compare": "^3.2.0",
|
||||||
"react-final-form": "^6.5.3",
|
"react-final-form": "^6.5.3",
|
||||||
"react-spinners": "^0.11.0",
|
"react-spinners": "^0.11.0",
|
||||||
|
"react-table": "^7.7.0",
|
||||||
"react-window-dynamic-list": "^2.3.5",
|
"react-window-dynamic-list": "^2.3.5",
|
||||||
"sharp": "^0.28.1",
|
"sharp": "^0.28.1",
|
||||||
"socket.io-client": "^4.1.2",
|
"socket.io-client": "^4.1.2",
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ $border-color: red;
|
|||||||
row-gap: 1.2em;
|
row-gap: 1.2em;
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
max-width: 200px;
|
max-width: 500px;
|
||||||
margin: 0 0 15px 0;
|
margin: 0 0 15px 0;
|
||||||
.is-horizontal {
|
.is-horizontal {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Dashboard from "./Dashboard";
|
|||||||
|
|
||||||
import Import from "./Import";
|
import Import from "./Import";
|
||||||
import { ComicDetail } from "./ComicDetail";
|
import { ComicDetail } from "./ComicDetail";
|
||||||
|
import Library from "./Library";
|
||||||
|
|
||||||
import { Switch, Route } from "react-router";
|
import { Switch, Route } from "react-router";
|
||||||
import Navbar from "./Navbar";
|
import Navbar from "./Navbar";
|
||||||
@@ -21,6 +22,9 @@ class App extends React.Component {
|
|||||||
<Route path="/import">
|
<Route path="/import">
|
||||||
<Import path={"./comics"} />
|
<Import path={"./comics"} />
|
||||||
</Route>
|
</Route>
|
||||||
|
<Route path="/library">
|
||||||
|
<Library />
|
||||||
|
</Route>
|
||||||
<Route
|
<Route
|
||||||
path={"/comic/details/:comicObjectId"}
|
path={"/comic/details/:comicObjectId"}
|
||||||
component={ComicDetail}
|
component={ComicDetail}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import ComicVineSearchForm from "./ComicVineSearchForm";
|
|||||||
|
|
||||||
import { css } from "@emotion/react";
|
import { css } from "@emotion/react";
|
||||||
import PuffLoader from "react-spinners/PuffLoader";
|
import PuffLoader from "react-spinners/PuffLoader";
|
||||||
import { isEmpty, isUndefined, isEqual } from "lodash";
|
import { isEmpty, isUndefined } from "lodash";
|
||||||
import { IExtractedComicBookCoverFile, RootState } from "threetwo-ui-typings";
|
import { IExtractedComicBookCoverFile, RootState } from "threetwo-ui-typings";
|
||||||
import { fetchComicVineMatches } from "../actions/fileops.actions";
|
import { fetchComicVineMatches } from "../actions/fileops.actions";
|
||||||
import { Drawer, Divider } from "antd";
|
import { Drawer, Divider } from "antd";
|
||||||
@@ -27,7 +27,6 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
|||||||
|
|
||||||
const comicVineSearchResults = useSelector(
|
const comicVineSearchResults = useSelector(
|
||||||
(state: RootState) => state.comicInfo.searchResults,
|
(state: RootState) => state.comicInfo.searchResults,
|
||||||
|
|
||||||
);
|
);
|
||||||
const comicVineSearchQueryObject = useSelector(
|
const comicVineSearchQueryObject = useSelector(
|
||||||
(state: RootState) => state.comicInfo.searchQuery,
|
(state: RootState) => state.comicInfo.searchQuery,
|
||||||
@@ -136,8 +135,8 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
|||||||
|
|
||||||
<div className="search-results-container">
|
<div className="search-results-container">
|
||||||
{!isEmpty(comicVineSearchResults) && (
|
{!isEmpty(comicVineSearchResults) && (
|
||||||
<MatchResult matchData={comicVineSearchResults} />
|
<MatchResult matchData={comicVineSearchResults} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
getRecentlyImportedComicBooks({
|
getRecentlyImportedComicBooks({
|
||||||
paginationOptions: {
|
paginationOptions: {
|
||||||
page: 0,
|
page: 0,
|
||||||
limit: 31,
|
limit: 5,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
115
src/client/components/Library.tsx
Normal file
115
src/client/components/Library.tsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import React, {
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useCallback,
|
||||||
|
useMemo,
|
||||||
|
ReactElement,
|
||||||
|
} from "react";
|
||||||
|
import {
|
||||||
|
removeLeadingPeriod,
|
||||||
|
escapePoundSymbol,
|
||||||
|
} from "../shared/utils/formatting.utils";
|
||||||
|
import { useTable } from "react-table";
|
||||||
|
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
|
||||||
|
interface IComicBookLibraryProps {
|
||||||
|
matches: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Library = ({}: IComicBookLibraryProps): ReactElement => {
|
||||||
|
const data = useSelector(
|
||||||
|
(state: RootState) => state.fileOps.recentComics.docs,
|
||||||
|
);
|
||||||
|
const columns = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: "Comic Metadata",
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
Header: "Name",
|
||||||
|
accessor: "rawFileDetails",
|
||||||
|
Cell: (props) => {
|
||||||
|
const encodedFilePath = encodeURI(
|
||||||
|
"http://localhost:3000" +
|
||||||
|
removeLeadingPeriod(props.cell.value.path),
|
||||||
|
);
|
||||||
|
const filePath = escapePoundSymbol(encodedFilePath);
|
||||||
|
return (
|
||||||
|
<div className="card-container">
|
||||||
|
<div className="card">
|
||||||
|
<div className="is-horizontal">
|
||||||
|
<div className="card-image">
|
||||||
|
<figure>
|
||||||
|
<img className="image" src={filePath} />
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<div className="card-content">
|
||||||
|
<p>{props.cell.value.name}</p>
|
||||||
|
{props.cell.value.containedIn}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: "Import Status",
|
||||||
|
accessor: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
|
||||||
|
useTable({ columns, data });
|
||||||
|
|
||||||
|
const comicBookLibraryItems = React.useMemo(() => {});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="container">
|
||||||
|
<div className="section">
|
||||||
|
<h1 className="title">Library</h1>
|
||||||
|
<div className="columns">
|
||||||
|
<div className="column">
|
||||||
|
<table {...getTableProps()}>
|
||||||
|
<thead>
|
||||||
|
{headerGroups.map((headerGroup, idx) => (
|
||||||
|
<tr key={idx} {...headerGroup.getHeaderGroupProps()}>
|
||||||
|
{headerGroup.headers.map((column, idx) => (
|
||||||
|
<th key={idx} {...column.getHeaderProps()}>
|
||||||
|
{column.render("Header")}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody {...getTableBodyProps()}>
|
||||||
|
{rows.map((row, idx) => {
|
||||||
|
prepareRow(row);
|
||||||
|
return (
|
||||||
|
<tr key={idx} {...row.getRowProps()}>
|
||||||
|
{row.cells.map((cell, idx) => {
|
||||||
|
console.log(cell);
|
||||||
|
return (
|
||||||
|
<td key={idx} {...cell.getCellProps()}>
|
||||||
|
{cell.render("Cell")}
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Library;
|
||||||
@@ -47,6 +47,9 @@ const Navbar: React.FunctionComponent = (props) => {
|
|||||||
Import
|
Import
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
<Link to="/library" className="navbar-item">
|
||||||
|
Library
|
||||||
|
</Link>
|
||||||
<div className="navbar-item has-dropdown is-hoverable">
|
<div className="navbar-item has-dropdown is-hoverable">
|
||||||
<a
|
<a
|
||||||
className="navbar-link is-active"
|
className="navbar-link is-active"
|
||||||
|
|||||||
@@ -11340,6 +11340,11 @@ react-spinners@^0.11.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@emotion/react" "^11.1.4"
|
"@emotion/react" "^11.1.4"
|
||||||
|
|
||||||
|
react-table@^7.7.0:
|
||||||
|
version "7.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.7.0.tgz#e2ce14d7fe3a559f7444e9ecfe8231ea8373f912"
|
||||||
|
integrity sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA==
|
||||||
|
|
||||||
react-window-dynamic-list@^2.3.5:
|
react-window-dynamic-list@^2.3.5:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/react-window-dynamic-list/-/react-window-dynamic-list-2.4.2.tgz#e9cabcd067cb066619613af00f5dd42bca9f4b19"
|
resolved "https://registry.yarnpkg.com/react-window-dynamic-list/-/react-window-dynamic-list-2.4.2.tgz#e9cabcd067cb066619613af00f5dd42bca9f4b19"
|
||||||
|
|||||||
Reference in New Issue
Block a user