ADD MyClips page and VideoCard component
This commit is contained in:
@@ -5,6 +5,7 @@ import ClipUpload from './pages/ClipUpload';
|
|||||||
import ClipEdit from './pages/ClipEdit';
|
import ClipEdit from './pages/ClipEdit';
|
||||||
import Home from './pages/Home';
|
import Home from './pages/Home';
|
||||||
import {useEffect} from "react";
|
import {useEffect} from "react";
|
||||||
|
import MyClips from './pages/MyClips';
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -19,6 +20,7 @@ function App() {
|
|||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/create" element={<ClipUpload />} />
|
<Route path="/create" element={<ClipUpload />} />
|
||||||
<Route path="/create/:id" element={<ClipEdit />} />
|
<Route path="/create/:id" element={<ClipEdit />} />
|
||||||
|
<Route path="/my-clips" element={<MyClips />} />
|
||||||
</Route>
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useEffect, useState} from "react";
|
|||||||
import { Volume1, Volume2, VolumeX, Play, Pause } from 'lucide-react';
|
import { Volume1, Volume2, VolumeX, Play, Pause } from 'lucide-react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import type { VideoMetadata } from "../../utils/types.ts";
|
import type { VideoMetadata } from "../../utils/types.ts";
|
||||||
|
import { formatTime } from "../../utils/utils.ts";
|
||||||
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -10,20 +11,6 @@ type Props = {
|
|||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function formatTime(seconds: number): string {
|
|
||||||
const h = Math.floor(seconds / 3600);
|
|
||||||
const m = Math.floor((seconds % 3600) / 60);
|
|
||||||
const s = Math.floor(seconds % 60);
|
|
||||||
|
|
||||||
const padded = (n: number) => n.toString().padStart(2, '0');
|
|
||||||
|
|
||||||
if (h > 0) {
|
|
||||||
return `${h}:${padded(m)}:${padded(s)}`;
|
|
||||||
} else {
|
|
||||||
return `${m}:${padded(s)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Playbar({ video, videoMetadata, className }: Props) {
|
export default function Playbar({ video, videoMetadata, className }: Props) {
|
||||||
const [isPlaying, setIsPlaying] = useState(false);
|
const [isPlaying, setIsPlaying] = useState(false);
|
||||||
const [volume, setVolume] = useState(100);
|
const [volume, setVolume] = useState(100);
|
||||||
|
|||||||
36
frontend/src/components/video/VideoCard.tsx
Normal file
36
frontend/src/components/video/VideoCard.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
import { formatTime } from "../../utils/utils.ts";
|
||||||
|
import {Link} from "react-router-dom";
|
||||||
|
|
||||||
|
type VideoCardProps = {
|
||||||
|
title: string,
|
||||||
|
length: number,
|
||||||
|
thumbnailUrl: string,
|
||||||
|
videoUrl: string,
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const VideoCard = ({
|
||||||
|
title,
|
||||||
|
length,
|
||||||
|
thumbnailUrl,
|
||||||
|
videoUrl,
|
||||||
|
className}: VideoCardProps) => {
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
to={videoUrl}
|
||||||
|
>
|
||||||
|
<div className={clsx("flex flex-col", className)}>
|
||||||
|
<img src={thumbnailUrl} alt="Video Thumbnail" />
|
||||||
|
|
||||||
|
<div className={"flex flex-row justify-between items-center p-2"}>
|
||||||
|
<p>{title}</p>
|
||||||
|
<p>{formatTime(length)}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VideoCard;
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import VideoCard from "../components/video/VideoCard";
|
||||||
|
|
||||||
|
const MyClips = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<VideoCard
|
||||||
|
title={"My First Clip"}
|
||||||
|
length={120}
|
||||||
|
thumbnailUrl={"https://upload.wikimedia.org/wikipedia/commons/1/19/Billy_Joel_Shankbone_NYC_2009.jpg"}
|
||||||
|
videoUrl={"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}
|
||||||
|
className={"w-40"}
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyClips;
|
||||||
|
|||||||
17
frontend/src/utils/utils.ts
Normal file
17
frontend/src/utils/utils.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
function formatTime(seconds: number): string {
|
||||||
|
const h = Math.floor(seconds / 3600);
|
||||||
|
const m = Math.floor((seconds % 3600) / 60);
|
||||||
|
const s = Math.floor(seconds % 60);
|
||||||
|
|
||||||
|
const padded = (n: number) => n.toString().padStart(2, '0');
|
||||||
|
|
||||||
|
if (h > 0) {
|
||||||
|
return `${h}:${padded(m)}:${padded(s)}`;
|
||||||
|
} else {
|
||||||
|
return `${m}:${padded(s)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
formatTime
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user