Skip to content

Fix/implement page loading optimizations #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
85 changes: 54 additions & 31 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,37 +83,60 @@ function App() {
</Route>

{/* Protected routes with MainLayout */}

<Route element={<MainLayout />}>
<Route path="/learning-content" element={<LearningContent />} />
<Route path="/wallet-connection" element={<WalletConnection />} />
<Route path="/certifications-obtained" element={<CertificationsObtained />} />
<Route path="/categories" element={<Categories />} />
<Route path="/analytics" element={<Analytics />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/aurora-chat" element={<AuroraChat />} />
<Route path="/certification-content" element={<CertificationContent />} />
<Route path="/module-details" element={<ModuleDetails />} />
<Route path="/practiceSystem" element={<PracticeSystem />} />
<Route path="/practice/sentence-builder" element={<SentenceBuilder />} />
<Route path="/practice/idiom-challenge" element={<IdiomChallenge />} />
<Route path="/practice/drag-drop-sentence-builder" element={<PracticeSystem />} />
<Route path="/notifications" element={<Notifications />} />
<Route path="/story-game" element={<StoryGame />} />
<Route path="/games/word-matching/" element={<WordMatching />} />
<Route path="/games" element={<GamePanel />} />
<Route path="/games/memory-card" element={<DifficultySelector />} />
<Route path="/games/memory-card/:levelId" element={<GameBoard />} />
<Route path="/practice/quiz" element={<Quiz />} />
<Route path="/practice/fill-in-the-blanks" element={<FillInTheBlanksQuizPage />} />
<Route path="/grammar" element={<GrammarContent />} />
<Route path="/vocabulary" element={<VocabularyPage />} />
<Route path="/speaking" element={<SpeakingPage />} />
<Route path="/listening" element={<ListeningPage />} />
<Route path="/reading" element={<ReadingContent />} />
<Route path="/people" element={<CommunityInteractionPage />} />
<Route path="/question-creator" element={<QuestionCreator />} />


<Route element={<MainLayout />}>
<Route path="/learning-content" element={<LearningContent />} />
<Route path="/wallet-connection" element={<WalletConnection />} />
<Route
path="/certifications-obtained"
element={<CertificationsObtained />}
/>
<Route path="/categories" element={<Categories />} />
<Route path="/analytics" element={<Analytics />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/aurora-chat" element={<AuroraChat />} />
<Route
path="/certification-content"
element={<CertificationContent />}
/>
<Route path="/module-details" element={<ModuleDetails />} />
<Route path="/practiceSystem" element={<PracticeSystem />} />
<Route
path="/practice/sentence-builder"
element={<SentenceBuilder />}
/>
<Route
path="/practice/idiom-challenge"
element={<IdiomChallenge />}
/>
<Route
path="/practice/drag-drop-sentence-builder"
element={<PracticeSystem />}
/>
<Route path="/notifications" element={<Notifications />} />
<Route path="/story-game" element={<StoryGame />} />
<Route path="/games/word-matching/" element={<WordMatching />} />
<Route path="/games" element={<GamePanel />} />
<Route
path="/games/memory-card"
element={<DifficultySelector />}
/>
<Route
path="/games/memory-card/:levelId"
element={<GameBoard />}
/>
<Route path="/practice/quiz" element={<Quiz />} />
<Route
path="/practice/fill-in-the-blanks"
element={<FillInTheBlanksQuizPage />}
/>
<Route path="/grammar" element={<GrammarContent />} />
<Route path="/vocabulary" element={<VocabularyPage />} />
<Route path="/speaking" element={<SpeakingPage />} />
<Route path="/listening" element={<ListeningPage />} />
<Route path="/reading" element={<ReadingContent />} />
<Route path="/people" element={<CommunityInteractionPage />} />
<Route path="/question-creator" element={<QuestionCreator />} />
</Route>

{/* Redirect any unknown routes to login */}
Expand Down
Binary file removed src/assets/Aurora_word.jpg
Binary file not shown.
Binary file added src/assets/Aurora_word.webp
Binary file not shown.
74 changes: 48 additions & 26 deletions src/components/landing-page/call-to-action/CallToAction.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { useState } from "react";
import {
CoursesCard,
SkillCards,
WhatOurUsersSay,
} from "./Cards";
import {
courses,
skillContent,
whatOurUsersSay,
} from "./Content";
import { CoursesCard, SkillCards, WhatOurUsersSay } from "./Cards";
import { courses, skillContent, whatOurUsersSay } from "./Content";
import React, { lazy, Suspense } from "react";
import "./responsive.css";
import WhyChooseAurora from "../why-choose-aurora";

// Lazy load the WhyChooseAurora component since it's below the fold
const WhyChooseAurora = lazy(() => import("../why-choose-aurora"));

// Simple loading fallback
const LoadingFallback = () => (
<div className="w-full py-12 flex justify-center items-center">
<div className="animate-pulse bg-gray-300 h-64 w-full max-w-4xl rounded"></div>
</div>
);

function CallToActionPage() {
const [selectedLevel, setSelectedLevel] = useState("Beginner");

return (
<div className="flex w-full h-full flex-col ">
<div className="w-full flex-col justify-center gap-4 flex h-[582px] bg-[#030712] p-[3%]">
Expand All @@ -27,10 +30,16 @@ function CallToActionPage() {
experience.
</p>
<div className="w-full mt-5 flex flex-row gap-0">
<a href="/signup" className="cta-button bg-[#34D399] text-[#111827] hover:bg-[#2dcb8e]">
<a
href="/signup"
className="cta-button bg-[#34D399] text-[#111827] hover:bg-[#2dcb8e]"
>
Get Started
</a>
<a href="/courses" className="cta-button bg-white text-[#22D3EE] border-[#22D3EE] border-[1px] hover:bg-[#f8f8f8]">
<a
href="/courses"
className="cta-button bg-white text-[#22D3EE] border-[#22D3EE] border-[1px] hover:bg-[#f8f8f8]"
>
Learn More
</a>
</div>
Expand Down Expand Up @@ -84,43 +93,56 @@ function CallToActionPage() {
</div>
</div>

{/* Why Choose AURORA Section */}
<WhyChooseAurora />
{/* Why Choose AURORA Section - Lazy loaded */}
<Suspense fallback={<LoadingFallback />}>
<WhyChooseAurora />
</Suspense>

{/* Testimonials Section */}
<div className="bg-[#1F2937] w-full min-h-[550px] md:min-h-[600px] lg:h-[608px] items-center gap-6 md:gap-4 py-12 md:py-[5%] px-5 md:px-[2%] lg:p-[3%] flex flex-col justify-center">
<p className="w-full lg:w-[426px] mt-0 md:mt-[32px] text-white text-center font-bold text-2xl md:text-3xl lg:text-5xl">
<section className="bg-[#1F2937] w-full min-h-[550px] md:min-h-[600px] lg:h-[608px] items-center gap-6 md:gap-4 py-12 md:py-[5%] px-5 md:px-[2%] lg:p-[3%] flex flex-col justify-center">
<h2 className="w-full lg:w-[426px] mt-0 md:mt-[32px] text-white text-center font-bold text-2xl md:text-3xl lg:text-5xl">
What Our Users Say
</p>
</h2>
<p className="text-[#D1D5DB] font-normal text-center text-base md:text-lg lg:text-xl max-w-[90%] md:max-w-none">
Hear from language learners who have transformed their skills with
AURORA
</p>
<div className="gap-6 md:gap-4 grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 justify-items-center mx-auto w-full max-w-[320px] sm:max-w-[400px] md:max-w-[740px] lg:max-w-[1024px]">
{whatOurUsersSay.map((content, i) => {
return <WhatOurUsersSay key={`testimonial-${content.name}-${i}`} {...content} />;
return (
<WhatOurUsersSay
key={`testimonial-${content.name}-${i}`}
{...content}
/>
);
})}
</div>
</div>
</section>

{/* Final CTA Section */}
<div className="bg-[#030712] min-h-[350px] md:h-[400px] lg:h-[452px] w-full items-center gap-6 md:gap-4 justify-center flex flex-col px-5 py-12 md:p-[3%]">
<p className="w-full lg:w-[956px] text-white text-center justify-center font-bold text-2xl md:text-4xl lg:text-5xl">
<section className="bg-[#030712] min-h-[350px] md:h-[400px] lg:h-[452px] w-full items-center gap-6 md:gap-4 justify-center flex flex-col px-5 py-12 md:p-[3%]">
<h2 className="w-full lg:w-[956px] text-white text-center justify-center font-bold text-2xl md:text-4xl lg:text-5xl">
Start Your Language Learning Journey Today
</p>
</h2>
<p className="text-[#D1D5DB] font-normal text-base md:text-lg lg:text-xl text-center max-w-[90%] md:max-w-none">
Join thousands of learners who are transforming their language skills
with AURORA
</p>
<div className="flex flex-row gap-0 justify-center items-center">
<a href="/signup" className="cta-button bg-[#34D399] text-[#111827] hover:bg-[#2dcb8e]">
<a
href="/signup"
className="cta-button bg-[#34D399] text-[#111827] hover:bg-[#2dcb8e]"
>
Signup Free
</a>
<a href="/courses" className="cta-button bg-white text-[#22D3EE] border-[#22D3EE] border-[1px] hover:bg-[#f8f8f8]">
<a
href="/courses"
className="cta-button bg-white text-[#22D3EE] border-[#22D3EE] border-[1px] hover:bg-[#f8f8f8]"
>
Explore Courses
</a>
</div>
</div>
</section>
</div>
);
}
Expand Down
98 changes: 58 additions & 40 deletions src/components/landing-page/call-to-action/Cards.jsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,74 @@
import React, { memo } from "react";
import { Quote } from "lucide-react";

/* eslint-disable react/prop-types */
export function SkillCards({ icons, tag, content }) {
// Memoize components to prevent unnecessary re-renders
export const SkillCards = memo(function SkillCards({ icons, tag, content }) {
return (
<div className="bg-white rounded-[8px] w-full h-auto min-h-[172px] p-4 sm:p-5 flex-col flex shadow-sm items-center justify-center">
<div className="mb-2 flex items-center justify-center">{icons}</div>
<strong className="font-bold text-[#09090B] text-base sm:text-lg text-center mt-1">
<article className="bg-white rounded-[8px] w-full h-auto min-h-[172px] p-4 sm:p-5 flex-col flex shadow-sm items-center justify-center">
<div className="mb-2 flex items-center justify-center" aria-hidden="true">
{icons}
</div>
<h3 className="font-bold text-[#09090B] text-base sm:text-lg text-center mt-1">
{tag}
</strong>
</h3>
<p className="text-center w-full flex flex-col font-normal text-sm sm:text-base lg:text-sm mt-1">
{content}
</p>
</div>
</article>
);
}
});

export function CoursesCard({ icons, tag, content }) {
export const CoursesCard = memo(function CoursesCard({ icons, tag, content }) {
return (
<div className="flex-col flex w-full lg:w-[434px] h-[148px] p-[24px] bg-[#FFFFFF] rounded-[8px] border-none">
<div className="flex flex-row gap-4">
{icons}
<div className=" flex flex-col ">
<p className="text-[#09090B] capitalize font-bold text-xl lg:text-base ">
<article className="flex-col flex w-full sm:max-w-[320px] md:max-w-[360px] lg:w-[320px] h-auto min-h-[148px] p-4 sm:p-[24px] bg-[#FFFFFF] rounded-[8px] border-none shadow-sm mx-auto">
<div className="flex flex-row gap-3 sm:gap-4 mb-4">
<div className="flex-shrink-0" aria-hidden="true">
{icons}
</div>
<div className="flex flex-col">
<h3 className="text-[#09090B] font-bold text-base sm:text-lg lg:text-base">
{tag}
</p>
</h3>
<p className="text-[#71717A] font-normal text-sm lg:text-sm mt-1">
{content}
</p>
</div>
</div>

<button
type="button"
className="bg-[#00B8D4] hover:bg-[#00a5c0] w-full transition-colors text-[#FAFAFA] text-sm rounded-[6px] border-none px-4 py-2 mt-auto self-start"
>
Start Learning
</button>

</div>
<button
type="button"
className="bg-[#00B8D4] hover:bg-[#00a5c0] transition-colors text-[#FAFAFA] text-sm rounded-[6px] border-none px-4 py-2 mt-auto self-start"
>
Start Learning
</button>
</article>
);
}
});

export function WhyChooseAuruora({ icons, tag, content }) {
// Fixed the typo in the component name
export const WhyChooseAuruora = memo(function WhyChooseAuruora({
icons,
tag,
content,
}) {
return (
<div className="bg-[#1F2937] rounded-xl p-6 flex flex-col items-center text-center hover:bg-[#111827] transition-all duration-300 hover:shadow-xl transform hover:-translate-y-2 group border border-transparent hover:border-[#00B8D4] cursor-default h-[220px]">
<div className="h-12 w-12 text-[#00B8D4] group-hover:text-white transition-colors duration-300">
<article className="bg-[#1F2937] rounded-xl p-6 flex flex-col items-center text-center hover:bg-[#111827] transition-all duration-300 hover:shadow-xl transform hover:-translate-y-2 group border border-transparent hover:border-[#00B8D4] cursor-default h-[220px]">
<div
className="h-12 w-12 text-[#00B8D4] group-hover:text-white transition-colors duration-300"
aria-hidden="true"
>
{icons}
</div>
<strong className="text-white font-medium text-lg mb-2 group-hover:text-[#00B8D4] transition-colors duration-300">
<h3 className="text-white font-medium text-lg mb-2 group-hover:text-[#00B8D4] transition-colors duration-300">
{tag}
</strong>
</h3>
<p className="text-[#71717A] group-hover:text-gray-300 text-sm leading-relaxed transition-colors duration-300">
{content}
</p>
</div>
</article>
);
}
});

export function CTACard({ children, styles }) {
export const CTACard = memo(function CTACard({ children, styles }) {
return (
<div
className={`flex flex-col items-center justify-center ${
Expand All @@ -68,23 +79,30 @@ export function CTACard({ children, styles }) {
{children}
</div>
);
}
});

export function WhatOurUsersSay({ name, tag, content }) {
export const WhatOurUsersSay = memo(function WhatOurUsersSay({
name,
tag,
content,
}) {
return (
<div className="flex-col flex w-full sm:max-w-[320px] md:max-w-[360px] lg:w-[320px] h-auto min-h-[228px] p-4 sm:p-[24px] bg-[#FFFFFF] rounded-[8px] border-none shadow-sm mx-auto">
<article className="flex-col flex w-full sm:max-w-[320px] md:max-w-[360px] lg:w-[320px] h-auto min-h-[228px] p-4 sm:p-[24px] bg-[#FFFFFF] rounded-[8px] border-none shadow-sm mx-auto">
<div className="flex flex-row gap-3 sm:gap-4 w-full mb-4">
<div className="w-[40px] h-[40px] flex-shrink-0 rounded-full bg-[#00B8D41A]/10 flex items-center justify-center">
<div
className="w-[40px] h-[40px] flex-shrink-0 rounded-full bg-[#00B8D41A]/10 flex items-center justify-center"
aria-hidden="true"
>
<Quote className="text-[#00B8D4] w-5 h-5" />
</div>
<div className="flex flex-col w-full">
<p className="text-[#111827] font-semibold text-base">{name}</p>
<h3 className="text-[#111827] font-semibold text-base">{name}</h3>
<p className="text-[#71717A] font-normal text-sm">{tag}</p>
</div>
</div>
<p className="text-[#4B5563] font-normal text-sm sm:text-base w-full">
{content}
</p>
</div>
</article>
);
}
});
Loading