ADD functionality to fetch and display user clips in MyClips component
This commit is contained in:
@@ -4,28 +4,28 @@ import {Link} from "react-router-dom";
|
|||||||
|
|
||||||
type VideoCardProps = {
|
type VideoCardProps = {
|
||||||
title: string,
|
title: string,
|
||||||
length: number,
|
duration: number,
|
||||||
thumbnailUrl: string,
|
thumbnailPath: string,
|
||||||
videoUrl: string,
|
videoPath: string,
|
||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const VideoCard = ({
|
const VideoCard = ({
|
||||||
title,
|
title,
|
||||||
length,
|
duration,
|
||||||
thumbnailUrl,
|
thumbnailPath,
|
||||||
videoUrl,
|
videoPath,
|
||||||
className}: VideoCardProps) => {
|
className}: VideoCardProps) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
to={videoUrl}
|
to={videoPath}
|
||||||
>
|
>
|
||||||
<div className={clsx("flex flex-col", className)}>
|
<div className={clsx("flex flex-col", className)}>
|
||||||
<img src={thumbnailUrl} alt="Video Thumbnail" />
|
<img src={thumbnailPath} alt="Video Thumbnail" />
|
||||||
|
|
||||||
<div className={"flex flex-row justify-between items-center p-2"}>
|
<div className={"flex flex-row justify-between items-center p-2"}>
|
||||||
<p>{title}</p>
|
<p>{title}</p>
|
||||||
<p>{formatTime(length)}</p>
|
<p>{formatTime(duration)}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,17 +1,30 @@
|
|||||||
import VideoCard from "../components/video/VideoCard";
|
import VideoCard from "../components/video/VideoCard";
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import { getClips } from "../utils/endpoints";
|
||||||
|
import type { Clip } from "../utils/types";
|
||||||
|
|
||||||
const MyClips = () => {
|
const MyClips = () => {
|
||||||
|
const [clips, setClips] = useState<Clip[]>([]);
|
||||||
|
const [error, setError] = useState<null | string>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getClips(setError).then((data) => setClips(data));
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className={"flex flex-row"}>
|
||||||
<VideoCard
|
{clips.map((clip) => (
|
||||||
title={"My First Clip"}
|
<VideoCard
|
||||||
length={120}
|
key={clip.videoPath}
|
||||||
thumbnailUrl={"https://upload.wikimedia.org/wikipedia/commons/1/19/Billy_Joel_Shankbone_NYC_2009.jpg"}
|
title={clip.title}
|
||||||
videoUrl={"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}
|
duration={clip.duration}
|
||||||
className={"w-40"}
|
thumbnailPath={clip.thumbnailPath}
|
||||||
/>
|
videoPath={clip.videoPath}
|
||||||
|
className={"w-30 p-5"}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{error}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type {VideoMetadata, APIResponse, User} from "./types.ts";
|
import type {VideoMetadata, APIResponse, User, Clip} from "./types.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads a file to the backend.
|
* Uploads a file to the backend.
|
||||||
@@ -65,7 +65,9 @@ const editFile = async (
|
|||||||
/**
|
/**
|
||||||
* Triggers file processing.
|
* Triggers file processing.
|
||||||
*/
|
*/
|
||||||
const processFile = async (uuid: string, setError: Function): Promise<boolean> => {
|
const processFile = async (
|
||||||
|
uuid: string,
|
||||||
|
setError: Function): Promise<boolean> => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/v1/process/${uuid}`);
|
const response = await fetch(`/api/v1/process/${uuid}`);
|
||||||
|
|
||||||
@@ -85,7 +87,8 @@ const processFile = async (uuid: string, setError: Function): Promise<boolean> =
|
|||||||
/**
|
/**
|
||||||
* Fetches the processing progress percentage.
|
* Fetches the processing progress percentage.
|
||||||
*/
|
*/
|
||||||
const getProgress = async (uuid: string): Promise<number> => {
|
const getProgress = async (
|
||||||
|
uuid: string): Promise<number> => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/v1/progress/${uuid}`);
|
const response = await fetch(`/api/v1/progress/${uuid}`);
|
||||||
|
|
||||||
@@ -105,7 +108,8 @@ const getProgress = async (uuid: string): Promise<number> => {
|
|||||||
/**
|
/**
|
||||||
* Fetches original metadata from the backend.
|
* Fetches original metadata from the backend.
|
||||||
*/
|
*/
|
||||||
const getMetadata = async (uuid: string): Promise<VideoMetadata> => {
|
const getMetadata = async (
|
||||||
|
uuid: string): Promise<VideoMetadata> => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/v1/metadata/original/${uuid}`);
|
const response = await fetch(`/api/v1/metadata/original/${uuid}`);
|
||||||
|
|
||||||
@@ -143,11 +147,32 @@ const getUser = async (): Promise<null | User > => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getClips = async (setError: Function): Promise< Clip[]> => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/v1/clips/', {credentials: "include",});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorResult: APIResponse = await response.json();
|
||||||
|
setError(errorResult.message);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const result: APIResponse = await response.json();
|
||||||
|
return result.data;
|
||||||
|
|
||||||
|
} catch (error: unknown) {
|
||||||
|
console.error('Error fetching clips:', error);
|
||||||
|
setError('Failed to fetch clips');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
uploadFile,
|
uploadFile,
|
||||||
editFile,
|
editFile,
|
||||||
processFile,
|
processFile,
|
||||||
getProgress,
|
getProgress,
|
||||||
getMetadata,
|
getMetadata,
|
||||||
getUser
|
getUser,
|
||||||
|
getClips
|
||||||
};
|
};
|
||||||
@@ -21,8 +21,21 @@ type User = {
|
|||||||
profilePicture: string
|
profilePicture: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Clip = {
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
duration: number,
|
||||||
|
thumbnailPath: string,
|
||||||
|
videoPath: string,
|
||||||
|
fps: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
createdAt: string,
|
||||||
|
}
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
APIResponse,
|
APIResponse,
|
||||||
VideoMetadata,
|
VideoMetadata,
|
||||||
User
|
User,
|
||||||
|
Clip
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ import com.ddf.vodsystem.entities.APIResponse;
|
|||||||
import com.ddf.vodsystem.entities.Clip;
|
import com.ddf.vodsystem.entities.Clip;
|
||||||
import com.ddf.vodsystem.exceptions.NotAuthenticated;
|
import com.ddf.vodsystem.exceptions.NotAuthenticated;
|
||||||
import com.ddf.vodsystem.services.ClipService;
|
import com.ddf.vodsystem.services.ClipService;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||||
|
|||||||
Reference in New Issue
Block a user