├── types └── react-slick.d.ts ├── public └── images │ ├── grainy.png │ ├── peepcn.png │ ├── grainy1.jpg │ └── codenexuslogo.png ├── app ├── api │ ├── auth │ │ └── [auth0] │ │ │ └── route.js │ ├── feedback │ │ └── route.ts │ └── courses │ │ └── route.ts ├── profile │ ├── enrolled │ │ └── page.tsx │ ├── dashboard │ │ └── page.tsx │ └── me │ │ └── page.tsx ├── page.tsx ├── feedback │ └── page.tsx ├── trending │ └── page.tsx ├── creator │ └── page.tsx ├── courses │ ├── page.tsx │ └── addCourse │ │ └── page.tsx ├── layout.tsx └── globals.css ├── postcss.config.mjs ├── components ├── ui │ ├── fonts.ts │ ├── skeleton.tsx │ ├── label.tsx │ ├── input.tsx │ ├── separator.tsx │ ├── progress.tsx │ ├── tooltip.tsx │ ├── button.tsx │ ├── card.tsx │ ├── breadcrumb.tsx │ ├── sheet.tsx │ ├── dropdown-menu.tsx │ └── sidebar.tsx ├── common │ ├── navigation │ │ ├── NavbarClient.tsx │ │ ├── BottomBar.tsx │ │ └── HomeBar.tsx │ ├── SideLayout.tsx │ └── HomePage.tsx ├── profile │ └── user │ │ └── userprofile.tsx ├── Trending │ ├── TrendingCarousel.tsx │ └── Trending.tsx ├── Feedback │ └── Feedback.tsx └── courses │ ├── AddCourseForm.tsx │ └── PathCarouselWithCourses.tsx ├── lib ├── utils.ts └── db.ts ├── next.config.ts ├── .eslintrc.json ├── styles └── page.css ├── components.json ├── .gitignore ├── hooks └── use-mobile.tsx ├── tsconfig.json ├── context └── themecontext.tsx ├── package.json ├── tailwind.config.ts └── README.md /types/react-slick.d.ts: -------------------------------------------------------------------------------- 1 | // types/react-slick.d.ts 2 | declare module 'react-slick'; 3 | -------------------------------------------------------------------------------- /public/images/grainy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moiz2405/CODENEXUS/HEAD/public/images/grainy.png -------------------------------------------------------------------------------- /public/images/peepcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moiz2405/CODENEXUS/HEAD/public/images/peepcn.png -------------------------------------------------------------------------------- /public/images/grainy1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moiz2405/CODENEXUS/HEAD/public/images/grainy1.jpg -------------------------------------------------------------------------------- /public/images/codenexuslogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/moiz2405/CODENEXUS/HEAD/public/images/codenexuslogo.png -------------------------------------------------------------------------------- /app/api/auth/[auth0]/route.js: -------------------------------------------------------------------------------- 1 | // app/api/auth/[auth0]/route.js 2 | import { handleAuth } from '@auth0/nextjs-auth0'; 3 | 4 | export const GET = handleAuth(); 5 | -------------------------------------------------------------------------------- /app/profile/enrolled/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const page = () => { 4 | return ( 5 |
page
6 | ) 7 | } 8 | 9 | export default page -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /components/ui/fonts.ts: -------------------------------------------------------------------------------- 1 | import { Bebas_Neue } from 'next/font/google' 2 | 3 | export const bebasNeue = Bebas_Neue({ 4 | weight: '400', 5 | subsets: ['latin'], 6 | display: 'swap', 7 | }) -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /app/profile/dashboard/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Page = () => { 4 | return ( 5 |
page
6 | ); 7 | }; 8 | 9 | export default Page; // Use default export 10 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | 2 | import HomePage from '../components/common/HomePage'; 3 | export default function Home() { 4 | return ( 5 | <> 6 | {/* just checkin */} 7 | 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /app/feedback/page.tsx: -------------------------------------------------------------------------------- 1 | import Feedback from "../../components/Feedback/Feedback"; 2 | 3 | export default function Page() { 4 | return ( 5 |
6 | 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | 3 | const nextConfig: NextConfig = { 4 | images: { 5 | domains: ["lh3.googleusercontent.com,'api/placeholder'"], // Add the Google domain for profile pictures 6 | }, 7 | // other config options 8 | }; 9 | 10 | export default nextConfig; 11 | -------------------------------------------------------------------------------- /app/profile/me/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import UserProfile from '../../../components/profile/user/UserProfile' 3 | import UserProfile from '../../../components/profile/user/userprofile' 4 | const page = () => { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default page -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "../../lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["next/core-web-vitals", "next/typescript"], 3 | "rules": { 4 | "@typescript-eslint/no-unused-expressions": "off", // Disable no-unused-expressions rule 5 | "@typescript-eslint/no-require-imports": "off", // Disable no-require-imports rule 6 | "@typescript-eslint/no-unused-vars": "off" // Disable no-unused-vars rule 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /styles/page.css: -------------------------------------------------------------------------------- 1 | .coming-soon-container { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | justify-content: center; 6 | height: 100vh; 7 | text-align: center; 8 | } 9 | 10 | .coming-soon-title { 11 | font-size: 3rem; 12 | margin-bottom: 1rem; 13 | } 14 | 15 | .coming-soon-description { 16 | font-size: 1.5rem; 17 | color: #666; 18 | } -------------------------------------------------------------------------------- /app/trending/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Trending from '../../components/Trending/Trending' 3 | import TrendingCarousel from '../../components/Trending/TrendingCarousel' 4 | function page() { 5 | return ( 6 | <> 7 |
8 | 9 | 10 |
11 | 12 | ) 13 | } 14 | 15 | export default page -------------------------------------------------------------------------------- /app/creator/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import '../../styles/page.css' 3 | 4 | function Page() { 5 | return ( 6 |
7 |

Coming Soon

8 |

We are working hard to bring you this page. Stay tuned!

9 |
10 | ) 11 | } 12 | 13 | export default Page -------------------------------------------------------------------------------- /app/api/feedback/route.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | 3 | export async function POST(req: Request) { 4 | try { 5 | const body = await req.json(); 6 | const { feedback } = body; 7 | console.log("Feedback received:", feedback); 8 | return NextResponse.json({ success: true }); 9 | } catch (error) { 10 | console.error("Error processing feedback:", error); 11 | return NextResponse.json({ success: false }, { status: 500 }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/courses/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PathCarouselWithCourses from '../../components/courses/PathCarouselWithCourses'; 3 | 4 | const Page = () => { 5 | const paths = ['Full Stack', 'Front End','Back End','DSA','DevOps', 'Web Development','Cyber Security', 'Cloud Computing', 'AI/ML']; // Example paths 6 | 7 | return ( 8 |
9 | 10 |
11 | ); 12 | }; 13 | 14 | export default Page; 15 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | 32 | # env files (can opt-in for committing if needed) 33 | .env* 34 | 35 | # vercel 36 | .vercel 37 | 38 | # typescript 39 | *.tsbuildinfo 40 | next-env.d.ts 41 | -------------------------------------------------------------------------------- /hooks/use-mobile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /app/courses/addCourse/page.tsx: -------------------------------------------------------------------------------- 1 | import { getSession, Session } from '@auth0/nextjs-auth0'; 2 | import AddCourseForm from '../../../components/courses/AddCourseForm'; 3 | 4 | // Define a more specific type for the session object 5 | interface CoursePageProps { 6 | session: Session | null; // Session or null if not authenticated 7 | } 8 | 9 | const CoursePage = async () => { 10 | const session = await getSession(); // Fetch session from Auth0 11 | 12 | // You can now properly type session and check if it's null 13 | if (!session?.user) { 14 | return

You must be logged in to view this page.

; 15 | } 16 | 17 | return ; 18 | }; 19 | 20 | export default CoursePage; 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "noEmit": true, 13 | "esModuleInterop": true, 14 | "module": "ESNext", // Use ES modules 15 | "moduleResolution": "node", // Ensure correct module resolution for Node.js 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "jsx": "preserve", 19 | "incremental": true, 20 | "plugins": [ 21 | { 22 | "name": "next" 23 | } 24 | ] 25 | }, 26 | "include": [ 27 | "next-env.d.ts", 28 | "**/*.ts", 29 | "**/*.tsx", 30 | ".next/types/**/*.ts" 31 | ], 32 | "exclude": [ 33 | "node_modules" 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "../../lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "../../lib/utils" 4 | 5 | const Input = React.forwardRef>( 6 | ({ className, type, ...props }, ref) => { 7 | return ( 8 | 17 | ) 18 | } 19 | ) 20 | Input.displayName = "Input" 21 | 22 | export { Input } 23 | -------------------------------------------------------------------------------- /components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Separator = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >( 12 | ( 13 | { className, orientation = "horizontal", decorative = true, ...props }, 14 | ref 15 | ) => ( 16 | 27 | ) 28 | ) 29 | Separator.displayName = SeparatorPrimitive.Root.displayName 30 | 31 | export { Separator } 32 | -------------------------------------------------------------------------------- /components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /components/common/navigation/NavbarClient.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { usePathname } from "next/navigation"; 4 | import HomeBar from './HomeBar'; 5 | import Bottombar from "./BottomBar"; 6 | import { useTheme } from "../../../context/themecontext"; // Import theme context 7 | import Layout from "../SideLayout"; 8 | const NavbarClient = () => { 9 | const pathname = usePathname(); // Get the current pathname 10 | const { isDarkMode } = useTheme(); // Access dark mode state from context 11 | 12 | // Check if we are on the homepage 13 | const isHomePage = pathname === "/"; 14 | 15 | return ( 16 |
{/* Apply dark mode class */} 17 | {/* Render HomeBar if on the homepage, otherwise PageBar */} 18 | {isHomePage ? : null} 19 | {!isHomePage ? : null} 20 | 21 | {/* Conditionally render Bottombar or SideBar based on the homepage */} 22 | {isHomePage ? : null} 23 |
24 | ); 25 | }; 26 | 27 | export default NavbarClient; 28 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from "next"; 2 | import "./globals.css"; 3 | import NavbarClient from '../components/common/navigation/NavbarClient'; 4 | import { ThemeProvider } from "../context/themecontext"; 5 | import { UserProvider } from "@auth0/nextjs-auth0/client"; 6 | export const metadata = { 7 | title: "CodeNexus", 8 | description: "AI Skill Development Platform Tailored for You", 9 | openGraph: { 10 | title: "CodeNexus", 11 | description: "AI Skill Development Platform Tailored for You", 12 | images: [ 13 | { 14 | url: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/CodeNexus.jpg", // Relative path 15 | width: 800, 16 | height: 600, 17 | alt: "CodeNexus AI Skill Development", 18 | }, 19 | ], 20 | }, 21 | metadataBase: new URL("https://code-nexus-delta.vercel.app/"), // Replace with your deployed URL 22 | }; 23 | 24 | export default function RootLayout({ 25 | children, 26 | }: Readonly<{ children: React.ReactNode }>) { 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | {children} 34 | 35 | 36 | 37 | 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /components/ui/tooltip.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as TooltipPrimitive from "@radix-ui/react-tooltip" 5 | 6 | import { cn } from "../../lib/utils" 7 | 8 | const TooltipProvider = TooltipPrimitive.Provider 9 | 10 | const Tooltip = TooltipPrimitive.Root 11 | 12 | const TooltipTrigger = TooltipPrimitive.Trigger 13 | 14 | const TooltipContent = React.forwardRef< 15 | React.ElementRef, 16 | React.ComponentPropsWithoutRef 17 | >(({ className, sideOffset = 4, ...props }, ref) => ( 18 | 19 | 28 | 29 | )) 30 | TooltipContent.displayName = TooltipPrimitive.Content.displayName 31 | 32 | export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } 33 | -------------------------------------------------------------------------------- /lib/db.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from '@supabase/supabase-js'; 2 | 3 | const supabaseUrl = process.env.SUPABASE_URL || ''; // Add your Supabase URL in environment variable 4 | const supabaseKey = process.env.SUPABASE_KEY || ''; // Add your Supabase anon/public key 5 | 6 | // Create a supabase client 7 | const supabase = createClient(supabaseUrl, supabaseKey); 8 | 9 | // Function to fetch data from the 'courses' table 10 | export async function fetchCourses(path?: string) { 11 | try { 12 | const { data, error } = await supabase 13 | .from('courses') 14 | .select('*') 15 | .eq(path ? 'path' : '', path) 16 | .order('id', { ascending: true }); // Adjust your sorting or filtering based on requirements 17 | 18 | if (error) throw error; 19 | return data; 20 | } catch (error) { 21 | console.error('Error fetching courses:', error); 22 | throw new Error('Failed to fetch courses'); 23 | } 24 | } 25 | 26 | // Function to insert a new course 27 | export async function insertCourse(course: { 28 | title: string; 29 | videoUrl: string; 30 | thumbnailurl?: string; 31 | path: string; 32 | description?: string; 33 | }) { 34 | try { 35 | const { data, error } = await supabase.from('courses').insert([course]); 36 | 37 | if (error) throw error; 38 | return data; 39 | } catch (error) { 40 | console.error('Error inserting course:', error); 41 | throw new Error('Failed to insert course'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /context/themecontext.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React, { createContext, useState, useContext, ReactNode, useEffect } from "react"; 3 | 4 | // Define the shape of the context state 5 | interface ThemeContextType { 6 | isDarkMode: boolean; 7 | toggleDarkMode: () => void; 8 | } 9 | 10 | // Create a context with default values 11 | const ThemeContext = createContext(undefined); 12 | 13 | export const ThemeProvider: React.FC<{ children: ReactNode }> = ({ children }) => { 14 | const [isDarkMode, setIsDarkMode] = useState(false); 15 | 16 | // On mount, check if a theme is stored in localStorage 17 | useEffect(() => { 18 | const savedTheme = localStorage.getItem("theme"); 19 | if (savedTheme) { 20 | setIsDarkMode(savedTheme === "dark"); 21 | } 22 | }, []); 23 | 24 | // Update the class on the or tag when theme changes 25 | useEffect(() => { 26 | if (isDarkMode) { 27 | document.body.classList.add("dark"); 28 | } else { 29 | document.body.classList.remove("dark"); 30 | } 31 | }, [isDarkMode]); 32 | 33 | // Toggle dark mode and update localStorage 34 | const toggleDarkMode = () => { 35 | setIsDarkMode((prevMode) => { 36 | const newMode = !prevMode; 37 | localStorage.setItem("theme", newMode ? "dark" : "light"); 38 | return newMode; 39 | }); 40 | }; 41 | 42 | return ( 43 | 44 | {children} 45 | 46 | ); 47 | }; 48 | 49 | // Custom hook to access theme context 50 | export const useTheme = () => { 51 | const context = useContext(ThemeContext); 52 | if (!context) { 53 | throw new Error("useTheme must be used within a ThemeProvider"); 54 | } 55 | return context; 56 | }; 57 | -------------------------------------------------------------------------------- /app/api/courses/route.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | import { fetchCourses, insertCourse } from "../../../lib/db"; 3 | 4 | // Handle GET requests (fetch courses) 5 | export async function GET(req: NextRequest) { 6 | const url = new URL(req.url); 7 | const path = url.searchParams.get("path"); 8 | 9 | try { 10 | const path = url.searchParams.get("path") || ""; 11 | const courses = await fetchCourses(path); // Use the new fetchCourses function 12 | return NextResponse.json(courses, { status: 200 }); 13 | } catch (error) { 14 | console.error("Error fetching courses:", error); 15 | return NextResponse.json( 16 | { error: "Failed to fetch courses" }, 17 | { status: 500 } 18 | ); 19 | } 20 | } 21 | 22 | // Handle POST requests (add a new course) 23 | export async function POST(req: NextRequest) { 24 | const { title, videoUrl, thumbnailUrl, path, description } = await req.json(); 25 | 26 | if (!title || !videoUrl || !path) { 27 | return NextResponse.json( 28 | { error: "Title, Video URL, and Path are required" }, 29 | { status: 400 } 30 | ); 31 | } 32 | 33 | try { 34 | const course = { 35 | title, 36 | videoUrl, 37 | thumbnailUrl: thumbnailUrl || "/api/placeholder/400/300", // Provide a default placeholder 38 | path, 39 | description: description || null, 40 | }; 41 | 42 | const result = await insertCourse(course); // Use the new insertCourse function 43 | return NextResponse.json( 44 | { message: "Course added successfully", course: result }, 45 | { status: 201 } 46 | ); 47 | } catch (error) { 48 | console.error("Error adding course:", error); 49 | return NextResponse.json( 50 | { error: "Failed to add course" }, 51 | { status: 500 } 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /components/profile/user/userprofile.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React from 'react'; 3 | import { useUser } from '@auth0/nextjs-auth0/client'; 4 | import Image from 'next/image'; 5 | import { useRouter } from 'next/navigation'; 6 | 7 | function UserProfile() { 8 | const { user, error, isLoading } = useUser(); 9 | const router = useRouter(); 10 | 11 | const handleLogout = () => { 12 | // Use the Auth0 logout API to log the user out 13 | window.location.href = '/api/auth/logout'; 14 | }; 15 | 16 | if (isLoading) { 17 | return
Loading...
; 18 | } 19 | 20 | if (error) { 21 | return
Error: {error.message}
; 22 | } 23 | 24 | if (!user) { 25 | return
You are not logged in.
; 26 | } 27 | 28 | return ( 29 |
30 |
31 |
32 |
33 | {/* Display user's Google ID logo */} 34 | {user.picture ? ( 35 | Profile Picture 42 | ) : ( 43 |
44 | {user.name?.[0]} 45 |
46 | )} 47 |
48 |
49 |

{user.name}

50 |

{user.email}

51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 | ); 59 | } 60 | 61 | export default UserProfile; 62 | -------------------------------------------------------------------------------- /components/common/navigation/BottomBar.tsx: -------------------------------------------------------------------------------- 1 | // Sidebar.tsx 2 | "use client"; 3 | import React, { useState } from "react"; 4 | import Link from "next/link"; 5 | import { 6 | FaHome, 7 | FaBook, 8 | FaChartBar, 9 | FaStore, 10 | FaFileAlt, 11 | FaUserPlus, 12 | } from "react-icons/fa"; 13 | 14 | const Bottombar: React.FC = () => { 15 | const [hovered, setHovered] = useState(null); 16 | 17 | const sidebarItems = [ 18 | { name: "Home", icon: , link: "/" }, 19 | { name: "Courses", icon: , link: "/courses" }, 20 | { name: "Trending", icon: , link: "/trending" }, 21 | { name: "Store", icon: , link: "/store" }, 22 | { name: "Resume", icon: , link: "/resume" }, 23 | { name: "Creator Access", icon: , link: "/creator-access" }, 24 | ]; 25 | 26 | return ( 27 |
29 | {sidebarItems.map((item) => ( 30 |
setHovered(item.name)} 34 | onMouseLeave={() => setHovered(null)} 35 | > 36 | 37 |
38 |
{item.icon}
39 |
40 | 41 | {hovered === item.name && ( 42 |
44 | {item.name} 45 |
46 | )} 47 |
48 | ))} 49 |
50 | ); 51 | }; 52 | 53 | export default Bottombar; 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codenexus", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@auth0/nextjs-auth0": "^3.5.0", 13 | "@radix-ui/react-dialog": "^1.1.2", 14 | "@radix-ui/react-dropdown-menu": "^2.1.2", 15 | "@radix-ui/react-label": "^2.1.0", 16 | "@radix-ui/react-progress": "^1.1.0", 17 | "@radix-ui/react-separator": "^1.1.0", 18 | "@radix-ui/react-slot": "^1.1.0", 19 | "@radix-ui/react-tooltip": "^1.1.4", 20 | "@supabase/supabase-js": "^2.47.10", 21 | "@tailwindcss/forms": "^0.5.9", 22 | "class-variance-authority": "^0.7.0", 23 | "classnames": "^2.5.1", 24 | "clsx": "^2.1.1", 25 | "lucide-react": "^0.460.0", 26 | "next": "^15.0.3", 27 | "react": "19.0.0-rc-66855b96-20241106", 28 | "react-dom": "19.0.0-rc-66855b96-20241106", 29 | "react-icons": "^5.3.0", 30 | "react-router-dom": "^7.0.1", 31 | "react-slick": "^0.30.3", 32 | "shadcn-ui": "^0.9.3", 33 | "slick-carousel": "^1.8.1", 34 | "sqlite": "^5.1.1", 35 | "sqlite3": "^5.1.7", 36 | "swiper": "^11.1.15", 37 | "tailwind-merge": "^2.5.4", 38 | "tailwindcss-animate": "^1.0.7" 39 | }, 40 | "devDependencies": { 41 | "@types/node": "^20", 42 | "@types/react": "^18", 43 | "@types/react-dom": "^18", 44 | "@types/react-icons": "^2.2.7", 45 | "eslint": "^8", 46 | "eslint-config-next": "15.0.3", 47 | "postcss": "^8", 48 | "tailwindcss": "^3.4.1", 49 | "ts-node": "^10.9.2", 50 | "typescript": "^5.7.2" 51 | }, 52 | "description": "This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).", 53 | "main": "index.js", 54 | "directories": { 55 | "lib": "lib" 56 | }, 57 | "author": "", 58 | "license": "ISC" 59 | } 60 | -------------------------------------------------------------------------------- /components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "../../lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", 9 | { 10 | variants: { 11 | variant: { 12 | default: 13 | "bg-primary text-primary-foreground shadow hover:bg-primary/90", 14 | destructive: 15 | "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", 16 | outline: 17 | "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", 18 | secondary: 19 | "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", 20 | ghost: "hover:bg-accent hover:text-accent-foreground", 21 | link: "text-primary underline-offset-4 hover:underline", 22 | }, 23 | size: { 24 | default: "h-9 px-4 py-2", 25 | sm: "h-8 rounded-md px-3 text-xs", 26 | lg: "h-10 rounded-md px-8", 27 | icon: "h-9 w-9", 28 | }, 29 | }, 30 | defaultVariants: { 31 | variant: "default", 32 | size: "default", 33 | }, 34 | } 35 | ) 36 | 37 | export interface ButtonProps 38 | extends React.ButtonHTMLAttributes, 39 | VariantProps { 40 | asChild?: boolean 41 | } 42 | 43 | const Button = React.forwardRef( 44 | ({ className, variant, size, asChild = false, ...props }, ref) => { 45 | const Comp = asChild ? Slot : "button" 46 | return ( 47 | 52 | ) 53 | } 54 | ) 55 | Button.displayName = "Button" 56 | 57 | export { Button, buttonVariants } 58 | -------------------------------------------------------------------------------- /components/ui/card.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "../../lib/utils" 4 | 5 | const Card = React.forwardRef< 6 | HTMLDivElement, 7 | React.HTMLAttributes 8 | >(({ className, ...props }, ref) => ( 9 |
17 | )) 18 | Card.displayName = "Card" 19 | 20 | const CardHeader = React.forwardRef< 21 | HTMLDivElement, 22 | React.HTMLAttributes 23 | >(({ className, ...props }, ref) => ( 24 |
29 | )) 30 | CardHeader.displayName = "CardHeader" 31 | 32 | const CardTitle = React.forwardRef< 33 | HTMLDivElement, 34 | React.HTMLAttributes 35 | >(({ className, ...props }, ref) => ( 36 |
41 | )) 42 | CardTitle.displayName = "CardTitle" 43 | 44 | const CardDescription = React.forwardRef< 45 | HTMLDivElement, 46 | React.HTMLAttributes 47 | >(({ className, ...props }, ref) => ( 48 |
53 | )) 54 | CardDescription.displayName = "CardDescription" 55 | 56 | const CardContent = React.forwardRef< 57 | HTMLDivElement, 58 | React.HTMLAttributes 59 | >(({ className, ...props }, ref) => ( 60 |
61 | )) 62 | CardContent.displayName = "CardContent" 63 | 64 | const CardFooter = React.forwardRef< 65 | HTMLDivElement, 66 | React.HTMLAttributes 67 | >(({ className, ...props }, ref) => ( 68 |
73 | )) 74 | CardFooter.displayName = "CardFooter" 75 | 76 | export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } 77 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "tailwindcss"; 2 | import tailwindcssAnimate from "tailwindcss-animate"; 3 | import forms from "@tailwindcss/forms"; 4 | 5 | export default { 6 | darkMode: ["class"], 7 | content: [ 8 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 9 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 10 | "./app/**/*.{js,ts,jsx,tsx,mdx}", 11 | ], 12 | theme: { 13 | extend: { 14 | colors: { 15 | background: "hsl(var(--background))", 16 | foreground: "hsl(var(--foreground))", 17 | card: { 18 | DEFAULT: "hsl(var(--card))", 19 | foreground: "hsl(var(--card-foreground))", 20 | }, 21 | popover: { 22 | DEFAULT: "hsl(var(--popover))", 23 | foreground: "hsl(var(--popover-foreground))", 24 | }, 25 | primary: { 26 | DEFAULT: "hsl(var(--primary))", 27 | foreground: "hsl(var(--primary-foreground))", 28 | }, 29 | secondary: { 30 | DEFAULT: "hsl(var(--secondary))", 31 | foreground: "hsl(var(--secondary-foreground))", 32 | }, 33 | muted: { 34 | DEFAULT: "hsl(var(--muted))", 35 | foreground: "hsl(var(--muted-foreground))", 36 | }, 37 | accent: { 38 | DEFAULT: "hsl(var(--accent))", 39 | foreground: "hsl(var(--accent-foreground))", 40 | }, 41 | destructive: { 42 | DEFAULT: "hsl(var(--destructive))", 43 | foreground: "hsl(var(--destructive-foreground))", 44 | }, 45 | border: "hsl(var(--border))", 46 | input: "hsl(var(--input))", 47 | ring: "hsl(var(--ring))", 48 | chart: { 49 | "1": "hsl(var(--chart-1))", 50 | "2": "hsl(var(--chart-2))", 51 | "3": "hsl(var(--chart-3))", 52 | "4": "hsl(var(--chart-4))", 53 | "5": "hsl(var(--chart-5))", 54 | }, 55 | sidebar: { 56 | DEFAULT: "hsl(var(--sidebar-background))", 57 | foreground: "hsl(var(--sidebar-foreground))", 58 | primary: "hsl(var(--sidebar-primary))", 59 | "primary-foreground": "hsl(var(--sidebar-primary-foreground))", 60 | accent: "hsl(var(--sidebar-accent))", 61 | "accent-foreground": "hsl(var(--sidebar-accent-foreground))", 62 | border: "hsl(var(--sidebar-border))", 63 | ring: "hsl(var(--sidebar-ring))", 64 | }, 65 | }, 66 | borderRadius: { 67 | lg: "var(--radius)", 68 | md: "calc(var(--radius) - 2px)", 69 | sm: "calc(var(--radius) - 4px)", 70 | }, 71 | animation: { 72 | fadeIn: "fadeIn 0.5s ease-in-out", 73 | }, 74 | keyframes: { 75 | fadeIn: { 76 | "0%": { opacity: "0" }, 77 | "100%": { opacity: "1" }, 78 | }, 79 | }, 80 | }, 81 | }, 82 | plugins: [ 83 | tailwindcssAnimate, 84 | forms, // Adds better form styles 85 | ], 86 | } satisfies Config; 87 | -------------------------------------------------------------------------------- /components/Trending/TrendingCarousel.tsx: -------------------------------------------------------------------------------- 1 | // components/courses/TrendingCarousel.tsx 2 | "use client"; 3 | 4 | import React from "react"; 5 | import Slider from "react-slick"; // Make sure to import Slider 6 | import Image from "next/image"; 7 | import "slick-carousel/slick/slick.css"; // Add these imports for slick-carousel styles 8 | import "slick-carousel/slick/slick-theme.css"; // Add slick-theme for the carousel styles 9 | 10 | interface Course { 11 | id: string; 12 | title: string; 13 | thumbnailUrl: string; 14 | } 15 | 16 | const TrendingCarousel: React.FC = () => { 17 | // Static courses data 18 | const courses: Course[] = [ 19 | { 20 | id: "1", 21 | title: "React for Beginners", 22 | thumbnailUrl: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/frontend/3.jpg", 23 | }, 24 | { 25 | id: "2", 26 | title: "Advanced JavaScript", 27 | thumbnailUrl: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/fullstack/2.jpg", 28 | }, 29 | { 30 | id: "3", 31 | title: "Node.js Mastery", 32 | thumbnailUrl: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/dsa/2.jpg", 33 | }, 34 | { 35 | id: "4", 36 | title: "CSS Flexbox Essentials", 37 | thumbnailUrl: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/devops/2.jpg", 38 | }, 39 | { 40 | id: "5", 41 | title: "TypeScript Deep Dive", 42 | thumbnailUrl: "https://raw.githubusercontent.com/moiz2405/codenexus-thumbnails/refs/heads/main/backend/3.jpg", 43 | }, 44 | ]; 45 | 46 | const settings = { 47 | dots: true, // Show navigation dots 48 | infinite: true, 49 | speed: 500, 50 | slidesToShow: 1, // Show 1 slide at a time on small screens 51 | slidesToScroll: 1, 52 | autoplay: true, // Enable autoplay 53 | autoplaySpeed: 3000, // Time in milliseconds before auto-scrolling to the next slide (3 seconds) 54 | responsive: [ 55 | { 56 | breakpoint: 640, 57 | settings: { 58 | slidesToShow: 2, // Show 2 slides at a time on medium screens 59 | }, 60 | }, 61 | { 62 | breakpoint: 1024, 63 | settings: { 64 | slidesToShow: 3, // Show 3 slides at a time on large screens 65 | }, 66 | }, 67 | ], 68 | }; 69 | 70 | return ( 71 | 72 | {courses.map((course) => ( 73 |
74 | {course.title} 82 | 83 | 84 |
85 | ))} 86 |
87 | ); 88 | }; 89 | 90 | export default TrendingCarousel; 91 | -------------------------------------------------------------------------------- /components/common/navigation/HomeBar.tsx: -------------------------------------------------------------------------------- 1 | import Link from "next/link"; 2 | import { ArrowRight } from "lucide-react"; 3 | import { bebasNeue } from "../../ui/fonts"; 4 | import { FaSun, FaMoon } from "react-icons/fa"; 5 | import { useTheme } from "../../../context/themecontext"; 6 | 7 | interface NavLinkProps { 8 | href: string; 9 | children: React.ReactNode; 10 | } 11 | 12 | const NavLink: React.FC = ({ href, children }) => ( 13 | 17 | {children} 18 | 19 | ); 20 | 21 | export default function HomeBar() { 22 | const { isDarkMode, toggleDarkMode } = useTheme(); 23 | const navItems = [ 24 | "Home", 25 | "Creator Access", 26 | "Reviews", 27 | "Community", 28 | "Alumni", 29 | "About Us", 30 | ]; 31 | 32 | return ( 33 | 90 | ); 91 | } 92 | -------------------------------------------------------------------------------- /components/ui/breadcrumb.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { ChevronRight, MoreHorizontal } from "lucide-react" 4 | 5 | import { cn } from "../../lib/utils" 6 | 7 | const Breadcrumb = React.forwardRef< 8 | HTMLElement, 9 | React.ComponentPropsWithoutRef<"nav"> & { 10 | separator?: React.ReactNode 11 | } 12 | >(({ ...props }, ref) =>