234 lines
11 KiB
TypeScript
234 lines
11 KiB
TypeScript
import React, { useEffect } from 'react';
|
|
import type { ReactElement } from 'react';
|
|
import Head from 'next/head';
|
|
import Link from 'next/link';
|
|
import BaseButton from '../components/BaseButton';
|
|
import LayoutGuest from '../layouts/Guest';
|
|
import { getPageTitle } from '../config';
|
|
import * as icon from '@mdi/js';
|
|
import BaseIcon from '../components/BaseIcon';
|
|
import { useAppDispatch, useAppSelector } from '../stores/hooks';
|
|
import { fetch as fetchCourses } from '../stores/courses/coursesSlice';
|
|
|
|
export default function Starter() {
|
|
const dispatch = useAppDispatch();
|
|
const { courses, loading } = useAppSelector((state) => state.courses);
|
|
|
|
useEffect(() => {
|
|
dispatch(fetchCourses({ query: '?published=true&limit=6' }));
|
|
}, [dispatch]);
|
|
|
|
const title = 'EduFlow LMS';
|
|
|
|
const features = [
|
|
{
|
|
title: 'Expert-Led Courses',
|
|
description: 'Learn from industry professionals with real-world experience.',
|
|
icon: icon.mdiSchool,
|
|
},
|
|
{
|
|
title: 'Flexible Learning',
|
|
description: 'Study at your own pace, anytime and anywhere in the world.',
|
|
icon: icon.mdiClockFast,
|
|
},
|
|
{
|
|
title: 'Progress Tracking',
|
|
description: 'Monitor your growth with detailed analytics and assessments.',
|
|
icon: icon.mdiChartLine,
|
|
},
|
|
];
|
|
|
|
const getThumbnail = (course: any) => {
|
|
if (course.thumbnail && course.thumbnail.length > 0) {
|
|
return `/api/file/download?privateUrl=${course.thumbnail[0].privateUrl}`;
|
|
}
|
|
return 'https://images.pexels.com/photos/1181244/pexels-photo-1181244.jpeg?auto=compress&cs=tinysrgb&w=600';
|
|
};
|
|
|
|
return (
|
|
<div className="bg-slate-50 dark:bg-slate-900 min-h-screen">
|
|
<Head>
|
|
<title>{getPageTitle('Home')}</title>
|
|
</Head>
|
|
|
|
{/* Hero Section */}
|
|
<section className="relative overflow-hidden bg-indigo-600 text-white">
|
|
<div className="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10"></div>
|
|
<div className="container mx-auto px-6 py-24 relative z-10">
|
|
<div className="flex flex-col lg:flex-row items-center">
|
|
<div className="lg:w-1/2 mb-12 lg:mb-0">
|
|
<h1 className="text-5xl lg:text-6xl font-extrabold leading-tight mb-6">
|
|
Unlock Your Potential with <span className="text-indigo-200">EduFlow</span>
|
|
</h1>
|
|
<p className="text-xl text-indigo-100 mb-10 max-w-lg">
|
|
The most intuitive platform for instructors to create and students to excel. Start your journey today.
|
|
</p>
|
|
<div className="flex flex-wrap gap-4">
|
|
<BaseButton
|
|
href="/register"
|
|
label="Start Learning Now"
|
|
color="white"
|
|
className="px-8 py-3 font-bold rounded-full shadow-lg"
|
|
/>
|
|
<BaseButton
|
|
href="/login"
|
|
label="Instructor Portal"
|
|
color="info"
|
|
outline
|
|
className="px-8 py-3 font-bold rounded-full border-2 border-white text-white hover:bg-white hover:text-indigo-600"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="lg:w-1/2 relative">
|
|
<div className="bg-gradient-to-tr from-violet-500 to-indigo-500 rounded-2xl shadow-2xl p-4 transform rotate-2">
|
|
<img
|
|
src="https://images.pexels.com/photos/4050312/pexels-photo-4050312.jpeg?auto=compress&cs=tinysrgb&w=800"
|
|
alt="Learning"
|
|
className="rounded-xl shadow-inner -rotate-2"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Features Section */}
|
|
<section className="py-20 container mx-auto px-6">
|
|
<div className="text-center mb-16">
|
|
<h2 className="text-3xl font-bold text-slate-800 dark:text-white mb-4">Why Choose EduFlow?</h2>
|
|
<div className="w-20 h-1 bg-indigo-500 mx-auto"></div>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-12">
|
|
{features.map((feature, idx) => (
|
|
<div key={idx} className="bg-white dark:bg-slate-800 p-8 rounded-2xl shadow-sm hover:shadow-xl transition-shadow border border-slate-100 dark:border-slate-700 text-center">
|
|
<div className="inline-flex items-center justify-center w-16 h-16 bg-indigo-100 dark:bg-indigo-900 text-indigo-600 dark:text-indigo-300 rounded-full mb-6">
|
|
<BaseIcon path={feature.icon} size={32} />
|
|
</div>
|
|
<h3 className="text-xl font-bold mb-4 text-slate-800 dark:text-white">{feature.title}</h3>
|
|
<p className="text-slate-600 dark:text-slate-400 leading-relaxed">
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Course Catalog Preview */}
|
|
<section className="py-20 bg-slate-100 dark:bg-slate-800/50">
|
|
<div className="container mx-auto px-6">
|
|
<div className="flex justify-between items-end mb-12">
|
|
<div>
|
|
<h2 className="text-3xl font-bold text-slate-800 dark:text-white mb-2">Popular Courses</h2>
|
|
<p className="text-slate-600 dark:text-slate-400">Join thousands of students learning these top-rated skills.</p>
|
|
</div>
|
|
<BaseButton href="/login" label="Browse All" color="info" outline />
|
|
</div>
|
|
|
|
{loading ? (
|
|
<div className="flex justify-center items-center py-20">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600"></div>
|
|
</div>
|
|
) : (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{courses && courses.length > 0 ? (
|
|
courses.map((course: any, idx: number) => (
|
|
<div key={idx} className="bg-white dark:bg-slate-800 rounded-2xl overflow-hidden shadow-md hover:shadow-2xl transition-all group border border-slate-200 dark:border-slate-700">
|
|
<div className="h-48 relative overflow-hidden">
|
|
<Link href={`/course/${course.id}`}>
|
|
<img
|
|
src={getThumbnail(course)}
|
|
alt={course.title}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500 cursor-pointer"
|
|
/>
|
|
</Link>
|
|
{course.category && (
|
|
<div className="absolute top-4 left-4">
|
|
<span className="bg-indigo-600 text-white text-xs font-bold px-3 py-1 rounded-full uppercase tracking-wider">
|
|
{course.category.name}
|
|
</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
<div className="p-6">
|
|
<div className="flex items-center text-xs text-slate-500 mb-2">
|
|
<BaseIcon path={icon.mdiAccountCircle} size={14} className="mr-1" />
|
|
<span>{course.instructor ? `${course.instructor.firstName}${course.instructor.lastName ? " " + course.instructor.lastName : ""}` : 'Instructor'}</span>
|
|
</div>
|
|
<Link href={`/course/${course.id}`}>
|
|
<h3 className="text-xl font-bold mb-4 text-slate-800 dark:text-white group-hover:text-indigo-600 transition-colors cursor-pointer">
|
|
{course.title}
|
|
</h3>
|
|
</Link>
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center text-sm font-medium text-slate-700 dark:text-slate-300">
|
|
<BaseIcon path={icon.mdiSchool} size={16} className="mr-1 text-indigo-500" />
|
|
<span>{course.level}</span>
|
|
</div>
|
|
<div className="text-xl font-black text-indigo-600">
|
|
{course.price ? `$${course.price}` : 'Free'}
|
|
</div>
|
|
</div>
|
|
<BaseButton
|
|
href={`/course/${course.id}`}
|
|
label="View Details"
|
|
color="info"
|
|
className="w-full mt-6 py-3 rounded-xl"
|
|
/>
|
|
</div>
|
|
</div>
|
|
))
|
|
) : (
|
|
<div className="col-span-full text-center py-12 text-slate-500">
|
|
No courses found. Check back later!
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Footer */}
|
|
<footer className="bg-slate-900 text-slate-400 py-12 px-6 border-t border-slate-800">
|
|
<div className="container mx-auto grid grid-cols-1 md:grid-cols-4 gap-12">
|
|
<div className="col-span-1 md:col-span-2">
|
|
<h2 className="text-2xl font-bold text-white mb-6">EduFlow<span className="text-indigo-500">.</span></h2>
|
|
<p className="max-w-sm mb-6 leading-relaxed">
|
|
Empowering the next generation of creators and learners through an accessible, robust, and beautiful LMS experience.
|
|
</p>
|
|
<div className="flex space-x-4">
|
|
<BaseIcon path={icon.mdiTwitter} size={20} className="hover:text-white cursor-pointer" />
|
|
<BaseIcon path={icon.mdiFacebook} size={20} className="hover:text-white cursor-pointer" />
|
|
<BaseIcon path={icon.mdiLinkedin} size={20} className="hover:text-white cursor-pointer" />
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h4 className="text-white font-bold mb-6 uppercase text-sm tracking-widest">Platform</h4>
|
|
<ul className="space-y-4">
|
|
<li><Link href="/login" className="hover:text-white">Browse Courses</Link></li>
|
|
<li><Link href="/register" className="hover:text-white">Become Instructor</Link></li>
|
|
<li><Link href="/login" className="hover:text-white">Mobile App</Link></li>
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<h4 className="text-white font-bold mb-6 uppercase text-sm tracking-widest">Support</h4>
|
|
<ul className="space-y-4">
|
|
<li><Link href="/privacy-policy" className="hover:text-white">Privacy Policy</Link></li>
|
|
<li><Link href="/terms-of-use" className="hover:text-white">Terms of Service</Link></li>
|
|
<li><Link href="#" className="hover:text-white">Help Center</Link></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div className="container mx-auto mt-12 pt-8 border-t border-slate-800 text-sm text-center md:text-left flex flex-col md:flex-row justify-between items-center">
|
|
<p>© 2026 EduFlow LMS. All rights reserved.</p>
|
|
<div className="mt-4 md:mt-0">
|
|
Generated with <span className="text-pink-500">♥</span> by Flatlogic
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
Starter.getLayout = function getLayout(page: ReactElement) {
|
|
return <LayoutGuest>{page}</LayoutGuest>;
|
|
}; |