Enable users to manage video playlists and mark favorite content
Adds new user, playlist, and favorites management API endpoints and React components. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 50814a1e-92e4-4968-856f-7bc7eedf5e8f Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/50814a1e-92e4-4968-856f-7bc7eedf5e8f/hISDNbZ
This commit is contained in:
@@ -247,6 +247,198 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// User routes
|
||||
app.get("/api/users/:id", async (req, res) => {
|
||||
try {
|
||||
const user = await storage.getUser(req.params.id);
|
||||
if (!user) {
|
||||
return res.status(404).json({ message: "User not found" });
|
||||
}
|
||||
// Don't send password hash
|
||||
const { passwordHash, ...safeUser } = user;
|
||||
res.json(safeUser);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch user" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/users", async (req, res) => {
|
||||
try {
|
||||
const userData = req.body;
|
||||
const user = await storage.createUser(userData);
|
||||
const { passwordHash, ...safeUser } = user;
|
||||
res.status(201).json(safeUser);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to create user" });
|
||||
}
|
||||
});
|
||||
|
||||
// Playlist routes
|
||||
app.get("/api/playlists", async (req, res) => {
|
||||
try {
|
||||
const userId = req.query.userId as string;
|
||||
const limit = parseInt(req.query.limit as string) || 20;
|
||||
const offset = parseInt(req.query.offset as string) || 0;
|
||||
|
||||
if (!userId) {
|
||||
return res.status(400).json({ message: "userId is required" });
|
||||
}
|
||||
|
||||
const playlists = await storage.getPlaylists(userId, limit, offset);
|
||||
res.json(playlists);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch playlists" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/playlists/:id", async (req, res) => {
|
||||
try {
|
||||
const userId = req.query.userId as string;
|
||||
const playlist = await storage.getPlaylist(req.params.id, userId);
|
||||
if (!playlist) {
|
||||
return res.status(404).json({ message: "Playlist not found" });
|
||||
}
|
||||
res.json(playlist);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/playlists", async (req, res) => {
|
||||
try {
|
||||
const playlist = await storage.createPlaylist(req.body);
|
||||
res.status(201).json(playlist);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to create playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
app.put("/api/playlists/:id", async (req, res) => {
|
||||
try {
|
||||
const userId = req.query.userId as string;
|
||||
if (!userId) {
|
||||
return res.status(400).json({ message: "userId is required" });
|
||||
}
|
||||
|
||||
const playlist = await storage.updatePlaylist(req.params.id, req.body, userId);
|
||||
if (!playlist) {
|
||||
return res.status(404).json({ message: "Playlist not found or access denied" });
|
||||
}
|
||||
res.json(playlist);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to update playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/playlists/:id", async (req, res) => {
|
||||
try {
|
||||
const userId = req.query.userId as string;
|
||||
if (!userId) {
|
||||
return res.status(400).json({ message: "userId is required" });
|
||||
}
|
||||
|
||||
const success = await storage.deletePlaylist(req.params.id, userId);
|
||||
if (!success) {
|
||||
return res.status(404).json({ message: "Playlist not found or access denied" });
|
||||
}
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to delete playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
// Playlist videos routes
|
||||
app.get("/api/playlists/:id/videos", async (req, res) => {
|
||||
try {
|
||||
const videos = await storage.getPlaylistVideos(req.params.id);
|
||||
res.json(videos);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch playlist videos" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/playlists/:id/videos", async (req, res) => {
|
||||
try {
|
||||
const playlistVideo = await storage.addVideoToPlaylist({
|
||||
playlistId: req.params.id,
|
||||
videoId: req.body.videoId,
|
||||
position: req.body.position || 0
|
||||
});
|
||||
res.status(201).json(playlistVideo);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes("already in playlist")) {
|
||||
return res.status(409).json({ message: error.message });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to add video to playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/playlists/:playlistId/videos/:videoId", async (req, res) => {
|
||||
try {
|
||||
const success = await storage.removeVideoFromPlaylist(req.params.playlistId, req.params.videoId);
|
||||
if (!success) {
|
||||
return res.status(404).json({ message: "Video not found in playlist" });
|
||||
}
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to remove video from playlist" });
|
||||
}
|
||||
});
|
||||
|
||||
// Favorites routes
|
||||
app.get("/api/favorites", async (req, res) => {
|
||||
try {
|
||||
const userId = req.query.userId as string;
|
||||
const limit = parseInt(req.query.limit as string) || 20;
|
||||
const offset = parseInt(req.query.offset as string) || 0;
|
||||
|
||||
if (!userId) {
|
||||
return res.status(400).json({ message: "userId is required" });
|
||||
}
|
||||
|
||||
const favorites = await storage.getUserFavorites(userId, limit, offset);
|
||||
res.json(favorites);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch favorites" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/favorites", async (req, res) => {
|
||||
try {
|
||||
const favorite = await storage.addToFavorites({
|
||||
userId: req.body.userId,
|
||||
videoId: req.body.videoId
|
||||
});
|
||||
res.status(201).json(favorite);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && error.message.includes("already in favorites")) {
|
||||
return res.status(409).json({ message: error.message });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to add to favorites" });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/favorites/:userId/:videoId", async (req, res) => {
|
||||
try {
|
||||
const success = await storage.removeFromFavorites(req.params.userId, req.params.videoId);
|
||||
if (!success) {
|
||||
return res.status(404).json({ message: "Favorite not found" });
|
||||
}
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to remove from favorites" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/favorites/:userId/:videoId", async (req, res) => {
|
||||
try {
|
||||
const isFavorited = await storage.isVideoFavorited(req.params.userId, req.params.videoId);
|
||||
res.json({ isFavorited });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to check favorite status" });
|
||||
}
|
||||
});
|
||||
|
||||
const httpServer = createServer(app);
|
||||
return httpServer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user