Skip to content
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
85 changes: 85 additions & 0 deletions src/theme/Footer/Layout/enhanced-footer.css
Original file line number Diff line number Diff line change
Expand Up @@ -1729,3 +1729,88 @@ html[data-theme='light'] .enhanced-footer {
.stat-item:nth-child(2) { animation-delay: 0.2s; }
.stat-item:nth-child(3) { animation-delay: 0.3s; }
.stat-item:nth-child(4) { animation-delay: 0.4s; }


/* Toast Notification Styles */
.newsletter-toast {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9999;
animation: slideIn 0.3s ease-out;
isolation: isolate;
}

.toast-content {
display: flex;
align-items: center;
background: #ffffff !important; /* solid white */
border-radius: 8px;
padding: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
border-left: 4px solid #4CAF50;
max-width: 350px;
opacity: 1 !important;
}


.toast-icon {
font-size: 24px;
margin-right: 12px;
}

.toast-message h4 {
margin: 0 0 4px 0;
font-size: 16px;
color: #2c3e50;
}

.toast-message p {
margin: 0;
font-size: 14px;
color: #7f8c8d;
}

.toast-close {
background: none;
border: none;
font-size: 20px;
cursor: pointer;
margin-left: 16px;
color: #95a5a6;
padding: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}

.toast-close:hover {
background: #f8f9fa;
color: #2c3e50;
}

@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

@media (max-width: 768px) {
.newsletter-toast {
bottom: 10px;
right: 10px;
left: 10px;
}

.toast-content {
max-width: none;
}
}
126 changes: 97 additions & 29 deletions src/theme/Footer/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

import React, {type ReactNode, useState, useEffect} from 'react';
import Link from "@docusaurus/Link";
import type {Props} from '@theme/Footer/Layout';
import './enhanced-footer.css';
import Counter from './Counter';
import { createPortal } from "react-dom";


// Dynamic stats interface
interface FooterStats {
Expand All @@ -28,6 +29,7 @@ export default function FooterLayout({
});
const [email, setEmail] = useState('');
const [isSubscribed, setIsSubscribed] = useState(false);
const [showToast, setShowToast] = useState(false);

useEffect(() => {
// Simulate real-time stats updates
Expand Down Expand Up @@ -59,22 +61,57 @@ export default function FooterLayout({
e.preventDefault();
if (email) {
setIsSubscribed(true);
setShowToast(true);

// Hide toast after 3 seconds
setTimeout(() => {
setShowToast(false);
}, 3000);

// Reset form after 3 seconds
setTimeout(() => {
setIsSubscribed(false);
setEmail('');
}, 3000);
}
};

return (
<footer className="enhanced-footer">
{/* Toast Notification */}
{showToast &&
createPortal(
<div className="newsletter-toast">
<div className="toast-content">
<span className="toast-icon">🎉</span>
<div className="toast-message">
<h4>Successfully Subscribed!</h4>
<p>Thank you for joining our newsletter.</p>
</div>
<button
className="toast-close"
onClick={() => setShowToast(false)}
aria-label="Close notification"
>
×
</button>
</div>
</div>,
document.body // 👈 mounts toast directly to <body>, outside footer
)}

{/* Hero Section */}
<div className="footer-hero">
<div className="container">
<div className="footer-hero-content">
<div className="footer-logo-section">
<div className="footer-logo">
<div className="logo-container">
<img src="/img/logo.png" alt="recodehive" className="footer-logo-img" />
<img
src="/img/logo.png"
alt="recodehive"
className="footer-logo-img"
/>
</div>
<div className="footer-brand-header">
<h1 className="footer-brand-title">recodehive</h1>
Expand All @@ -86,37 +123,49 @@ export default function FooterLayout({
<span className="star">⭐</span>
<span className="star">⭐</span>
</div>
<span className="trust-text">Trusted by 50K+ developers</span>
<span className="trust-text">
Trusted by 50K+ developers
</span>
</div>
</div>
</div>
</div>
<div className="footer-hero-text">
<h1>Empowering the Next Generation of Developers</h1>
<p>Master cutting-edge technologies, build innovative projects, and join a thriving community of developers passionate about open-source innovation and continuous learning.</p>
<p>
Master cutting-edge technologies, build innovative projects, and
join a thriving community of developers passionate about
open-source innovation and continuous learning.
</p>
</div>
</div>

{/* Stats Section */}
<div className="footer-stats">
<div className="stat-item" title="Growing community of active learners">
<div
className="stat-item"
title="Growing community of active learners"
>
<div className="stat-icon stat-icon-learners">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zM4 18v-6h2.5l6 6H4zm16.5-9.5L19 7l-7.5 7.5L9 12l-2.5 2.5L4 12l7.5-7.5L14 7l6.5 1.5z"/>
<path d="M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zM4 18v-6h2.5l6 6H4zm16.5-9.5L19 7l-7.5 7.5L9 12l-2.5 2.5L4 12l7.5-7.5L14 7l6.5 1.5z" />
</svg>
</div>
<div className="stat-content">
<div className="stat-number">
<Counter value={parseInt(stats.activeUsers)} suffix="K+" />
<Counter value={parseInt(stats.activeUsers)} suffix="K+" />
</div>
<div className="stat-label">Active Learners</div>
</div>
</div>

<div className="stat-item" title="Comprehensive tutorials and courses">
<div
className="stat-item"
title="Comprehensive tutorials and courses"
>
<div className="stat-icon stat-icon-tutorials">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z"/>
<path d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-5 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z" />
</svg>
</div>
<div className="stat-content">
Expand All @@ -127,10 +176,13 @@ export default function FooterLayout({
</div>
</div>

<div className="stat-item" title="High success rate in learning outcomes">
<div
className="stat-item"
title="High success rate in learning outcomes"
>
<div className="stat-icon stat-icon-success">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
</svg>
</div>
<div className="stat-content">
Expand All @@ -141,10 +193,13 @@ export default function FooterLayout({
</div>
</div>

<div className="stat-item" title="Round-the-clock community support">
<div
className="stat-item"
title="Round-the-clock community support"
>
<div className="stat-icon stat-icon-support">
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-6h2v6zm0-8h-2V7h2v4z"/>
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-6h2v6zm0-8h-2V7h2v4z" />
</svg>
</div>
<div className="stat-content">
Expand All @@ -169,7 +224,6 @@ export default function FooterLayout({
<ul className="footer-links">
<li>
<Link to="#" className="footer-link">

<span className="link-icon">📖</span>
Documentation
<span className="link-badge popular">Popular</span>
Expand Down Expand Up @@ -271,7 +325,6 @@ export default function FooterLayout({
</Link>
</li>
</ul>

</div>

{/* Newsletter Column with Quick Links below */}
Expand All @@ -281,7 +334,8 @@ export default function FooterLayout({
Stay in the Loop
</h3>
<p className="newsletter-description">
Join {stats.activeUsers} developers getting weekly insights, tutorials, and exclusive content.
Join {stats.activeUsers} developers getting weekly insights,
tutorials, and exclusive content.
</p>
<form className="newsletter-form" onSubmit={handleSubscribe}>
<input
Expand All @@ -294,14 +348,18 @@ export default function FooterLayout({
/>
<button
type="submit"
className={`newsletter-button ${isSubscribed ? 'subscribed' : ''}`}
className={`newsletter-button ${
isSubscribed ? "subscribed" : ""
}`}
disabled={isSubscribed}
>
{isSubscribed ? '✓ Subscribed!' : 'Subscribe Now →'}
{isSubscribed ? "✓ Subscribed!" : "Subscribe Now →"}
</button>
</form>
<div className="newsletter-stats">
<span className="newsletter-stat">📊 1.2K+ developers joined this week</span>
<span className="newsletter-stat">
📊 1.2K+ developers joined this week
</span>
</div>
{/* Quick Links Section moved below subscription */}
<div className="quick-links-section newsletter-quick-links">
Expand Down Expand Up @@ -338,7 +396,7 @@ export default function FooterLayout({
aria-label="GitHub"
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 0C5.37 0 0 5.37 0 12C0 17.31 3.435 21.795 8.205 23.385C8.805 23.49 9.03 23.13 9.03 22.815C9.03 22.53 9.015 21.585 9.015 20.58C6 21.135 5.22 19.845 4.98 19.17C4.845 18.825 4.26 17.76 3.75 17.475C3.33 17.25 2.73 16.695 3.735 16.68C4.68 16.665 5.355 17.55 5.58 17.91C6.66 19.725 8.385 19.215 9.075 18.9C9.18 18.12 9.495 17.595 9.84 17.295C7.17 16.995 4.38 15.96 4.38 11.37C4.38 10.065 4.845 8.985 5.61 8.145C5.49 7.845 5.07 6.615 5.73 4.965C5.73 4.965 6.735 4.65 9.03 6.195C9.99 5.925 11.01 5.79 12.03 5.79C13.05 5.79 14.07 5.925 15.03 6.195C17.325 4.635 18.33 4.965 18.33 4.965C18.99 6.615 18.57 7.845 18.45 8.145C19.215 8.985 19.68 10.05 19.68 11.37C19.68 15.975 16.875 16.995 14.205 17.295C14.64 17.67 15.015 18.39 15.015 19.515C15.015 21.12 15 22.41 15 22.815C15 23.13 15.225 23.505 15.825 23.385C18.2072 22.5807 20.2772 21.0497 21.7437 19.0074C23.2101 16.965 23.9993 14.5143 24 12C24 5.37 18.63 0 12 0Z"/>
<path d="M12 0C5.37 0 0 5.37 0 12C0 17.31 3.435 21.795 8.205 23.385C8.805 23.49 9.03 23.13 9.03 22.815C9.03 22.53 9.015 21.585 9.015 20.58C6 21.135 5.22 19.845 4.98 19.17C4.845 18.825 4.26 17.76 3.75 17.475C3.33 17.25 2.73 16.695 3.735 16.68C4.68 16.665 5.355 17.55 5.58 17.91C6.66 19.725 8.385 19.215 9.075 18.9C9.18 18.12 9.495 17.595 9.84 17.295C7.17 16.995 4.38 15.96 4.38 11.37C4.38 10.065 4.845 8.985 5.61 8.145C5.49 7.845 5.07 6.615 5.73 4.965C5.73 4.965 6.735 4.65 9.03 6.195C9.99 5.925 11.01 5.79 12.03 5.79C13.05 5.79 14.07 5.925 15.03 6.195C17.325 4.635 18.33 4.965 18.33 4.965C18.99 6.615 18.57 7.845 18.45 8.145C19.215 8.985 19.68 10.05 19.68 11.37C19.68 15.975 16.875 16.995 14.205 17.295C14.64 17.67 15.015 18.39 15.015 19.515C15.015 21.12 15 22.41 15 22.815C15 23.13 15.225 23.505 15.825 23.385C18.2072 22.5807 20.2772 21.0497 21.7437 19.0074C23.2101 16.965 23.9993 14.5143 24 12C24 5.37 18.63 0 12 0Z" />
</svg>
</Link>

Expand All @@ -348,7 +406,7 @@ export default function FooterLayout({
aria-label="Twitter"
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</Link>

Expand All @@ -358,7 +416,7 @@ export default function FooterLayout({
aria-label="Instagram"
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/>
<path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" />
</svg>
</Link>

Expand All @@ -368,29 +426,39 @@ export default function FooterLayout({
aria-label="LinkedIn"
>
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z" />
</svg>
</Link>
</div>
</div>

<div className="footer-bottom-center">
<div className="footer-legal-links">
<Link to="/privacy-policy" className="legal-link">Privacy Policy</Link>
<Link to="/terms-service" className="legal-link">Terms of Service</Link>
<Link to="/code-of-conduct" className="legal-link">Code of Conduct</Link>
<Link to="/License" className="legal-link">License</Link>
<Link to="/privacy-policy" className="legal-link">
Privacy Policy
</Link>
<Link to="/terms-service" className="legal-link">
Terms of Service
</Link>
<Link to="/code-of-conduct" className="legal-link">
Code of Conduct
</Link>
<Link to="/License" className="legal-link">
License
</Link>
</div>
</div>

<div className="footer-bottom-right">
<div className="footer-copyright">
<span>© {currentYear} recodehive. Made with ❤️ by the Community.</span>
<span>
© {currentYear} recodehive. Made with ❤️ by the Community.
</span>
</div>
</div>
</div>
</div>
</div>
</footer>
);
}
}
Loading