mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-12-12 00:31:11 -05:00
refactor: [UEPR-116] move playlist component to separate file
This commit is contained in:
parent
1854d11e45
commit
c9405ffafb
4 changed files with 98 additions and 93 deletions
|
@ -0,0 +1,66 @@
|
|||
import React, {useEffect, useState} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import api from '../../lib/api';
|
||||
import {YoutubeVideoButton} from '../youtube-video-button/youtube-video-button.jsx';
|
||||
import Spinner from '../spinner/spinner.jsx';
|
||||
|
||||
import './youtube-playlist-item.scss';
|
||||
|
||||
export const YoutubePlaylistItem = ({playlistRequestUri, playlistTitleId, onSelectedVideo}) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [playlistVideos, setPlaylistVideos] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
api({
|
||||
host: process.env.ROOT_URL,
|
||||
method: 'GET',
|
||||
uri: playlistRequestUri,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}, (_err, body, res) => {
|
||||
setLoading(false);
|
||||
if (res.statusCode === 200) {
|
||||
setPlaylistVideos(body);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="playlist">
|
||||
<div className="playlist-title">
|
||||
<FormattedMessage id={playlistTitleId} />
|
||||
</div>
|
||||
{loading ? (
|
||||
<Spinner
|
||||
className="spinner"
|
||||
color="transparent-gray"
|
||||
/>
|
||||
) : (
|
||||
<section className="playlist-videos">
|
||||
{playlistVideos
|
||||
.sort(
|
||||
(firstVideo, secondVideo) =>
|
||||
new Date(firstVideo.publishedAt).getTime() <
|
||||
new Date(secondVideo.publishedAt).getTime()
|
||||
)
|
||||
.map(video => (
|
||||
<YoutubeVideoButton
|
||||
key={video.videoId}
|
||||
onSelectedVideo={onSelectedVideo}
|
||||
{...video}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
YoutubePlaylistItem.propTypes = {
|
||||
playlistRequestUri: PropTypes.string,
|
||||
playlistTitleId: PropTypes.string,
|
||||
onSelectedVideo: PropTypes.func
|
||||
};
|
|
@ -0,0 +1,26 @@
|
|||
.playlist {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
.playlist-title {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.playlist-videos {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(13.125rem, auto));
|
||||
justify-content: space-around;
|
||||
align-items: start;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const React = require('react');
|
||||
const {useState, useCallback, useEffect} = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const api = require('../../lib/api');
|
||||
const {useState, useCallback} = require('react');
|
||||
|
||||
const Button = require('../../components/forms/button.jsx');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
|
@ -12,13 +10,10 @@ const Page = require('../../components/page/www/page.jsx');
|
|||
const render = require('../../lib/render.jsx');
|
||||
|
||||
const {useIntl} = require('react-intl');
|
||||
const {
|
||||
YoutubeVideoButton
|
||||
} = require('../../components/youtube-video-button/youtube-video-button.jsx');
|
||||
const {
|
||||
YoutubeVideoModal
|
||||
} = require('../../components/youtube-video-modal/youtube-video-modal.jsx');
|
||||
const Spinner = require('../../components/spinner/spinner.jsx');
|
||||
const {YoutubePlaylistItem} = require('../../components/youtube-playlist-item/youtube-playlist-item.jsx');
|
||||
|
||||
require('./ideas.scss');
|
||||
|
||||
|
@ -101,57 +96,6 @@ const playlists = {
|
|||
'advanced-topics': 'ideas.advancedTopics'
|
||||
};
|
||||
|
||||
const PlaylistItem = ({playlistKey, onSelectedVideo}) => {
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [playlistVideos, setPlaylistVideos] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
api({
|
||||
host: process.env.ROOT_URL,
|
||||
method: 'GET',
|
||||
uri: `/ideas/videos/${playlistKey}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}, (_err, body, res) => {
|
||||
setLoading(false);
|
||||
if (res.statusCode === 200) {
|
||||
setPlaylistVideos(body);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="playlist">
|
||||
<div className="playlist-title">
|
||||
<FormattedMessage id={playlists[playlistKey]} />
|
||||
</div>
|
||||
{loading ? (
|
||||
<Spinner
|
||||
className="spinner"
|
||||
color="transparent-gray"
|
||||
/>
|
||||
) : (
|
||||
<section className="playlist-videos">
|
||||
{playlistVideos
|
||||
.sort(
|
||||
(firstVideo, secondVideo) =>
|
||||
new Date(firstVideo.publishedAt).getTime() <
|
||||
new Date(secondVideo.publishedAt).getTime()
|
||||
)
|
||||
.map(video => (
|
||||
<YoutubeVideoButton
|
||||
key={video.videoId}
|
||||
onSelectedVideo={onSelectedVideo}
|
||||
{...video}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Ideas = () => {
|
||||
const intl = useIntl();
|
||||
const [youtubeVideoId, setYoutubeVideoId] = useState('');
|
||||
|
@ -252,9 +196,10 @@ const Ideas = () => {
|
|||
</div>
|
||||
<section className="playlists">
|
||||
{Object.keys(playlists).map(playlistKey => (
|
||||
<PlaylistItem
|
||||
<YoutubePlaylistItem
|
||||
key={playlistKey}
|
||||
playlistKey={playlistKey}
|
||||
playlistRequestUri={`/ideas/videos/${playlistKey}`}
|
||||
playlistTitleId={playlists[playlistKey]}
|
||||
onSelectedVideo={onSelectedVideo}
|
||||
/>
|
||||
))}
|
||||
|
@ -368,11 +313,6 @@ const Ideas = () => {
|
|||
);
|
||||
};
|
||||
|
||||
PlaylistItem.propTypes = {
|
||||
playlistKey: PropTypes.string,
|
||||
onSelectedVideo: PropTypes.func
|
||||
};
|
||||
|
||||
render(
|
||||
<Page>
|
||||
<Ideas />
|
||||
|
|
|
@ -92,33 +92,6 @@ $base-bg: $ui-white;
|
|||
}
|
||||
}
|
||||
|
||||
.playlist {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
.playlist-title {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.playlist-videos {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(13.125rem, auto));
|
||||
justify-content: space-around;
|
||||
align-items: start;
|
||||
gap: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.physical-ideas {
|
||||
.inner {
|
||||
display: flex;
|
||||
|
@ -203,7 +176,7 @@ $base-bg: $ui-white;
|
|||
}
|
||||
}
|
||||
|
||||
.tips, .physical-ideas, .playlist {
|
||||
.tips, .physical-ideas {
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
|
|
Loading…
Reference in a new issue