From f41f52cfdf682c67f2621b8f0aafc2eb41b4656b Mon Sep 17 00:00:00 2001 From: Sangeeta Kundu Date: Sat, 23 Aug 2025 15:48:58 +0530 Subject: [PATCH] Added ThemeToggle and dark mode to Home page --- client/src/Pages/Community.jsx | 24 +- client/src/Pages/Contact.jsx | 33 +- client/src/Pages/Home.jsx | 95 +- client/src/Pages/LandingPage.jsx | 501 +- client/src/Pages/ProfilePage.jsx | 195 +- client/src/Pages/ScanPage.jsx | 45 +- client/src/Pages/Tutorial.jsx | 300 +- client/src/Pages/TutorialsPage.jsx | 67 +- client/src/components/AIDamageDetection.jsx | 35 +- client/src/components/AIResponseSection.jsx | 8 +- client/src/components/FAQAccordion.jsx | 14 +- client/src/components/FluidCursor.jsx | 7 +- client/src/components/Footer.jsx | 55 +- client/src/components/HomeFAQ.jsx | 16 +- client/src/components/NavBar.jsx | 255 +- client/src/components/ProtectedRoute.jsx | 4 +- client/src/components/ScrollTop.jsx | 6 +- client/src/components/ThemeToggle.jsx | 23 + client/src/components/Tour.jsx | 60 +- client/src/context/ThemeContext.jsx | 30 + client/src/main.jsx | 9 +- client/tailwind.config.js | 4 +- package-lock.json | 15927 +++++++++++++++++- server/.env | 3 +- 24 files changed, 16956 insertions(+), 760 deletions(-) create mode 100644 client/src/components/ThemeToggle.jsx create mode 100644 client/src/context/ThemeContext.jsx diff --git a/client/src/Pages/Community.jsx b/client/src/Pages/Community.jsx index 1973eaa..b62cfb4 100644 --- a/client/src/Pages/Community.jsx +++ b/client/src/Pages/Community.jsx @@ -32,15 +32,15 @@ const Community = () => { ]; return ( -
+
{/* Hero Section */}

- Join the Community + Join the Community

-

+

Connect with fellow DIY repair enthusiasts. Share tips, ask questions, and learn together in our vibrant community of tinkerers and technicians.

@@ -52,29 +52,29 @@ const Community = () => { {features.map((feature, i) => (
-
+
{feature.icon}
-

+

{feature.title}

-

{feature.desc}

+

{feature.desc}

))}
{/* CTA */} -
-

Ready to Connect?

-

+

+

Ready to Connect?

+

Join our community today and start sharing your repair journey with others.

-
@@ -82,4 +82,4 @@ const Community = () => { ); }; -export default Community; \ No newline at end of file +export default Community; diff --git a/client/src/Pages/Contact.jsx b/client/src/Pages/Contact.jsx index 093e94d..2751910 100644 --- a/client/src/Pages/Contact.jsx +++ b/client/src/Pages/Contact.jsx @@ -1,4 +1,3 @@ - import React, { useEffect, useState } from 'react'; import Navbar from '../components/NavBar'; import AOS from 'aos'; @@ -33,15 +32,15 @@ const Contact = () => { }; return ( -
+
{/* Hero Section */}

- Contact Us + Contact Us

-

+

Have questions or feedback? We'd love to hear from you. Reach out and we'll get back to you as soon as possible.

@@ -49,7 +48,7 @@ const Contact = () => { {/* Contact Form */}
-
+
{ placeholder="Your Name" value={formData.name} onChange={handleChange} - className="w-full px-4 py-3 bg-[#1E293B] text-white rounded-lg border border-gray-600 focus:border-[#38BDF8] focus:outline-none transition" + className="w-full px-4 py-3 bg-[#1E293B] dark:bg-gray-700 text-white dark:text-gray-200 rounded-lg border border-gray-600 dark:border-gray-500 focus:border-[#38BDF8] dark:focus:border-cyan-400 focus:outline-none transition" required />
@@ -69,7 +68,7 @@ const Contact = () => { placeholder="Your Email" value={formData.email} onChange={handleChange} - className="w-full px-4 py-3 bg-[#1E293B] text-white rounded-lg border border-gray-600 focus:border-[#38BDF8] focus:outline-none transition" + className="w-full px-4 py-3 bg-[#1E293B] dark:bg-gray-700 text-white dark:text-gray-200 rounded-lg border border-gray-600 dark:border-gray-500 focus:border-[#38BDF8] dark:focus:border-cyan-400 focus:outline-none transition" required />
@@ -80,13 +79,13 @@ const Contact = () => { rows="6" value={formData.message} onChange={handleChange} - className="w-full px-4 py-3 bg-[#1E293B] text-white rounded-lg border border-gray-600 focus:border-[#38BDF8] focus:outline-none transition resize-none" + className="w-full px-4 py-3 bg-[#1E293B] dark:bg-gray-700 text-white dark:text-gray-200 rounded-lg border border-gray-600 dark:border-gray-500 focus:border-[#38BDF8] dark:focus:border-cyan-400 focus:outline-none transition resize-none" required >
@@ -96,22 +95,22 @@ const Contact = () => { {/* Contact Info */}
-
+
- - support@refixly.com + + support@refixly.com
-

+

We typically respond within 24 hours

@@ -121,4 +120,4 @@ const Contact = () => { ); }; -export default Contact; \ No newline at end of file +export default Contact; diff --git a/client/src/Pages/Home.jsx b/client/src/Pages/Home.jsx index b90fdbd..f93a2a3 100644 --- a/client/src/Pages/Home.jsx +++ b/client/src/Pages/Home.jsx @@ -56,7 +56,7 @@ const UserHome = () => { } return ( -
+
{/* Hero Section */} @@ -71,16 +71,16 @@ const UserHome = () => { backgroundRepeat: 'no-repeat', }} > -
+

- Own and Repair Smart + Own and Repair Smart

-

+

Refixly is your AI-powered DIY assistant. Scan, Learn, and Repair—all from your pocket.

{/* Features */} -
+
-

- Powerful Features +

+ Powerful Features

-

+

Discover how Refixly makes device repair simple, smart, and accessible for everyone.

@@ -102,18 +102,18 @@ const UserHome = () => { {features.map((f, i) => (
handleNagivaion(f.title)} > -
+
{f.icon}
-

+

{f.title}

-

+

{f.desc}

@@ -121,25 +121,26 @@ const UserHome = () => {
- {/*About*/} + {/* About */}
-

About Refixly

-

+

About Refixly

+

Refixly empowers everyday users with the tools and guidance to fix their own devices—no technician needed. Our blend of AI, AR, and community knowledge makes repair smart, simple, and sustainable. Whether you're fixing a phone, tablet, or laptop, we provide all the support you need—step-by-step and stress-free.

+ {/* Smart Diagnostics */}
-

Smart Diagnostics

-

+

Smart Diagnostics

+

Our AI-powered diagnostics system can detect common device issues just by asking you a few questions or analyzing device behavior. No more searching endless forums—get a fast, intelligent diagnosis.

-

+

This feature is designed to assist both beginners and experienced users in identifying exact faults in their devices without trial and error.

@@ -148,29 +149,31 @@ const UserHome = () => {
+ {/* AR Assistance */}
AR Assistance
-

Augmented Reality Assistance

-

+

Augmented Reality Assistance

+

Use our AR-guided instructions to repair devices with confidence. Point your camera and see real-time overlays guiding you where to tap, unscrew, or replace components.

-

+

Perfect for visual learners and first-time repairers, our AR makes complex tasks feel like a breeze.

+ {/* Eco-Friendly Repairs */}
-

Eco-Friendly Repairs

-

+

Eco-Friendly Repairs

+

Refixly encourages users to repair rather than replace. Each repair helps reduce the growing pile of e-waste and lowers your carbon footprint.

-

+

By extending the lifespan of your electronics, you’re contributing to a more sustainable planet—and saving money too.

@@ -179,30 +182,32 @@ const UserHome = () => {
+ {/* Community-Driven Solutions */}
Community
-

Community-Driven Solutions

-

+

Community-Driven Solutions

+

Join a vibrant community of tinkerers, technicians, and learners. Share repair tips, ask for advice, or explore crowd-sourced solutions from people who’ve fixed the same issue you’re facing.

-

+

Our forums and repair logs make it easy to connect, learn, and grow your skills alongside others.

+ {/* One-Stop Repair Toolkit */}
-

One-Stop Repair Toolkit

-

+

One-Stop Repair Toolkit

+

Everything you need in one place: step-by-step repair guides, video walkthroughs, tool recommendations, and where to buy parts. Stop wasting time looking in multiple places—we’ve got it all in one dashboard.

-

+

Our toolkit is user-friendly, constantly updated, and adaptable to new devices and technologies.

@@ -213,12 +218,12 @@ const UserHome = () => {
{/* Steps */} -
+
-

- How It Works +

+ How It Works

-

+

Get started with Refixly in just a few simple steps. Our intuitive process makes device repair accessible to everyone.

@@ -226,18 +231,18 @@ const UserHome = () => { {steps.map((s, i) => (
-
+
{s.icon}
-

+

{s.title}

-

+

{s.desc}

@@ -247,19 +252,19 @@ const UserHome = () => {
{/* FAQ */} -
- +
+
{/* CTA */} -
+
-

Ready to start fixing smarter?

-

+

Ready to start fixing smarter?

+

Join thousands of users who trust Refixly to guide their DIY repair journeys.

+ + - -
- - - {/* Hero Section */} -
-
-
-
- - AI-Powered Repair Assistant -
-

- Repair with -
- Confidence -

-

- Your AI-powered DIY repair assistant. Scan, diagnose, and fix with step-by-step guidance. -

-
- - - - -
-
-
- Repair -
-
-
- - {/* Stats Section */} -
-
- {stats.map((stat, index) => ( -
-
-
{stat.number}
-
{stat.label}
-
-
- ))} -
-
+ {/* Theme Toggle Button */} +
+ +
+ +
+ + + {/* Hero Section */} +
+
+
+
+ + AI-Powered Repair Assistant +
+

+ Repair with +
+ Confidence +

+

+ Your AI-powered DIY repair assistant. Scan, diagnose, and fix with step-by-step guidance. +

+
+ + + + +
+
+
+ Repair +
+
+
- {/* How It Works */} -
-
-

How It Works

-

Three simple steps to repair anything with AI assistance

+{/* Stats Section */} +
+
+ {stats.map((stat, index) => ( +
+
+
{stat.number}
+
{stat.label}
-
- {[{ icon: '📱', title: 'Scan', desc: 'Use your camera to scan the broken device and let AI identify the issue.' }, { icon: '🧠', title: 'Analyze', desc: 'Get instant diagnosis and step-by-step repair instructions.' }, { icon: '🛠️', title: 'Repair', desc: 'Follow guided tutorials with AR assistance to fix confidently.' }].map((step, i) => ( -
-
{step.icon}
-

{step.title}

-

{step.desc}

-
- {String(i + 1).padStart(2, '0')} -
-
- ))} +
+ ))} +
+
+ + + {/* How It Works */} +
+
+

+ How It Works +

+

+ Three simple steps to repair anything with AI assistance +

+
+
+ {[ + { icon: '📱', title: 'Scan', desc: 'Use your camera to scan the broken device and let AI identify the issue.' }, + { icon: '🧠', title: 'Analyze', desc: 'Get instant diagnosis and step-by-step repair instructions.' }, + { icon: '🛠️', title: 'Repair', desc: 'Follow guided tutorials with AR assistance to fix confidently.' } + ].map((step, i) => ( +
+
{step.icon}
+

+ {step.title} +

+

{step.desc}

+
+ {String(i + 1).padStart(2, '0')}
-
+
+ ))} +
+ {/* Features */} -
-
-

Powerful Features

-

Everything you need to become your own repair expert

-
-
- {features.map((feature, i) => ( -
-
{feature.icon}
-

{feature.title}

-

{feature.desc}

-
- Learn More - -
-
- ))} +
+
+

+ Powerful Features +

+

+ Everything you need to become your own repair expert +

+
+
+ {features.map((feature, i) => ( +
+
{feature.icon}
+

+ {feature.title} +

+

{feature.desc}

+
+ Learn More +
-
+
+ ))} + +
+ {/* FAQ */} -
-
-

Frequently Asked Questions

-

Everything you need to know about Refixly

-
-
- -
-
- - {/* Call To Action */} -
-
-
-

Ready to Fix it Yourself?

-

- Join thousands of users who are repairing with confidence using Refixly. -

-
- - - - -
-
-
-
+
+
+

+ Frequently Asked Questions +

+

+ Everything you need to know about Refixly +

+
+
+ +
+
+ + {/* Call To Action */} +
+
+
+

+ Ready to Fix it Yourself? +

+

+ Join thousands of users who are repairing with confidence using Refixly. +

+
+ + + + +
+
+
+
+ ); }; diff --git a/client/src/Pages/ProfilePage.jsx b/client/src/Pages/ProfilePage.jsx index 2456774..dcd3331 100644 --- a/client/src/Pages/ProfilePage.jsx +++ b/client/src/Pages/ProfilePage.jsx @@ -46,15 +46,9 @@ const ProfilePage = () => { }; }, []); - useEffect(() => { - const handler = setTimeout(() => { - setDebouncedDisplayName(displayName); - }, 300); - - return () => { - clearTimeout(handler); - }; + const handler = setTimeout(() => setDebouncedDisplayName(displayName), 300); + return () => clearTimeout(handler); }, [displayName]); const handleProfileUpdate = async (e) => { @@ -63,16 +57,14 @@ const ProfilePage = () => { const loadingToast = toast.loading('Updating profile...'); try { - await updateProfile(user, { - displayName: displayName, - }); + await updateProfile(user, { displayName }); toast.success('Profile updated successfully!', { id: loadingToast }); setIsEditing(false); } catch (error) { toast.error(`Error: ${error.message}`, { id: loadingToast }); } }; - + const handleRemoveTutorial = (videoId) => { const updatedSaved = savedTutorials.filter(t => t.videoId !== videoId); localStorage.setItem('refixly_savedTutorials', JSON.stringify(updatedSaved)); @@ -87,53 +79,119 @@ const ProfilePage = () => { }; if (isLoading) { - return
; + return ( +
+ +
+ ); } + if (!user) { - return

Please log in to view your profile.

; + return ( +
+ +
+

Please log in to view your profile.

+
+
+ ); } const renderTabContent = () => { switch (activeTab) { case 'history': - return ( -
- {searchHistory.length > 0 ? ( - <> -
- -
- - - ) : (

Your scan history will appear here.

)} -
+ return searchHistory.length > 0 ? ( + <> +
+ +
+ + + ) : ( +

Your scan history will appear here.

); + case 'saved': return savedTutorials.length > 0 ? (
{savedTutorials.map(item => ( -
- - {item.title} +
+ + {item.title} {item.title} -
))}
- ) : (

Your saved tutorials will appear here.

); + ) : ( +

Your saved tutorials will appear here.

+ ); + case 'repairs': - return ; + return ( + + ); + default: return null; } }; - - const tabButtonStyle = (tabName) => `flex items-center gap-2 px-4 py-2 font-semibold rounded-t-lg border-b-2 transition-colors ${activeTab === tabName ? 'border-blue-400 text-blue-400' : 'border-transparent text-gray-400 hover:text-white'}`; + + const tabButtonStyle = (tabName) => + `flex items-center gap-2 px-4 py-2 font-semibold rounded-t-lg border-b-2 transition-colors ${ + activeTab === tabName + ? 'border-blue-400 text-blue-400' + : 'border-transparent text-gray-400 hover:text-white' + }`; return (
@@ -142,9 +200,9 @@ const ProfilePage = () => {
- Profile
@@ -153,40 +211,59 @@ const ProfilePage = () => {
{!isEditing && ( - )}
+ {isEditing && ( - -
-
- - setDisplayName(e.target.value)} - className="w-full mt-1 px-3 py-2 bg-gray-700 border border-gray-600 rounded-md" - /> -
-
- - -
+ +
+ + setDisplayName(e.target.value)} + className="w-full mt-1 px-3 py-2 bg-gray-700 border border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400 text-white" + /> +
+
+ +
)}
- +
+
{renderTabContent()}
diff --git a/client/src/Pages/ScanPage.jsx b/client/src/Pages/ScanPage.jsx index efdd873..0235813 100644 --- a/client/src/Pages/ScanPage.jsx +++ b/client/src/Pages/ScanPage.jsx @@ -43,11 +43,11 @@ const ScanPage = () => { }, [scanMode, isModelLoading]); useEffect(() => { - if (!isModelLoading) { - setScanMode('webcam'); - enableWebcam(); - } -}, [isModelLoading]); + if (!isModelLoading) { + setScanMode('webcam'); + enableWebcam(); + } + }, [isModelLoading]); const enableWebcam = async () => { try { @@ -108,16 +108,16 @@ const ScanPage = () => { }; const buttonBaseStyle = "px-4 py-2 rounded-lg font-semibold transition-all duration-300 flex items-center gap-2"; - const activeButtonStyle = "bg-blue-600 text-white"; - const inactiveButtonStyle = "bg-gray-700 text-gray-300 hover:bg-gray-600"; + const activeButtonStyle = "bg-blue-600 text-white dark:bg-blue-500 dark:text-white"; + const inactiveButtonStyle = "bg-gray-700 text-gray-300 hover:bg-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700"; return ( -
+
-

AI Object Scanner

-

Scan an object using your webcam or by uploading an image.

+

AI Object Scanner

+

Scan an object using your webcam or by uploading an image.

-
+
{scanMode === 'webcam' ? ( - videoRef.current?.srcObject ? (