Skip to content

Commit

Permalink
Merge pull request #1006 from parlemonde/feat-vil-624/my-videos
Browse files Browse the repository at this point in the history
Feat vil 624/my videos
  • Loading branch information
zemzamiouss authored Nov 13, 2024
2 parents 6139944 + 0b3bb6f commit 2f592ac
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 89 deletions.
1 change: 0 additions & 1 deletion src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export const Header = () => {
{hasAccessToNewAdmin && <MenuItem onClick={() => goToPage('/admin/newportal/create')}>Portail admin</MenuItem>}
{hasAccessToOldAdmin && <MenuItem onClick={() => goToPage('/admin/villages')}>Admin (old)</MenuItem>}
<MenuItem onClick={() => goToPage('/mon-compte')}>Mon compte</MenuItem>
{user.type !== UserType.FAMILY && <MenuItem onClick={() => goToPage('/mes-videos')}>Mes vidéos</MenuItem>}
<AccessControl featureName="id-family" key={user?.id || 'default'}>
{user.type === UserType.TEACHER ? <MenuItem onClick={() => goToPage('/familles/1')}>Mes familles</MenuItem> : null}{' '}
</AccessControl>
Expand Down
83 changes: 83 additions & 0 deletions src/components/VideoTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import React from 'react';

import VisibilityIcon from '@mui/icons-material/Visibility';
import { Table, TableBody, TableCell, TableHead, TableRow, Tooltip, IconButton } from '@mui/material';

import { DeleteButton } from './buttons/DeleteButton';
import { bgPage } from 'src/styles/variables.const';
import type { Video } from 'types/video.type';

interface VideoTableProps {
videos: Video[];
onView: (video: Video) => void;
onDelete: (id: number) => void;
}

export const VideoTable: React.FC<VideoTableProps> = ({ videos, onView, onDelete }) => {
const cellStyles = {
padding: '5px',
margin: 0,
};

return (
<Table size="medium" style={{ marginTop: '1rem' }}>
<TableHead style={{ borderBottom: '1px solid white' }}>
<TableRow>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
#
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
Nom de la vidéo
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
Lien de la vidéo (URL)
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }} align="right">
Actions
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{videos.map((video, index) => (
<TableRow
key={video.id}
sx={{
backgroundColor: 'white',
'&:nth-of-type(even)': {
backgroundColor: bgPage,
},
'&.sortable-ghost': {
opacity: 0,
},
}}
>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>{index + 1}</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>{video.name}</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>https://player.vimeo.com/video/{video.id}</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} align="right" padding="none" style={{ minWidth: '96px' }}>
<Tooltip title="Regarder">
<IconButton
aria-label="Voir"
onClick={() => {
onView(video);
}}
size="small"
style={{ border: '1px solid', marginRight: '0.25rem' }}
>
<VisibilityIcon />
</IconButton>
</Tooltip>
<Tooltip title="Supprimer">
<DeleteButton
color="red"
onDelete={() => onDelete(video.id)}
confirmLabel="Voulez vous vraiment supprimer cette vidéo ? Attention, elle ne sera plus accessible par les activités qui l'utilisent."
/>
</Tooltip>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
);
};
56 changes: 55 additions & 1 deletion src/pages/ma-classe.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import { useSnackbar } from 'notistack';
import React from 'react';
import { useQueryClient } from 'react-query';

import { isMascotte } from 'src/activity-types/anyActivity';
import { Base } from 'src/components/Base';
import { Modal } from 'src/components/Modal';
import { PageLayout } from 'src/components/PageLayout';
import { VideoTable } from 'src/components/VideoTable';
import { ActivityCard } from 'src/components/activities/ActivityCard';
import { GameCardMaClasse } from 'src/components/activities/ActivityCard/GameCardMaClasse';
import { MascotteTemplate } from 'src/components/activities/content/MascotteTemplate';
import { VideoView } from 'src/components/activities/content/views/VideoView';
import { ActivityContext } from 'src/contexts/activityContext';
import { UserContext } from 'src/contexts/userContext';
import { useActivities } from 'src/services/useActivities';
import { useActivityRequests } from 'src/services/useActivity';
import { useVideos } from 'src/services/useVideos';
import { axiosRequest } from 'src/utils/axiosRequest';
import type { Activity } from 'types/activity.type';
import { ActivityStatus } from 'types/activity.type';
import type { Video } from 'types/video.type';

const MaClasse = () => {
const queryClient = useQueryClient();
const { enqueueSnackbar } = useSnackbar();
const { user, setUser } = React.useContext(UserContext);
const { setActivity } = React.useContext(ActivityContext);
const [selectedVideo, setSelectedVideo] = React.useState<Video | null>(null);
const { videos } = useVideos();
const { activities } = useActivities({
userId: user?.id ?? 0,
});
Expand Down Expand Up @@ -89,6 +97,23 @@ const MaClasse = () => {
setDeleteIndex({ index: -1, isDraft: false });
};

const deleteVideo = async (id: number) => {
const response = await axiosRequest({
method: 'DELETE',
url: `/videos/${id}`,
});
if (response.error) {
enqueueSnackbar('Une erreur est survenue...', {
variant: 'error',
});
} else {
enqueueSnackbar('Vidéo supprimée avec succès !', {
variant: 'success',
});
queryClient.invalidateQueries('videos');
}
};

const hasNoPublishedActivities = activities.filter((a) => a.userId === user?.id && !isMascotte(a)).length === 0;
const hasGamesInActivities = activities.filter((a) => a.userId === user?.id && a.type === 4).length > 0;

Expand Down Expand Up @@ -151,9 +176,21 @@ const MaClasse = () => {
) : (
<p>Vous n&apos;avez pas de jeux publiés.</p>
)}
<h1 style={{ margin: '2rem 0 1rem 0' }}>Mes vidéos</h1>
{videos.length > 0 ? (
<VideoTable
videos={videos}
onDelete={deleteVideo}
onView={(video) => {
setSelectedVideo(video);
}}
/>
) : (
<p>Vous n&apos;avez pas encore mis en ligne de vidéos.</p>
)}
<h1 style={{ margin: '2rem 0 1rem 0' }}>Mes activités publiées</h1>
{hasNoPublishedActivities ? (
<p>Vous n&apos;avez pas d&apos;activités publiées.</p>
<p>Vous navez pas d&apos;activités publiées.</p>
) : (
activities.map((activity, index) =>
user && activity.userId === user.id && !isMascotte(activity) && activity.type !== 4 ? (
Expand Down Expand Up @@ -188,6 +225,23 @@ const MaClasse = () => {
<div>Voulez vous vraiment supprimer cette activité ?</div>
{activityToDelete && user && <ActivityCard activity={activityToDelete} isSelf={true} user={user} noButtons />}
</Modal>

<Modal
title={`Vidéo: ${selectedVideo?.name || ''}`}
cancelLabel="Fermer"
onClose={() => {
setSelectedVideo(null);
}}
open={selectedVideo !== null}
ariaDescribedBy="video-desc"
ariaLabelledBy="video-title"
fullWidth
maxWidth="md"
>
<div>
{selectedVideo !== null && <VideoView id={selectedVideo.id} value={`https://player.vimeo.com/video/${selectedVideo.id}`}></VideoView>}
</div>
</Modal>
</Base>
);
};
Expand Down
98 changes: 11 additions & 87 deletions src/pages/mes-videos.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,12 @@ import { useSnackbar } from 'notistack';
import React from 'react';
import { useQueryClient } from 'react-query';

import VisibilityIcon from '@mui/icons-material/Visibility';
import IconButton from '@mui/material/IconButton';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Tooltip from '@mui/material/Tooltip';

import { Base } from 'src/components/Base';
import { Modal } from 'src/components/Modal';
import { PageLayout } from 'src/components/PageLayout';
import { VideoTable } from 'src/components/VideoTable';
import { VideoView } from 'src/components/activities/content/views/VideoView';
import { DeleteButton } from 'src/components/buttons/DeleteButton';
import { useVideos } from 'src/services/useVideos';
import { bgPage } from 'src/styles/variables.const';
import { axiosRequest } from 'src/utils/axiosRequest';
import type { Video } from 'types/video.type';

Expand All @@ -27,98 +17,32 @@ const MesVideos = () => {
const { videos } = useVideos();
const [selectedVideo, setSelectedVideo] = React.useState<Video | null>(null);

const deleteVideo = (id: number) => async () => {
const deleteVideo = async (id: number) => {
const response = await axiosRequest({
method: 'DELETE',
url: `/videos/${id}`,
});
if (response.error) {
enqueueSnackbar('Une erreur est survenue...', {
variant: 'error',
});
enqueueSnackbar('Une erreur est survenue...', { variant: 'error' });
} else {
enqueueSnackbar('Vidéo supprimée avec succès !', {
variant: 'success',
});
enqueueSnackbar('Vidéo supprimée avec succès !', { variant: 'success' });
queryClient.invalidateQueries('videos');
}
};

const cellStyles = {
padding: '5px',
margin: 0,
};

return (
<Base>
<PageLayout>
<div className="width-900" style={{ overflow: 'auto' }}>
<h1>{'Mes vidéos'}</h1>
{videos.length > 0 ? (
<Table size="medium" style={{ marginTop: '1rem' }}>
<TableHead style={{ borderBottom: '1px solid white' }}>
<TableRow>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
#
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
Nom de la vidéo
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }}>
Lien de la vidéo (URL)
</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })} style={{ fontWeight: 'bold' }} align="right">
Actions
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{videos.map((video, index) => (
<TableRow
key={video.id}
sx={{
backgroundColor: 'white',
'&:nth-of-type(even)': {
backgroundColor: bgPage,
},
'&.sortable-ghost': {
opacity: 0,
},
}}
>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>{index + 1}</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>{video.name}</TableCell>
<TableCell sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}>https://player.vimeo.com/video/{video.id}</TableCell>
<TableCell
sx={(theme) => ({ [theme.breakpoints.only('xs')]: cellStyles })}
align="right"
padding="none"
style={{ minWidth: '96px' }}
>
<Tooltip title="Regarder">
<IconButton
aria-label="Voir"
onClick={() => {
setSelectedVideo(video);
}}
size="small"
style={{ border: '1px solid', marginRight: '0.25rem' }}
>
<VisibilityIcon />
</IconButton>
</Tooltip>
<Tooltip title="Supprimer">
<DeleteButton
color="red"
onDelete={deleteVideo(video.id)}
confirmLabel="Voulez vous vraiment supprimer cette vidéo ? Attention, elle ne sera plus accessible par les activités qui l'utilisent."
/>
</Tooltip>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
<VideoTable
videos={videos}
onDelete={deleteVideo}
onView={(video) => {
setSelectedVideo(video);
}}
/>
) : (
<p>{"Vous n'avez pas encore mis en ligne de vidéos !"}</p>
)}
Expand Down

0 comments on commit 2f592ac

Please sign in to comment.