refactor: [UEPR-116] move playlist component to separate file

This commit is contained in:
MiroslavDionisiev 2024-12-04 12:30:45 +02:00
parent 1854d11e45
commit c9405ffafb
4 changed files with 98 additions and 93 deletions

View file

@ -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
};

View file

@ -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;
}
}

View file

@ -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 />

View file

@ -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;