|
|
@ -1,9 +1,10 @@ |
|
|
import Navbar from "../components/Navbar.jsx"; |
|
|
import Navbar from "../components/Navbar.jsx"; |
|
|
import {useEffect, useState} from "react"; |
|
|
import { useEffect, useState } from "react"; |
|
|
import PlaylistCard from "../components/PlaylistCard.jsx"; |
|
|
import PlaylistCard from "../components/PlaylistCard.jsx"; |
|
|
import VideoCard from "../components/VideoCard.jsx"; |
|
|
import VideoCard from "../components/VideoCard.jsx"; |
|
|
import {useNavigate} from "react-router-dom"; |
|
|
import { useNavigate } from "react-router-dom"; |
|
|
import CreateChannelModal from "../modals/CreateChannelModal.jsx"; |
|
|
import CreateChannelModal from "../modals/CreateChannelModal.jsx"; |
|
|
|
|
|
import CreatePlaylistModal from "../modals/CreatePlaylistModal.jsx"; |
|
|
import { getChannel, getUserHistory, getPlaylists, updateUser } from "../services/user.service.js"; |
|
|
import { getChannel, getUserHistory, getPlaylists, updateUser } from "../services/user.service.js"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -21,6 +22,7 @@ export default function Account() { |
|
|
const [userPlaylists, setUserPlaylists] = useState([]); |
|
|
const [userPlaylists, setUserPlaylists] = useState([]); |
|
|
const [userChannel, setUserChannel] = useState(null); |
|
|
const [userChannel, setUserChannel] = useState(null); |
|
|
const [isModalOpen, setIsModalOpen] = useState(false); |
|
|
const [isModalOpen, setIsModalOpen] = useState(false); |
|
|
|
|
|
const [isCreatePlaylistModalOpen, setIsCreatePlaylistModalOpen] = useState(false); |
|
|
const [alerts, setAlerts] = useState([]); |
|
|
const [alerts, setAlerts] = useState([]); |
|
|
|
|
|
|
|
|
const navigation = useNavigate(); |
|
|
const navigation = useNavigate(); |
|
|
@ -92,160 +94,166 @@ export default function Account() { |
|
|
<main className="px-36 pt-[118px] flex justify-between items-start"> |
|
|
<main className="px-36 pt-[118px] flex justify-between items-start"> |
|
|
{/* Left side */} |
|
|
{/* Left side */} |
|
|
|
|
|
|
|
|
{/* Profile / Edit profile */} |
|
|
{/* Profile / Edit profile */} |
|
|
<form className="glassmorphism w-1/3 p-10"> |
|
|
<form className="glassmorphism w-1/3 p-10"> |
|
|
<div className="relative w-1/3 aspect-square overflow-hidden mb-3 mx-auto" onMouseEnter={() => setIsPictureEditActive(true)} onMouseLeave={() => setIsPictureEditActive(false)} > |
|
|
<div className="relative w-1/3 aspect-square overflow-hidden mb-3 mx-auto" onMouseEnter={() => setIsPictureEditActive(true)} onMouseLeave={() => setIsPictureEditActive(false)} > |
|
|
<label htmlFor="image"> |
|
|
<label htmlFor="image"> |
|
|
<img |
|
|
<img |
|
|
src={user.picture} |
|
|
src={user.picture} |
|
|
className="w-full aspect-square rounded-full object-cover" |
|
|
className="w-full aspect-square rounded-full object-cover" |
|
|
/> |
|
|
/> |
|
|
<div className={`absolute w-full h-full bg-[#000000EF] flex items-center justify-center top-0 left-0 rounded-full ${(isPictureEditActive && editMode) ? "opacity-100 cursor-pointer" : "opacity-0 cursor-default"} ` } > |
|
|
<div className={`absolute w-full h-full bg-[#000000EF] flex items-center justify-center top-0 left-0 rounded-full ${(isPictureEditActive && editMode) ? "opacity-100 cursor-pointer" : "opacity-0 cursor-default"} `} > |
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" className="fill-white" viewBox="0 0 24 24"> |
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" className="fill-white" viewBox="0 0 24 24"> |
|
|
<path d="M19.045 7.401c.378-.378.586-.88.586-1.414s-.208-1.036-.586-1.414l-1.586-1.586c-.378-.378-.88-.586-1.414-.586s-1.036.208-1.413.585L4 13.585V18h4.413L19.045 7.401zm-3-3 1.587 1.585-1.59 1.584-1.586-1.585 1.589-1.584zM6 16v-1.585l7.04-7.018 1.586 1.586L7.587 16H6zm-2 4h16v2H4z"></path> |
|
|
<path d="M19.045 7.401c.378-.378.586-.88.586-1.414s-.208-1.036-.586-1.414l-1.586-1.586c-.378-.378-.88-.586-1.414-.586s-1.036.208-1.413.585L4 13.585V18h4.413L19.045 7.401zm-3-3 1.587 1.585-1.59 1.584-1.586-1.585 1.589-1.584zM6 16v-1.585l7.04-7.018 1.586 1.586L7.587 16H6zm-2 4h16v2H4z"></path> |
|
|
</svg> |
|
|
</svg> |
|
|
</div> |
|
|
</div> |
|
|
</label> |
|
|
|
|
|
<input type="file" accept="image/*" id="image" className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" disabled={!editMode}/> |
|
|
|
|
|
</div> |
|
|
|
|
|
<label htmlFor="name" className="text-2xl text-white mb-1 block font-montserrat"> |
|
|
|
|
|
Nom d'utilisateur |
|
|
|
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="text" |
|
|
|
|
|
id="name" |
|
|
|
|
|
value={username} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setUsername(e.target.value)} |
|
|
|
|
|
placeholder="Nom d'utilisateur" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
<label htmlFor="email" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
|
|
|
Adresse e-mail |
|
|
|
|
|
</label> |
|
|
</label> |
|
|
<input |
|
|
<input type="file" accept="image/*" id="image" className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" disabled={!editMode} /> |
|
|
type="email" |
|
|
</div> |
|
|
id="email" |
|
|
<label htmlFor="name" className="text-2xl text-white mb-1 block font-montserrat"> |
|
|
value={email} |
|
|
Nom d'utilisateur |
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
</label> |
|
|
onChange={(e) => setEmail(e.target.value)} |
|
|
<input |
|
|
placeholder="Adresse mail" |
|
|
type="text" |
|
|
disabled={!editMode} |
|
|
id="name" |
|
|
/> |
|
|
value={username} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
{ editMode && ( |
|
|
onChange={(e) => setUsername(e.target.value)} |
|
|
<> |
|
|
placeholder="Nom d'utilisateur" |
|
|
<label htmlFor="password" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
disabled={!editMode} |
|
|
Mot de passe |
|
|
/> |
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="password" |
|
|
|
|
|
id="password" |
|
|
|
|
|
value={password} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setPassword(e.target.value)} |
|
|
|
|
|
placeholder="**************" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
<label htmlFor="confirm-password" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
|
|
|
Confirmer le mot de passe |
|
|
|
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="password" |
|
|
|
|
|
id="confirm-password" |
|
|
|
|
|
value={confirmPassword} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setConfirmPassword(e.target.value)} |
|
|
|
|
|
placeholder="" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
</> |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
<label htmlFor="email" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
|
|
|
Adresse e-mail |
|
|
|
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="email" |
|
|
|
|
|
id="email" |
|
|
|
|
|
value={email} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setEmail(e.target.value)} |
|
|
|
|
|
placeholder="Adresse mail" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
{editMode && ( |
|
|
|
|
|
<> |
|
|
|
|
|
<label htmlFor="password" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
|
|
|
Mot de passe |
|
|
|
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="password" |
|
|
|
|
|
id="password" |
|
|
|
|
|
value={password} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setPassword(e.target.value)} |
|
|
|
|
|
placeholder="**************" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
<label htmlFor="confirm-password" className="text-2xl text-white mb-1 mt-4 block font-montserrat"> |
|
|
|
|
|
Confirmer le mot de passe |
|
|
|
|
|
</label> |
|
|
|
|
|
<input |
|
|
|
|
|
type="password" |
|
|
|
|
|
id="confirm-password" |
|
|
|
|
|
value={confirmPassword} |
|
|
|
|
|
className={(editMode ? editModeClasses : nonEditModeClasses)} |
|
|
|
|
|
onChange={(e) => setConfirmPassword(e.target.value)} |
|
|
|
|
|
placeholder="" |
|
|
|
|
|
disabled={!editMode} |
|
|
|
|
|
/> |
|
|
|
|
|
</> |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
<div className="flex justify-center mt-5"> |
|
|
<div className="flex justify-center mt-5"> |
|
|
{ |
|
|
{ |
|
|
editMode ? ( |
|
|
editMode ? ( |
|
|
<div> |
|
|
<div> |
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer" |
|
|
|
|
|
onClick={handleUpdateUser} |
|
|
|
|
|
> |
|
|
|
|
|
Enregistrer |
|
|
|
|
|
</button> |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="bg-red-500 p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer ml-3" |
|
|
|
|
|
onClick={() => setEditMode(!editMode)} |
|
|
|
|
|
> |
|
|
|
|
|
Annuler |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<button |
|
|
<button |
|
|
type="button" |
|
|
type="button" |
|
|
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer" |
|
|
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer" |
|
|
|
|
|
onClick={handleUpdateUser} |
|
|
|
|
|
> |
|
|
|
|
|
Enregistrer |
|
|
|
|
|
</button> |
|
|
|
|
|
<button |
|
|
|
|
|
type="button" |
|
|
|
|
|
className="bg-red-500 p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer ml-3" |
|
|
onClick={() => setEditMode(!editMode)} |
|
|
onClick={() => setEditMode(!editMode)} |
|
|
> |
|
|
> |
|
|
Modifier le profil |
|
|
Annuler |
|
|
</button> |
|
|
</button> |
|
|
) |
|
|
</div> |
|
|
} |
|
|
) : ( |
|
|
</div> |
|
|
<button |
|
|
</form> |
|
|
type="button" |
|
|
|
|
|
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer" |
|
|
|
|
|
onClick={() => setEditMode(!editMode)} |
|
|
|
|
|
> |
|
|
|
|
|
Modifier le profil |
|
|
|
|
|
</button> |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
</div> |
|
|
|
|
|
</form> |
|
|
|
|
|
|
|
|
{ /* Right side */} |
|
|
{ /* Right side */} |
|
|
|
|
|
|
|
|
<div className="w-2/3 flex flex-col items-start pl-10"> |
|
|
<div className="w-2/3 flex flex-col items-start pl-10"> |
|
|
{/* Channel */} |
|
|
{/* Channel */} |
|
|
{userChannel ? ( |
|
|
{userChannel ? ( |
|
|
<div className="glassmorphism p-10 w-full flex justify-between"> |
|
|
<div className="glassmorphism p-10 w-full flex justify-between"> |
|
|
<p className="text-3xl text-white mb-2 font-montserrat font-bold">{userChannel.channel.name}</p> |
|
|
<p className="text-3xl text-white mb-2 font-montserrat font-bold">{userChannel.channel.name}</p> |
|
|
<button> |
|
|
<button> |
|
|
<span onClick={() => navigation(`/manage-channel/${userChannel.channel.id}`)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer"> |
|
|
<span onClick={() => navigation(`/manage-channel/${userChannel.channel.id}`)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer"> |
|
|
Gérer la chaîne |
|
|
Gérer la chaîne |
|
|
</span> |
|
|
</span> |
|
|
</button> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<div className="glassmorphism p-10 w-full"> |
|
|
|
|
|
<h2 className="text-3xl font-bold text-white mb-4">Chaîne</h2> |
|
|
|
|
|
<p className="text-xl text-white mb-2">Aucune chaîne associée à ce compte.</p> |
|
|
|
|
|
<button className=" mt-4"> |
|
|
|
|
|
<a onClick={() => setIsModalOpen(true)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer"> |
|
|
|
|
|
Créer une chaîne |
|
|
|
|
|
</a> |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* Playlists */} |
|
|
|
|
|
<h2 className="font-montserrat font-bold text-3xl text-white mt-10" >Playlists</h2> |
|
|
|
|
|
<div className="w-full mt-5 flex flex-wrap" > |
|
|
|
|
|
{ |
|
|
|
|
|
userPlaylists && userPlaylists.map((playlist, index) => ( |
|
|
|
|
|
<PlaylistCard playlist={playlist} key={index} onClick={handlePlaylistClick} /> |
|
|
|
|
|
)) |
|
|
|
|
|
} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
{/* History */} |
|
|
) : ( |
|
|
<h2 className="font-montserrat font-bold text-3xl text-white mt-10" >Historique</h2> |
|
|
<div className="glassmorphism p-10 w-full"> |
|
|
<div className="w-full mt-5 flex flex-wrap gap-2" > |
|
|
<h2 className="text-3xl font-bold text-white mb-4">Chaîne</h2> |
|
|
{ |
|
|
<p className="text-xl text-white mb-2">Aucune chaîne associée à ce compte.</p> |
|
|
userHistory && userHistory.map((video, index) => ( |
|
|
<button className=" mt-4"> |
|
|
<div className="w-1/3" key={index}> |
|
|
<a onClick={() => setIsModalOpen(true)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-semibold cursor-pointer"> |
|
|
<VideoCard video={video}/> |
|
|
Créer une chaîne |
|
|
</div> |
|
|
</a> |
|
|
)) |
|
|
</button> |
|
|
} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* Playlists */} |
|
|
|
|
|
<div className="flex justify-between items-center w-full mt-10"> |
|
|
|
|
|
<h2 className="font-montserrat font-bold text-3xl text-white" >Playlists</h2> |
|
|
|
|
|
<button onClick={() => setIsCreatePlaylistModalOpen(true)} className="bg-primary p-3 rounded-sm text-white font-montserrat text-lg font-semibold cursor-pointer"> |
|
|
|
|
|
Créer une playlist |
|
|
|
|
|
</button> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className="w-full mt-5 flex flex-wrap" > |
|
|
|
|
|
{ |
|
|
|
|
|
userPlaylists && userPlaylists.map((playlist, index) => ( |
|
|
|
|
|
<PlaylistCard playlist={playlist} key={index} onClick={handlePlaylistClick} /> |
|
|
|
|
|
)) |
|
|
|
|
|
} |
|
|
|
|
|
</div> |
|
|
|
|
|
{/* History */} |
|
|
|
|
|
<h2 className="font-montserrat font-bold text-3xl text-white mt-10" >Historique</h2> |
|
|
|
|
|
<div className="w-full mt-5 flex flex-wrap gap-2" > |
|
|
|
|
|
{ |
|
|
|
|
|
userHistory && userHistory.map((video, index) => ( |
|
|
|
|
|
<div className="w-1/3" key={index}> |
|
|
|
|
|
<VideoCard video={video} /> |
|
|
|
|
|
</div> |
|
|
|
|
|
)) |
|
|
|
|
|
} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
</main> |
|
|
</main> |
|
|
<CreateChannelModal isOpen={isModalOpen} onClose={() => closeModal()} addAlert={addAlert} /> |
|
|
<CreateChannelModal isOpen={isModalOpen} onClose={() => closeModal()} addAlert={addAlert} /> |
|
|
|
|
|
<CreatePlaylistModal isOpen={isCreatePlaylistModalOpen} onClose={() => setIsCreatePlaylistModalOpen(false)} addAlert={addAlert} /> |
|
|
</div> |
|
|
</div> |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|