diff --git a/frontend/src/pages/Following.tsx b/frontend/src/pages/FollowingPage.tsx
similarity index 100%
rename from frontend/src/pages/Following.tsx
rename to frontend/src/pages/FollowingPage.tsx
diff --git a/frontend/src/pages/Vods.tsx b/frontend/src/pages/Vods.tsx
deleted file mode 100644
index 934fbc2..0000000
--- a/frontend/src/pages/Vods.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import React, { useEffect, useState } from "react";
-import { useAuth } from "../context/AuthContext";
-import { useNavigate, useParams } from "react-router-dom";
-import DynamicPageContent from "../components/Layout/DynamicPageContent";
-
-interface Vod {
- vod_id: number;
- title: string;
- datetime: string;
- username: string;
- category_name: string;
- length: number;
- views: number;
-}
-
-const Vods: React.FC = () => {
- const navigate = useNavigate();
- const { username } = useParams<{ username?: string }>();
- const { isLoggedIn } = useAuth();
- const [ownedVods, setOwnedVods] = useState
([]);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
-
- useEffect(() => {
- if (!username) return;
-
- const fetchVods = async () => {
- try {
- const response = await fetch(`/api/vods/${username}`);
- if (!response.ok) throw new Error(`Failed to fetch VODs: ${response.statusText}`);
-
- const data = await response.json();
- setOwnedVods(data);
- } catch (err) {
- const errorMessage = err instanceof Error ? err.message : "Error fetching VODs.";
- setError(errorMessage);
- } finally {
- setLoading(false);
- }
- };
-
- fetchVods();
- }, [username]);
-
- if (loading) return Loading VODs...
;
- if (error) return {error}
;
-
- return (
-
-
-
-
{username}'s VODs
-
- {/* Horizontal Scrollable VOD List */}
-
- {ownedVods.length === 0 ? (
-
No VODs available.
- ) : (
- ownedVods.map((vod) => {
- const thumbnailUrl = `/vods/${username}/${vod.vod_id}.png`;
-
- return (
-
navigate(`/stream/${username}/vods/${vod.vod_id}`)}
- >
- {/* Thumbnail */}
-

{
- e.currentTarget.onerror = null;
- e.currentTarget.src = "/default-thumbnail.png";
- }}
- />
-
- {/* Video Info */}
-
-
{vod.title}
-
{username}
-
{vod.views} views
-
{new Date(vod.datetime).toLocaleString()}
-
-
- );
- })
- )}
-
-
-
-
- );
-};
-
-export default Vods;
diff --git a/frontend/src/pages/VodsPage.tsx b/frontend/src/pages/VodsPage.tsx
new file mode 100644
index 0000000..0803b83
--- /dev/null
+++ b/frontend/src/pages/VodsPage.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import DynamicPageContent from "../components/Layout/DynamicPageContent";
+import { useVods } from "../hooks/useContent";
+import ListRow from "../components/Layout/ListRow";
+import LoadingScreen from "../components/Layout/LoadingScreen";
+
+const VodsPage: React.FC = () => {
+ const { username } = useParams<{ username?: string }>();
+ const { vods, isLoading, error } = useVods(`/api/vods/${username}`);
+ const navigate = useNavigate();
+
+ if (isLoading) return Loading VODs...;
+ if (error) return Error loading VODs: {error};
+
+ return (
+
+
+
+
+ navigate(`/vods/${user}/${vodId}`)}
+ extraClasses="bg-black/50"
+ itemExtraClasses="w-[30vw]"
+ />
+
+
+
+ );
+};
+
+export default VodsPage;
diff --git a/web_server/database/testing_data.sql b/web_server/database/testing_data.sql
index 3bd0d26..a4bae89 100644
--- a/web_server/database/testing_data.sql
+++ b/web_server/database/testing_data.sql
@@ -129,14 +129,6 @@ INSERT INTO streams (user_id, title, start_time, category_id) VALUES
(26, 'Max Level, Max Power!', '2025-03-09 21:00:00', 26),
(27, 'Final Showdown!', '2025-03-10 17:00:00', 27);
--- Sample Data for vods
-INSERT INTO vods (user_id, title, datetime, category_id, length, views) VALUES
-(1, 'Epic Gaming Session', '2025-01-23 18:00:00', 1, 120, 500),
-(2, 'Live Music Jam', '2025-01-21 20:00:00', 2, 180, 800),
-(3, 'Sketching Live', '2025-01-22 15:00:00', 3, 90, 300),
-(4, 'Math Made Easy', '2025-01-21 10:00:00', 4, 150, 600),
-(5, 'Sports Highlights', '2025-01-19 12:00:00', 5, 210, 700);
-
-- Sample Data for tags
INSERT INTO tags(tag_name) VALUES
('English'),