From 87b8be0b658c59cf2f0bdcc369d91311404305a5 Mon Sep 17 00:00:00 2001 From: vantage-ola Date: Mon, 26 Aug 2024 15:25:52 +0100 Subject: [PATCH] discover: youtube --- tracknow/web/src/App.tsx | 3 + tracknow/web/src/Types.ts | 55 +++++++++-- .../web/src/components/Discover/Discover.tsx | 11 +++ .../web/src/components/Discover/Youtube.tsx | 99 +++++++++++++++++++ .../src/components/SideBar/LeftSideBar.tsx | 4 +- tracknow/web/src/hooks/API.ts | 25 ++++- tracknow/web/src/hooks/useInternet.ts | 23 +++++ tracknow/web/src/misc/miscFunctions.tsx | 7 +- 8 files changed, 210 insertions(+), 17 deletions(-) create mode 100644 tracknow/web/src/components/Discover/Discover.tsx create mode 100644 tracknow/web/src/components/Discover/Youtube.tsx create mode 100644 tracknow/web/src/hooks/useInternet.ts diff --git a/tracknow/web/src/App.tsx b/tracknow/web/src/App.tsx index b1ca845..fd7ce1f 100644 --- a/tracknow/web/src/App.tsx +++ b/tracknow/web/src/App.tsx @@ -9,6 +9,7 @@ import { UserLogin } from "./components/User/UserLogin"; import { UserSignUp } from "./components/User/UserSignUp"; import { Welcome } from "./components/Welcome/Welcome"; import { Home } from "./components/Home/Home"; +import Discover from "./components/Discover/Discover"; import UserAddLaptimes from "./components/User/UserAddLaptimes"; import UserAccountSettings from "./components/User/UserAccountSettings"; @@ -55,6 +56,7 @@ export const App = () => { } /> + {/*user is logged in */} @@ -67,6 +69,7 @@ export const App = () => { }> + } /> void; -} +}; export interface EditUser { username?: string; password?: string; nationality?: string; -} +}; export interface EditUserPic { profile_picture_url?: string; -} +}; export interface UserData { userId: number; @@ -87,7 +87,7 @@ export interface UserData { editProfile: (editProfile: EditUser) => Promise; editProfilePic: (editProfilePic: EditUserPic) => Promise; loading: boolean -} +}; export interface F1DriverStanding { position: string; @@ -97,7 +97,7 @@ export interface F1DriverStanding { }; Constructors: Array<{ name: string }>; points: string; -} +}; export interface F1ConstructorStanding { position: string; @@ -105,4 +105,39 @@ export interface F1ConstructorStanding { name: string; }; points: string; -} \ No newline at end of file +}; + +export interface YoutubeSearchResult { + kind: string; + etag: string; + id: { + kind: string; + videoId: string; + }; + snippet: { + publishedAt: string; + channelId: string; + title: string; + description: string; + thumbnails: { + default: { + url: string; + width: number; + height: number; + }; + medium: { + url: string; + width: number; + height: number; + }; + high: { + url: string; + width: number; + height: number; + }; + }; + channelTitle: string; + liveBroadcastContent: string; + publishTime: string; + }; +}; diff --git a/tracknow/web/src/components/Discover/Discover.tsx b/tracknow/web/src/components/Discover/Discover.tsx new file mode 100644 index 0000000..c2cddfc --- /dev/null +++ b/tracknow/web/src/components/Discover/Discover.tsx @@ -0,0 +1,11 @@ +import Youtube from "./Youtube"; +const Discover: React.FC = () => { + + return ( + <> + + + ); +}; + +export default Discover; \ No newline at end of file diff --git a/tracknow/web/src/components/Discover/Youtube.tsx b/tracknow/web/src/components/Discover/Youtube.tsx new file mode 100644 index 0000000..e455afb --- /dev/null +++ b/tracknow/web/src/components/Discover/Youtube.tsx @@ -0,0 +1,99 @@ +import * as React from "react"; +import { Box, Card, CardBody, Flex, HStack, Icon, Stack, Text } from "@chakra-ui/react"; +import useMiscFunctions from "../../misc/miscFunctions"; +import { FaYoutube, FaHashtag } from "react-icons/fa"; +import { formatDistanceToNow } from "date-fns"; + +import getInternetData from "../../hooks/useInternet"; +import { YoutubeSearchResult } from "../../Types"; + +const Youtube: React.FC = () => { + + const { LazyLoadYoutubeEmbed } = useMiscFunctions(); + const { fetchYoutube } = getInternetData(); + + const [youtube, setYoutube] = React.useState([]); + + React.useEffect(() => { + const fetchData = async () => { + const youtubeData = await fetchYoutube(); + setYoutube(youtubeData); + }; + fetchData(); + }) + return ( + <> + {youtube.map((video) => ( + + + + {video.snippet.title} + + {formatDistanceToNow(new Date(video.snippet.publishedAt), { addSuffix: true })} + + + + + + + + + + + + + {video.snippet.channelTitle} + + + + + + + + + + simracing + + + + + + + + + + motorsports + + + + + + + {video.snippet.description} + + + ))} + + ); + +}; + +export default Youtube; \ No newline at end of file diff --git a/tracknow/web/src/components/SideBar/LeftSideBar.tsx b/tracknow/web/src/components/SideBar/LeftSideBar.tsx index 4f8b262..8a1f4c0 100644 --- a/tracknow/web/src/components/SideBar/LeftSideBar.tsx +++ b/tracknow/web/src/components/SideBar/LeftSideBar.tsx @@ -19,7 +19,7 @@ interface SideItemProps extends FlexProps { const LinkItems: Array = [ { name: 'Home', icon: FiHome, disabled: false }, - { name: 'Discover', icon: FiGlobe, disabled: true }, + { name: 'Discover', icon: FiGlobe, disabled: false }, { name: 'Events', icon: FiCalendar, disabled: true }, { name: 'Leaderboard', icon: FiAward, disabled: true }, { name: 'Setups', icon: FiSettings, disabled: true }, @@ -31,8 +31,8 @@ const LinkItems: Array = [ const linkMap: { [key: string]: string } = { Home: "/home", + Discover: "/discover", - // TODO make this items open in a new page. Donate: 'https://www.buymeacoffee.com/vantageola', Contribute: 'https://github.com/vantage-ola', diff --git a/tracknow/web/src/hooks/API.ts b/tracknow/web/src/hooks/API.ts index c248f8f..67237c3 100644 --- a/tracknow/web/src/hooks/API.ts +++ b/tracknow/web/src/hooks/API.ts @@ -37,7 +37,10 @@ const endpoints = { // formula 1 standings FORMULA_1_TEAMS: `${API_PREFIX_URL}/f1/teams`, - FORMULA_1_DRIVERS: `${API_PREFIX_URL}/f1/drivers` + FORMULA_1_DRIVERS: `${API_PREFIX_URL}/f1/drivers`, + + // content from internet + YOUTUBE: (date: string) => `${API_PREFIX_URL}/internet/youtube?date=${date}` }; @@ -331,6 +334,23 @@ async function fetchF1Drivers() { return data; }; +// function to fetch daily youtube data +async function fetchYoutube(date: string) { + const response = await fetch(endpoints.YOUTUBE(date), { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + } + }); + + if (!response.ok) { + throw new Error(`Failed to fetch youtube data`) + }; + + const data = await response.json(); + return data; +}; + const API = { fetchUser, fetchUsers, @@ -345,7 +365,8 @@ const API = { fetchAUserLaptime, fetchUsersLaptimes, fetchF1Drivers, - fetchF1Teams + fetchF1Teams, + fetchYoutube }; diff --git a/tracknow/web/src/hooks/useInternet.ts b/tracknow/web/src/hooks/useInternet.ts new file mode 100644 index 0000000..4fa0e7a --- /dev/null +++ b/tracknow/web/src/hooks/useInternet.ts @@ -0,0 +1,23 @@ +import API from "./API"; + +const getInternetData = () => { + + const fetchYoutube = async () => { + + const currentDate = new Date().toLocaleDateString('en-CA'); //YYYY-MM-DD + + try { + const response = await API.fetchYoutube(currentDate); + return response; + + } catch (error) { + throw new Error("Error Fetching Youtube Data !"); + } + + + }; + + return { fetchYoutube } +}; + +export default getInternetData; \ No newline at end of file diff --git a/tracknow/web/src/misc/miscFunctions.tsx b/tracknow/web/src/misc/miscFunctions.tsx index 9eeb8fb..6449593 100644 --- a/tracknow/web/src/misc/miscFunctions.tsx +++ b/tracknow/web/src/misc/miscFunctions.tsx @@ -27,10 +27,10 @@ const useMiscFunctions = () => { overflow: "hidden", }; - const getYouTubeId = (url: string) => { + const getYouTubeId = (urlOrId: string) => { const regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; - const match = url.match(regExp); - return (match && match[7].length === 11) ? match[7] : false; + const match = urlOrId.match(regExp); + return (match && match[7].length === 11) ? match[7] : urlOrId; } const youtubeID = getYouTubeId(youtubeLink); @@ -50,6 +50,7 @@ const useMiscFunctions = () => { ); }; + const dummyLaptimes = [ { title: "Fast Lap at Brands Hatch",