From 8dbc96fba4245ef058cdbaf65f30a290840f490f Mon Sep 17 00:00:00 2001 From: iitzIrFan Date: Mon, 26 May 2025 16:07:42 +0530 Subject: [PATCH] Add video details and broadcasting features - Implement VideoDetails component to display individual video information including title and description. - Create BroadcastsPage component to list videos and shorts with pagination. - Add video card component for displaying video thumbnails and titles. - Introduce CSS styles for video layout, cards, and responsive design. - Fetch video titles from YouTube oEmbed API for dynamic title display. - Implement tab navigation for switching between videos and shorts. - Enhance user experience with hover effects and loading states for video thumbnails. --- docusaurus.config.ts | 284 +++------------------- src/pages/broadcasts/details.tsx | 114 +++++++++ src/pages/broadcasts/index.css | 397 +++++++++++++++++++++++++++++++ src/pages/broadcasts/index.tsx | 254 ++++++++++++++++++++ src/pages/broadcasts/video.css | 233 ++++++++++++++++++ 5 files changed, 1036 insertions(+), 246 deletions(-) create mode 100644 src/pages/broadcasts/details.tsx create mode 100644 src/pages/broadcasts/index.css create mode 100644 src/pages/broadcasts/index.tsx create mode 100644 src/pages/broadcasts/video.css diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 4b8b601f..0548a678 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -11,23 +11,15 @@ const config: Config = { tagline: "Dinosaurs are cool", favicon: "img/favicon.ico", - // Set the production url of your site here url: "https://your-docusaurus-site.example.com", - // Set the // pathname under which your site is served - // For GitHub pages deployment, it is often '//' baseUrl: "/", - // GitHub pages deployment config. - // If you aren't using GitHub pages, you don't need these. - organizationName: "facebook", // Usually your GitHub org/user name. - projectName: "docusaurus", // Usually your repo name. + organizationName: "facebook", + projectName: "docusaurus", onBrokenLinks: "throw", onBrokenMarkdownLinks: "warn", - // Even if you don't use internationalization, you can use this field to set - // useful metadata like html lang. For example, if your site is Chinese, you - // may want to replace "en" with "zh-Hans". i18n: { defaultLocale: "en", locales: ["en"], @@ -38,9 +30,7 @@ const config: Config = { "classic", { docs: { - sidebarPath: "./sidebars.ts", - // Please change this to your repo. - // Remove this to remove the "edit this page" links. + sidebarPath: require.resolve("./sidebars.ts"), editUrl: "https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/", }, @@ -50,24 +40,20 @@ const config: Config = { type: ["rss", "atom"], xslt: true, }, - // Please change this to your repo. - // Remove this to remove the "edit this page" links. editUrl: "https://github.com/facebook/docusaurus/tree/main/packages/create-docusaurus/templates/shared/", - // Useful options to enforce blogging best practices onInlineTags: "warn", onInlineAuthors: "warn", onUntruncatedBlogPosts: "warn", }, theme: { - customCss: "./src/css/custom.css", + customCss: require.resolve("./src/css/custom.css"), }, } satisfies Preset.Options, ], ], themeConfig: { - // Replace with your project's social card image: "img/docusaurus-social-card.jpg", navbar: { title: "Recode Hive", @@ -84,48 +70,42 @@ const config: Config = { { type: "html", value: `
- Tutorials -
- SQL - Python - GitHub - Nextjs - -
-
`, + Tutorials +
+ SQL + Python + GitHub + Nextjs +
+ `, }, - { type: "html", value: '
', }, - { type: "html", value: `
- Courses -
- git - Postman - -
-
`, + Courses +
+ git + Postman +
+ `, }, - { type: "html", value: '
', }, - { type: "html", value: ``, + Interview Prep + + `, }, ], }, @@ -152,7 +132,6 @@ const config: Config = { label: "🎖️ GitHub Badges", to: "/badges/github-badges/", }, - { label: "💾 Portfolio", to: "/roadmap/", @@ -170,6 +149,7 @@ const config: Config = { { to: "/blogs", html: '📰 Blogs', + position: "left", }, { type: "dropdown", @@ -184,7 +164,6 @@ const config: Config = { label: "📚 E-books", to: "#", }, - { label: "🛣️ Roadmap", to: "/roadmap/", @@ -195,12 +174,12 @@ const config: Config = { }, { label: "📺 Broadcast", - to: "https://www.youtube.com/recodehive", + to: "/broadcasts/", }, { label: "🎙️ Podcast", - to: "podcasts/", - }, + to: "/podcasts/", + }, ], }, { @@ -208,230 +187,44 @@ const config: Config = { position: "right", value: '
', }, - // { - // type: "dropdown", - // html: '🏷️ Tags', - // position: "left", - // items: [ - // { - // label: "🏷️ Tutorial Tags 📚", - // to: "/docs/tags/", - // activeBaseRegex: "/docs/tags/", - // }, - // { - // label: "🏷️ Courses Tags 🎓", - // to: "/courses/tags/", - // activeBaseRegex: "/courses/tags/", - // }, - // { - // label: "🏷️ DSA Tags 🧠", - // to: "/dsa/tags/", - // activeBaseRegex: "/dsa/tags/", - // }, - // ], - // }, { type: "search", position: "right", }, - { type: "html", position: "right", value: `
- -
`, + + `, }, - // { - // href: "https://github.com/codeharborhub/codeharborhub", - // position: "right", - // className: "header-github-link", - // "aria-label": "GitHub repository", - // }, - // { - // href: "https://www.codeharborhub.live/register", - // position: "right", - // className: "header-signup-link", - // "aria-label": "Auth", - // label: "Auth", - // }, ], // hideOnScroll: true, }, - // footer: { - // style: "dark", - // links: [ - // { - // title: " ", - // items: [ - // { - // html: ` - // - // `, - // }, - // ], - // }, - // { - // title: "Resources", - // items: [ - // { - // label: "Tutorials", - // to: "/docs", - // }, - // { - // label: "Courses", - // to: "/courses", - // }, - // { - // label: "DSA Problems", - // to: "#", - // }, - // { - // label: "DSA Solutions", - // to: "#", - // }, - // ], - // }, - // { - // title: "Company", - // items: [ - // { - // label: "About", - // to: "/about/", - // }, - // { - // label: "Contact", - // to: "/contact/", - // }, - // { - // label: "Careers", - // to: "/careers/", - // }, - // { - // label: "Team", - // to: "/community/team/", - // }, - // ], - // }, - // { - // title: "Terms/Conditions", - // items: [ - // { - // label: "Privacy Policy", - // to: "/privacy-policy/", - // }, - // { - // label: "Terms of Service", - // to: "/terms-service/", - // }, - // { - // label: "Code of Conduct", - // to: "/code-of-conduct", - // }, - // { - // label: "Cookie Policy", - // to: "/cookie-policy", - // }, - - // { - // label: "License", - // to: "/License/", - // }, - // ], - // }, - // { - // title: "Quick Links", - // items: [ - // { - // label: "Blog", - // to: "/blog", - // }, - // { - // label: "Community", - // to: "/community/", - // }, - // { - // label: "GitHub", - // href: "https://github.com/codeharborhub", - // }, - // ], - // }, - // { - // title: "Social Media", - // items: [ - // { - // label: "LinkedIn", - // href: "https://www.linkedin.com/company/codeharborhub/", - // }, - // { - // label: "YouTube", - // href: "https://www.youtube.com/", - // icon: "faYoutube", - // }, - // { - // label: "Discord", - // href: "https://discord.gg/c53FQn3pRv", - // }, - // { - // label: "Twitter(X)", - // href: "https://twitter.com/CodesWithAjay", - // }, - // ], - // }, - // ], - // logo: { - // alt: "Powered by Recodehive | Product Hunt", - // src: "https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=464236&theme=light", - // href: "https://www.producthunt.com/posts/codeharborhub", - // }, - // copyright: `Copyright © ${new Date().getFullYear()} CodeHarborHub, Made by Sanjay Viswanathan`, - // }, prism: { theme: prismThemes.github, darkTheme: prismThemes.dracula, }, algolia: { - // The application ID provided by Algolia - appId: 'YOUR_APP_ID', - - // Public API key: it is safe to commit it - apiKey: 'YOUR_SEARCH_API_KEY', - - indexName: 'YOUR_INDEX_NAME', - - // Optional: see doc section below + appId: "YOUR_APP_ID", + apiKey: "YOUR_SEARCH_API_KEY", + indexName: "YOUR_INDEX_NAME", contextualSearch: true, - - // Optional: Specify domains where the navigation should occur through window.location instead on history.push. Useful when our Algolia config crawls multiple documentation sites and we want to navigate with window.location.href to them. - externalUrlRegex: 'external\\.com|domain\\.com', - - // Optional: Replace parts of the item URLs from Algolia. Useful when using the same search index for multiple deployments using a different baseUrl. You can use regexp or string in the `from` param. For example: localhost:3000 vs myCompany.com/docs + externalUrlRegex: "external\\.com|domain\\.com", replaceSearchResultPathname: { - from: '/docs/', // or as RegExp: /\/docs\// - to: '/', + from: "/docs/", + to: "/", }, - - // Optional: Algolia search parameters searchParameters: {}, - - // Optional: path for search page that enabled by default (`false` to disable it) - searchPagePath: 'search', - - // Optional: whether the insights feature is enabled or not on Docsearch (`false` by default) + searchPagePath: "search", insights: false, - - //... other Algolia params }, } satisfies Preset.ThemeConfig, markdown: { mermaid: true, }, + themes: ["@docusaurus/theme-mermaid"], plugins: [ @@ -447,7 +240,6 @@ const config: Config = { ], [ "@docusaurus/plugin-content-docs", - /** @type {import('@docusaurus/plugin-content-docs').Options} */ { id: "community", path: "community", diff --git a/src/pages/broadcasts/details.tsx b/src/pages/broadcasts/details.tsx new file mode 100644 index 00000000..c4d96b80 --- /dev/null +++ b/src/pages/broadcasts/details.tsx @@ -0,0 +1,114 @@ +import React, { useState, useEffect } from 'react'; +import Layout from '@theme/Layout'; +import type { ReactElement } from 'react'; +import { useLocation } from '@docusaurus/router'; +import './index.css'; + +interface VideoData { + id: string; + youtubeUrl: string; + type: 'video' | 'shorts'; +} + +interface LocationState { + video: VideoData; +} + +// Function to extract YouTube video ID from URL +const getYoutubeVideoId = (url: string): string => { + let videoId = ''; + const normalMatch = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\s]+)/); + const shortsMatch = url.match(/youtube\.com\/shorts\/([^&\s]+)/); + + if (normalMatch) { + videoId = normalMatch[1]; + } else if (shortsMatch) { + videoId = shortsMatch[1]; + } + return videoId; +}; + +export default function VideoDetails(): ReactElement { + const location = useLocation(); + const state = location.state as LocationState; + const video = state?.video; + const [title, setTitle] = useState('Loading...'); + + useEffect(() => { + const fetchVideoTitle = async () => { + if (!video?.youtubeUrl) return; + + try { + const response = await fetch(`https://www.youtube.com/oembed?url=${encodeURIComponent(video.youtubeUrl)}&format=json`); + const data = await response.json(); + setTitle(data.title); + } catch (error) { + setTitle('Video Title Unavailable'); + console.error('Error fetching video title:', error); + } + }; + + fetchVideoTitle(); + }, [video?.youtubeUrl]); + + // Random descriptive text about videos + const descriptions = [ + "Watch engaging content that inspires and educates.", + "Experience the power of visual storytelling.", + "Join us on a journey of learning through video.", + "Explore new concepts through dynamic video content.", + "Get inspired by expert insights and demonstrations.", + "Discover trending topics and timely tutorials.", + "Learn from the best in the field.", + "Stay updated with the latest trends and techniques.", + "Enhance your skills through visual learning.", + ]; + + // Get a random description + const randomDescription = descriptions[Math.floor(Math.random() * descriptions.length)]; + + if (!video) { + return ( + +
+

Video Not Found

+

Sorry, we couldn't find the video you're looking for.

+
+
+ ); + } + + return ( + +
+
+
+
+
+ {title} +
+
+ {video.type === 'shorts' ? '📱 Shorts' : '🎥 Video'} +
+
+
+

{randomDescription}

+
+
+