27 changed files with 2283 additions and 496 deletions
File diff suppressed because it is too large
@ -0,0 +1,95 @@ |
|||
import React from "react"; |
|||
import Navbar from "../components/Navbar"; |
|||
import { useEffect, useState } from "react"; |
|||
import { getAllUserSubscriptions, getAllUserSubscriptionVideos } from "../services/user.service.js"; |
|||
import { useAuth } from "../contexts/AuthContext.jsx"; |
|||
import VideoCard from "../components/VideoCard.jsx"; |
|||
import { useNavigate } from "react-router-dom"; |
|||
|
|||
export default function Subscription() { |
|||
|
|||
const navigate = useNavigate(); |
|||
|
|||
const [alerts, setAlerts] = useState([]); |
|||
const [subscriptions, setSubscriptions] = React.useState([]); |
|||
const [videos, setVideos] = useState([]); |
|||
const {user, isAuth} = useAuth(); |
|||
|
|||
useEffect(() => { |
|||
fetchSubscriptions(); |
|||
fetchSubscriptionVideos(); |
|||
}, []); |
|||
|
|||
const fetchSubscriptions = async () => { |
|||
const token = localStorage.getItem('token'); |
|||
if (!token) { |
|||
addAlert('error', "User not authenticated"); |
|||
return; |
|||
} |
|||
|
|||
const data = await getAllUserSubscriptions(user.id, token, addAlert); |
|||
if (data) { |
|||
setSubscriptions(data); |
|||
} |
|||
}; |
|||
|
|||
const fetchSubscriptionVideos = async () => { |
|||
const token = localStorage.getItem('token'); |
|||
if (!token) { |
|||
addAlert('error', "User not authenticated"); |
|||
return; |
|||
} |
|||
|
|||
const data = await getAllUserSubscriptionVideos(user.id, token, addAlert); |
|||
if (data) { |
|||
setVideos(data); |
|||
} |
|||
}; |
|||
const addAlert = (type, message) => { |
|||
const newAlert = { type, message, id: Date.now() }; // Add unique ID |
|||
setAlerts([...alerts, newAlert]); |
|||
}; |
|||
|
|||
const onCloseAlert = (alertToRemove) => { |
|||
setAlerts(alerts.filter(alert => alert !== alertToRemove)); |
|||
}; |
|||
|
|||
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="px-5 lg:px-36 w-full pt-[48px] lg:pt-[118px] lg:flex gap-8"> |
|||
|
|||
{/* LEFT SIDE (subscription list) */} |
|||
<div className="w-full lg:w-1/4 border-b border-gray-200 lg:border-b-0 mb-8 lg:mb-0 pb-2 lg:pb-0"> |
|||
<h2 className="text-2xl text-white font-montserrat font-semibold mb-4">Mes Abonnements</h2> |
|||
<ul className="space-y-2"> |
|||
{subscriptions.map(subscription => ( |
|||
<li |
|||
key={subscription.id} |
|||
className="p-2 flex items-center lg:border-r lg:border-gray-200 glassmorphism w-max lg:w-auto" |
|||
onClick={() => navigate(`/channel/${subscription.channel_id}`)} |
|||
> |
|||
<img |
|||
src={subscription.picture} |
|||
alt={subscription.channel_name} |
|||
className="w-14 aspect-square rounded-full inline-block mr-2 align-middle" |
|||
/> |
|||
<p className="text-white text-lg font-montserrat font-medium" >{subscription.channel_name}</p> |
|||
</li> |
|||
))} |
|||
</ul> |
|||
</div> |
|||
|
|||
{/* RIGHT SIDE (videos from subscriptions) */} |
|||
<div className="flex-1 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4"> |
|||
{videos.map(video => ( |
|||
<VideoCard key={video.id} video={video} /> |
|||
))} |
|||
</div> |
|||
|
|||
|
|||
</main> |
|||
</div> |
|||
); |
|||
} |
|||
Loading…
Reference in new issue