Basic pagination en Artistas

This commit is contained in:
Daniel Cortes
2020-06-06 06:47:21 -04:00
parent e08e75538d
commit 2f3e83f8c8
3 changed files with 118 additions and 57 deletions

View File

@@ -1,28 +1,53 @@
import React, {useEffect, useState} from 'react' import React, {useEffect, useState} from 'react'
import {getArtist, getArtistDiscs} from "../services/entity_service"; import {getArtist, getArtistDiscs} from "../services/entity_service";
import {CoverWithCaption} from './CoverArt'; import {CoverWithCaption} from './CoverArt';
import ReactJson from "react-json-view"; import {Paginate} from "./Paginate";
export const Discs = (props) => { export const Discs = (props) => {
const discs = props.discs ? props.discs.discs : null; const discs = props.discs ? props.discs : null;
const paginate = props.discs ? props.discs.paginate : null; const paginate = props.paginate ? props.paginate : null;
const handlePageChanged = (page) => {
props.onPageChanged(page);
}
let discContent;
if (discs) { if (discs) {
return ( discContent = (
<div className='discs'> <ul className="discs-list">
<h2>Discos</h2> {discs.map((disc, index) => {
<ul className={'discs-list'}> return (
{discs.map((disc, index) => { <div key={index} className='cover-container'>
return ( <CoverWithCaption cover_art={disc.cover_art} alt={`Cover art del disco ${disc.title}`} caption={disc.title}/>
<div className='cover-container'> </div>
<CoverWithCaption key={index} cover_art={disc.cover_art} alt={`Cover art del disco ${disc.title}`} caption={disc.title}/> )
</div> })}
) </ul>
})} );
</ul> } else {
</div> discContent = (
<ul className="discs-list loading">
{[...Array(16)].map((p, index) => (<div key={index} className='cover-container pulsating'/>))}
</ul>
);
}
let paginateContent;
if (paginate) {
const total = paginate.total;
const currentPage = paginate.current_page;
const pageLimit = paginate.per_page;
paginateContent = <Paginate totalRecords={total} pageLimit={pageLimit} currentPage={currentPage} pageNeighbours={2} onPageChanged={handlePageChanged} makeLink={() => ('#')}/>
}
return (
<div className='discs'>
<h2>Discos</h2>
{discContent}
{paginateContent}
</div>
) )
} else return <></>
} }
export const Artist = (props) => { export const Artist = (props) => {
@@ -52,19 +77,34 @@ export const Artist = (props) => {
export const ArtistView = (props) => { export const ArtistView = (props) => {
const [artist, setArtist] = useState(null); const [artist, setArtist] = useState(null);
const [discs, setDiscs] = useState(null); const [discs, setDiscs] = useState(null);
const [discsPaginate, setDiscsPaginate] = useState(null);
const mbid = props.match.params.mbid; const mbid = props.match.params.mbid;
useEffect(() => { useEffect(() => {
if (mbid) { if (mbid) {
getArtist(mbid).then((result) => setArtist(result)); getArtist(mbid).then((result) => setArtist(result));
getArtistDiscs(mbid, 15).then((result) => setDiscs(result)); getArtistDiscs(mbid, 1, 16).then((result) => {
setDiscs(result.discs);
setDiscsPaginate(result.paginate);
});
} }
}, [mbid]) }, [mbid])
const handleDiscPageChanged = (page) => {
setDiscs(null);
getArtistDiscs(mbid, page, 16).then((result) => {
setDiscs(result.discs);
setDiscsPaginate(result.paginate);
});
document.getElementById('root').scrollIntoView({behavior: 'smooth'});
}
return ( return (
<div className='artist-view'> <div className='artist-view'>
<Artist artist={artist}/> <Artist artist={artist}/>
<Discs discs={discs}/> <Discs discs={discs} paginate={discsPaginate} onPageChanged={handleDiscPageChanged}/>
{!mbid && <p>AHH</p>} {!mbid && <p>AHH</p>}
</div> </div>
); );

View File

@@ -8,8 +8,8 @@ export async function getArtist(mbid) {
return response.data return response.data
} }
export async function getArtistDiscs(mbid, per_page=10) { export async function getArtistDiscs(mbid, page = 1, per_page=10) {
const url = `${baseUrl}/artist/${mbid}/discs?per_page=${per_page}`; const url = `${baseUrl}/artist/${mbid}/discs?per_page=${per_page}&page=${page}`;
const response = await axios.get(url); const response = await axios.get(url);
return response.data return response.data
} }

View File

@@ -70,15 +70,25 @@ h1 {
font-size: var(--font-1); font-size: var(--font-1);
} }
h2 {font-size: var(--font-2);} h2 {
font-size: var(--font-2);
}
h3 {font-size: var(--font-3);} h3 {
font-size: var(--font-3);
}
h4 {font-size: var(--font-4);} h4 {
font-size: var(--font-4);
}
h5 {font-size: var(--font-5);} h5 {
font-size: var(--font-5);
}
small, .text_small {font-size: var(--font-6);} small, .text_small {
font-size: var(--font-6);
}
button.button { button.button {
border: 3px solid var(--accent); border: 3px solid var(--accent);
@@ -261,7 +271,6 @@ ul.entity_list {
} }
} }
.cover-caption { .cover-caption {
height: 250px; height: 250px;
width: 250px; width: 250px;
@@ -280,12 +289,12 @@ ul.entity_list {
} }
&:hover { &:hover {
figcaption{ figcaption {
display: block; display: block;
animation: slidein 300ms ease-in-out both; animation: slidein 300ms ease-in-out both;
@keyframes slidein { @keyframes slidein {
to{ to {
height: 80px; height: 80px;
transform: translateY(-80px); transform: translateY(-80px);
opacity: 100; opacity: 100;
@@ -308,40 +317,50 @@ ul.entity_list {
/* Tabs */ /* Tabs */
ul.tabs { ul.tabs {
display: flex; display: flex;
align-items: stretch; align-items: stretch;
border-bottom: 2px var(--gray-1) solid; border-bottom: 2px var(--gray-1) solid;
margin: 1rem 0; margin: 1rem 0;
li.tab { li.tab {
padding: .5rem 1em; padding: .5rem 1em;
margin-bottom: -2px; margin-bottom: -2px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
border-bottom: 2px var(--gray-2) solid; border-bottom: 2px var(--gray-2) solid;
} }
&.selected { &.selected {
border-bottom: 2px var(--accent) solid; border-bottom: 2px var(--accent) solid;
} }
} }
} }
/* Artists */ /* Artists */
.artist-view { .artist-view {
.artist{ .artist {
.title { .title {
h1 { margin-bottom: 0} h1 {
h4 { margin-top: 0; margin-bottom: .5em } margin-bottom: 0
}
h4 {
margin-top: 0;
margin-bottom: .5em
}
max-width: 60%; max-width: 60%;
} }
.button { .button {
margin-bottom: 1em; margin-bottom: 1em;
} }
.tags { .tags {
display:flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
li { li {
border-bottom: 3px solid var(--accent); border-bottom: 3px solid var(--accent);
margin-right: 1em; margin-right: 1em;
@@ -349,33 +368,35 @@ ul.tabs {
margin-bottom: .5em; margin-bottom: .5em;
font-weight: 500; font-weight: 500;
} }
margin-bottom: 2em; margin-bottom: 2em;
} }
} }
.discs { .discs {
.discs-list { .discs-list {
$grid-width: 250px;
$grid-gap: 30px;
display: grid; display: grid;
grid-auto-rows: 250px; grid-auto-rows: $grid-width;
gap: 30px; gap: $grid-gap;
justify-content: start; justify-content: start;
align-content: start; align-content: start;
$grid-width: 250px;
$grid-gap: 16px;
@for $x from 1 to 5 { @for $x from 1 to 5 {
@media (min-width: $grid-width * $x + $grid-gap * $x ) { @media (min-width: $grid-width * $x + $grid-gap * $x) {
grid-template-columns: repeat($x, auto); grid-template-columns: repeat($x, auto);
} }
} }
@media (min-width: $grid-width * 4 + $grid-gap * 4 ) { @media (min-width: $grid-width * 4 + $grid-gap * 4) {
justify-content: space-between; justify-content: space-between;
align-content: space-between;
} }
&.loading {
height: ($grid-width + $grid-gap) * 4;
}
.cover-container { .cover-container {
width: 250px; width: 250px;
@@ -405,7 +426,7 @@ ul.tabs {
} }
*[hidden] { *[hidden] {
visibility: hidden; visibility: hidden;
} }
.space-between { .space-between {