v2
This commit is contained in:
parent
a29f901104
commit
f721c4b74c
@ -30,3 +30,22 @@ li.stack-item:not(:last-child):after {
|
|||||||
.main-navbar, .app-sidebar-brand {
|
.main-navbar, .app-sidebar-brand {
|
||||||
box-shadow: 0px -1px 40px rgba(112, 144, 176, 0.2);
|
box-shadow: 0px -1px 40px rgba(112, 144, 176, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes blob {
|
||||||
|
0% { transform: translate(0px, 0px) scale(1); }
|
||||||
|
33% { transform: translate(30px, -50px) scale(1.1); }
|
||||||
|
66% { transform: translate(-20px, 20px) scale(0.9); }
|
||||||
|
100% { transform: translate(0px, 0px) scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-blob {
|
||||||
|
animation: blob 7s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animation-delay-2000 {
|
||||||
|
animation-delay: 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animation-delay-4000 {
|
||||||
|
animation-delay: 4s;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import type { ReactElement } from 'react';
|
import type { ReactElement } from 'react';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
@ -13,11 +13,21 @@ import { fetch as fetchCourses } from '../stores/courses/coursesSlice';
|
|||||||
export default function Starter() {
|
export default function Starter() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { courses, loading } = useAppSelector((state) => state.courses);
|
const { courses, loading } = useAppSelector((state) => state.courses);
|
||||||
|
const [scrollY, setScrollY] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchCourses({ query: '?published=true&limit=6' }));
|
dispatch(fetchCourses({ query: '?published=true&limit=6' }));
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleScroll = () => {
|
||||||
|
setScrollY(window.scrollY);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
return () => window.removeEventListener('scroll', handleScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const title = 'EduFlow LMS';
|
const title = 'EduFlow LMS';
|
||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
@ -46,17 +56,28 @@ export default function Starter() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-slate-50 dark:bg-slate-900 min-h-screen">
|
<div className="bg-slate-50 dark:bg-slate-900 min-h-screen overflow-hidden">
|
||||||
<Head>
|
<Head>
|
||||||
<title>{getPageTitle('Home')}</title>
|
<title>{getPageTitle('Home')}</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<section className="relative overflow-hidden bg-indigo-600 text-white">
|
<section className="relative overflow-hidden bg-indigo-600 text-white">
|
||||||
|
{/* Animated Background Blobs */}
|
||||||
|
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
||||||
|
<div className="absolute top-[-10%] right-[-5%] w-96 h-96 bg-purple-500 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob"></div>
|
||||||
|
<div className="absolute top-[20%] left-[-10%] w-72 h-72 bg-indigo-400 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob animation-delay-2000"></div>
|
||||||
|
<div className="absolute bottom-[-10%] left-[20%] w-80 h-80 bg-pink-500 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob animation-delay-4000"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-10"></div>
|
<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="container mx-auto px-6 py-24 relative z-10">
|
||||||
<div className="flex flex-col lg:flex-row items-center">
|
<div className="flex flex-col lg:flex-row items-center">
|
||||||
<div className="lg:w-1/2 mb-12 lg:mb-0">
|
<div
|
||||||
|
className="lg:w-1/2 mb-12 lg:mb-0"
|
||||||
|
style={{ transform: `translateY(${scrollY * 0.2}px)` }}
|
||||||
|
>
|
||||||
<h1 className="text-5xl lg:text-6xl font-extrabold leading-tight mb-6">
|
<h1 className="text-5xl lg:text-6xl font-extrabold leading-tight mb-6">
|
||||||
Unlock Your Potential with <span className="text-indigo-200">EduFlow</span>
|
Unlock Your Potential with <span className="text-indigo-200">EduFlow</span>
|
||||||
</h1>
|
</h1>
|
||||||
@ -68,39 +89,55 @@ export default function Starter() {
|
|||||||
href="/register"
|
href="/register"
|
||||||
label="Start Learning Now"
|
label="Start Learning Now"
|
||||||
color="white"
|
color="white"
|
||||||
className="px-8 py-3 font-bold rounded-full shadow-lg"
|
className="px-8 py-3 font-bold rounded-full shadow-lg transform transition hover:scale-105"
|
||||||
/>
|
/>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
href="/login"
|
href="/login"
|
||||||
label="Instructor Portal"
|
label="Instructor Portal"
|
||||||
color="info"
|
color="info"
|
||||||
outline
|
outline
|
||||||
className="px-8 py-3 font-bold rounded-full border-2 border-white text-white hover:bg-white hover:text-indigo-600"
|
className="px-8 py-3 font-bold rounded-full border-2 border-white text-white hover:bg-white hover:text-indigo-600 transform transition hover:scale-105"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:w-1/2 relative">
|
<div className="lg:w-1/2 relative perspective-1000">
|
||||||
<div className="bg-gradient-to-tr from-violet-500 to-indigo-500 rounded-2xl shadow-2xl p-4 transform rotate-2">
|
<div
|
||||||
|
className="bg-gradient-to-tr from-violet-500 to-indigo-500 rounded-2xl shadow-2xl p-4 transform rotate-2 transition-transform duration-75"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.1}px) rotate(2deg)` }}
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src="https://images.pexels.com/photos/4050312/pexels-photo-4050312.jpeg?auto=compress&cs=tinysrgb&w=800"
|
src="https://images.pexels.com/photos/4050312/pexels-photo-4050312.jpeg?auto=compress&cs=tinysrgb&w=800"
|
||||||
alt="Learning"
|
alt="Learning"
|
||||||
className="rounded-xl shadow-inner -rotate-2"
|
className="rounded-xl shadow-inner -rotate-2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Floating elements for parallax */}
|
||||||
|
<div
|
||||||
|
className="absolute -top-10 -right-10 w-24 h-24 bg-yellow-400 rounded-full mix-blend-multiply filter blur-xl opacity-70 animate-blob animation-delay-2000"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.2}px)` }}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="absolute -bottom-10 -left-10 w-32 h-32 bg-blue-400 rounded-full mix-blend-multiply filter blur-xl opacity-70 animate-blob"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.15}px)` }}
|
||||||
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* Features Section */}
|
{/* Features Section */}
|
||||||
<section className="py-20 container mx-auto px-6">
|
<section className="py-20 container mx-auto px-6 relative z-10">
|
||||||
<div className="text-center mb-16">
|
<div className="text-center mb-16">
|
||||||
<h2 className="text-3xl font-bold text-slate-800 dark:text-white mb-4">Why Choose EduFlow?</h2>
|
<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 className="w-20 h-1 bg-indigo-500 mx-auto"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-12">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-12">
|
||||||
{features.map((feature, idx) => (
|
{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
|
||||||
|
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 transform transition-transform duration-300 hover:-translate-y-2"
|
||||||
|
>
|
||||||
<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">
|
<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} />
|
<BaseIcon path={feature.icon} size={32} />
|
||||||
</div>
|
</div>
|
||||||
@ -132,7 +169,7 @@ export default function Starter() {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
{courses && courses.length > 0 ? (
|
{courses && courses.length > 0 ? (
|
||||||
courses.map((course: any, idx: number) => (
|
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 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 hover:-translate-y-1 duration-300">
|
||||||
<div className="h-48 relative overflow-hidden">
|
<div className="h-48 relative overflow-hidden">
|
||||||
<Link href={`/course/${course.id}`}>
|
<Link href={`/course/${course.id}`}>
|
||||||
<img
|
<img
|
||||||
@ -231,4 +268,4 @@ export default function Starter() {
|
|||||||
|
|
||||||
Starter.getLayout = function getLayout(page: ReactElement) {
|
Starter.getLayout = function getLayout(page: ReactElement) {
|
||||||
return <LayoutGuest>{page}</LayoutGuest>;
|
return <LayoutGuest>{page}</LayoutGuest>;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user