You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

222 lines
9.4 KiB

import Navbar from "../components/Navbar.jsx";
import {useEffect, useState} from "react";
import {useNavigate, useParams} from "react-router-dom";
import {useAuth} from "../contexts/AuthContext.jsx";
import VideoStatListElement from "../components/VideoStatListElement.jsx";
export default function ManageChannel() {
const {id} = useParams();
const {user} = useAuth();
const navigate = useNavigate();
const [channel, setChannel] = useState();
const [channelStats, setChannelStats] = useState();
const [channelName, setChannelName] = useState(null);
const [description, setDescription] = useState(null);
const [editMode, setEditMode] = useState(false);
const [alerts, setAlerts] = useState([]);
const token = localStorage.getItem("token");
const nonEditModeClasses = "text-2xl font-bold text-white p-2 focus:text-white focus:outline-none w-full font-montserrat resizable-none text-center";
const editModeClasses = nonEditModeClasses + " glassmorphism";
const nonEditModeClassesTextArea = "text-md font-normal text-white p-2 focus:text-white focus:outline-none w-full font-montserrat resizable-none w-full"
const editModeClassesTextArea = nonEditModeClassesTextArea + " glassmorphism h-48";
useEffect(() => {
fetchChannelData()
fetchChannelStats()
}, []);
const fetchChannelData = async () => {
try {
const request = await fetch(`/api/channels/${id}`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
}
})
const result = await request.json();
setChannel(result);
} catch (error) {
console.error("Error fetching channel data:", error);
}
}
const fetchChannelStats = async () => {
try {
const request = await fetch(`/api/channels/${id}/stats`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
}
})
const result = await request.json();
setChannelStats(result);
} catch (error) {
console.error("Error fetching channel stats", error);
}
}
const handleUpdateChannel = async () => {
if (!editMode) return;
try {
const response = await fetch(`/api/channels/${id}`, {
method: "PUT",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
body: JSON.stringify({
name: channelName || channel.name,
description: description || channel.description,
})
});
if (response.ok) {
setEditMode(false);
addAlert('success', 'Chaîne mise à jour avec succès');
fetchChannelData(); // Refresh channel data after update
} else {
console.error("Failed to update channel");
const errorData = await response.json();
addAlert('error', errorData.message || 'Erreur lors de la mise à jour de la chaîne');
}
} catch (error) {
console.error("Error updating channel:", error);
addAlert('error', 'Erreur lors de la mise à jour de la chaîne');
}
}
const onCloseAlert = (alertToRemove) => {
setAlerts(alerts.filter(alert => alert !== alertToRemove));
};
const addAlert = (type, message) => {
const newAlert = { type, message, id: Date.now() }; // Add unique ID
setAlerts([...alerts, newAlert]);
};
return (
<div className="min-w-screen min-h-screen bg-linear-to-br from-left-gradient to-right-gradient">
<Navbar isSearchPage={false} alerts={alerts} onCloseAlert={onCloseAlert} />
<main className="pt-[118px] px-36 flex">
{/* LEFT SIDE */}
<form className="glassmorphism w-1/3 h-screen py-10 px-4">
<img src={user.picture} className="w-1/3 aspect-square object-cover rounded-full mx-auto" alt=""/>
<label htmlFor="name" className={`text-2xl text-white mb-1 block font-montserrat ${editMode ? "block" : "hidden"} `}>
Nom de chaine
</label>
<input
type="text"
id="name"
value={channelName || channelName === "" ? channelName : channel ? channel.name : "Chargement"}
className={(editMode ? editModeClasses : nonEditModeClasses)}
onChange={(e) => setChannelName(e.target.value)}
placeholder="Nom d'utilisateur"
disabled={!editMode}
/>
<label htmlFor="name" className={`text-2xl text-white mb-1 block font-montserrat`}>
Description
</label>
<textarea
name="description"
id=""
className={(editMode ? editModeClassesTextArea : nonEditModeClassesTextArea)}
value={description || description === "" ? description : channel ? channel.description : "Chargement"}
onChange={(e) => setDescription(e.target.value)}
placeholder="Description de votre chaine"
disabled={!editMode}
></textarea>
{
editMode ? (
<div className="mt-4">
<button
type="button"
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer"
onClick={handleUpdateChannel}
>
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
type="button"
className="bg-primary p-3 rounded-sm text-white font-montserrat text-2xl font-black cursor-pointer mt-4"
onClick={() => setEditMode(!editMode)}
>
Modifier
</button>
)
}
</form>
{/* RIGHT SIDE */}
<div className="w-2/3 h-screen pl-10" >
{/* VIEW / SUBSCRIBERS STATS */}
<div className="flex gap-4" >
<div className="glassmorphism flex-1 h-32 flex flex-col justify-center items-center" >
{/* TOTAL VIEWS */}
<p className="text-white text-xl font-montserrat font-semibold" >Vues totales</p>
<p className="text-white text-2xl font-montserrat font-bold" >{channelStats ? channelStats.views : "0"}</p>
</div>
<div className="glassmorphism flex-1 h-32 flex flex-col justify-center items-center" >
{/* TOTAL SUBSCRIBERS */}
<p className="text-white text-xl font-montserrat font-semibold" >Abonnés</p>
<p className="text-white text-2xl font-montserrat font-bold" >{channelStats ? channelStats.subscribers : "0"}</p>
</div>
</div>
{/* VIDEOS */}
<div className="flex justify-between">
<h2 className="text-white text-3xl font-montserrat font-bold mt-10" >Vidéos</h2>
<button
className="bg-primary px-2 py-1 rounded-sm text-white font-montserrat text-md font-semibold cursor-pointer mt-4"
onClick={() => navigate("/add-video")}
>
Ajouter une vidéo
</button>
</div>
{ channel?.videos?.length > 0 ? (
<div className="flex flex-col gap-4 mt-5">
{channel.videos.map((video) => (
<VideoStatListElement
video={video}
onClick={() => navigate("/manage-video/" + video.id)}
key={video.id}
/>
))}
</div>
) : (
<p className="text-white text-xl font-montserrat mt-4">Aucune vidéo trouvée pour cette chaîne.</p>
)}
</div>
</main>
</div>
)
}