Skip to content
Closed
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
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@
}
})();
</script>
<script>
// Initialize theme before React renders to prevent flicker
(function() {
const theme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

if (theme === 'dark' || (!theme && prefersDark)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
})();
</script>
</head>
<body>
<div id="root"></div>
Expand Down
10 changes: 8 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@ import router from '@/routes';

const App = () => {
useEffect(() => {
const unsubscribe = router.subscribe(() => {
window.scrollTo(0, 0);
let lastPathname = window.location.pathname;

const unsubscribe = router.subscribe((state) => {
// Only scroll to top on pathname changes, not on query/hash changes
if (state.location.pathname !== lastPathname) {
window.scrollTo(0, 0);
lastPathname = state.location.pathname;
}
});
const handleRedirect = () => {
const redirectPath = sessionStorage.getItem('gh_redirect');
Expand Down
8 changes: 4 additions & 4 deletions src/components/DeveloperTestimonials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ const ReviewCard = ({
/>

{/* Feedback Text */}
<motion.p
className="text-gray-700 dark:text-gray-300 mt-2"
<motion.div
className="text-gray-700 dark:text-gray-300 mt-2 flex-1 overflow-y-auto max-h-32 custom-scrollbar"
variants={testimonialText}
>
{body}
</motion.p>
<p>{body}</p>
</motion.div>

{/* User Info */}
<div className="flex items-center mt-4 space-x-3 text-left">
Expand Down
73 changes: 54 additions & 19 deletions src/components/shared/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,51 @@ import { useState, useEffect } from 'react';
import { Moon, Sun } from 'lucide-react';

const DarkModeToggle = () => {
const [isDarkMode, setIsDarkMode] = useState(false);
// Initialize from the class that was already set in index.html
const [isDarkMode, setIsDarkMode] = useState(() => {
return document.documentElement.classList.contains('dark');
});
const [isHovered, setIsHovered] = useState(false);

useEffect(() => {
// Sync with localStorage and system preference on mount
const theme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

if (theme === 'dark') {
document.documentElement.classList.add('dark');
setIsDarkMode(true);
} else {
} else if (theme === 'light') {
document.documentElement.classList.remove('dark');
setIsDarkMode(false);
} else {
// If no preference saved, respect system preference
if (prefersDark) {
document.documentElement.classList.add('dark');
setIsDarkMode(true);
} else {
document.documentElement.classList.remove('dark');
setIsDarkMode(false);
}
}

// Listen for system theme changes (only if no manual preference is set)
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleThemeChange = (e: MediaQueryListEvent) => {
// Only update if user hasn't set a manual preference
if (!localStorage.getItem('theme')) {
if (e.matches) {
document.documentElement.classList.add('dark');
setIsDarkMode(true);
} else {
document.documentElement.classList.remove('dark');
setIsDarkMode(false);
}
}
};

mediaQuery.addEventListener('change', handleThemeChange);
return () => mediaQuery.removeEventListener('change', handleThemeChange);
}, []);

const toggleDarkMode = () => {
Expand All @@ -34,24 +67,25 @@ const DarkModeToggle = () => {
const translateX = isDarkMode ? trackWidth - thumbWidth - padding : padding;

return (
<button
onClick={toggleDarkMode}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className="group relative inline-flex h-9 w-18 items-center rounded-full transition-all duration-500 focus:outline-none focus:ring-2 focus:ring-offset-1"
style={{
backgroundColor: isDarkMode ? '#1e293b' : '#bae6fd',
boxShadow: isDarkMode
? '0 6px 16px rgba(30, 41, 59, 0.4), inset 0 1px 2px rgba(255, 255, 255, 0.05)'
: '0 6px 16px rgba(186, 230, 253, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.1)',
<div className="flex items-center justify-center overflow-visible">
<button
onClick={toggleDarkMode}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
className="group relative inline-flex h-9 w-18 items-center rounded-full transition-all duration-500 focus:outline-none focus:ring-2 focus:ring-offset-1"
style={{
backgroundColor: isDarkMode ? '#1e293b' : '#bae6fd',
boxShadow: isDarkMode
? '0 6px 16px rgba(30, 41, 59, 0.4), inset 0 1px 2px rgba(255, 255, 255, 0.05)'
: '0 6px 16px rgba(186, 230, 253, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.1)',

transform: isHovered ? 'scale(1.05)' : 'scale(1)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
}}
aria-label={isDarkMode ? 'Switch to light mode' : 'Switch to dark mode'}
role="switch"
aria-checked={isDarkMode}
>
transform: isHovered ? 'scale(1.05)' : 'scale(1)',
transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
}}
aria-label={isDarkMode ? 'Switch to light mode' : 'Switch to dark mode'}
role="switch"
aria-checked={isDarkMode}
>
<div
className="absolute inset-0 rounded-full overflow-hidden"
style={{
Expand Down Expand Up @@ -143,6 +177,7 @@ const DarkModeToggle = () => {
}}
/>
</button>
</div>
);
};

Expand Down
24 changes: 14 additions & 10 deletions src/pages/News/NewsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,15 +257,17 @@ const NewsPage: React.FC = () => {
>
<div className="flex items-center justify-center mb-6">
<Sparkles
className="text-blue-500 mr-4 animate-pulse"
size={32}
className="text-blue-500 mr-2 sm:mr-4 animate-pulse"
size={24}
style={{ width: 24, height: 24 }}
/>
<h1 className="text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600">
<h1 className="text-5xl sm:text-6xl md:text-7xl lg:text-8xl font-bold font-Caveat text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-green-600">
NEWS
</h1>
<TrendingUp
className="text-green-500 ml-4 animate-bounce"
size={32}
className="text-green-500 ml-2 sm:ml-4 animate-bounce"
size={24}
style={{ width: 24, height: 24 }}
/>
</div>

Expand Down Expand Up @@ -381,11 +383,13 @@ const NewsPage: React.FC = () => {
whileTap={{ scale: 0.95 }}
>
{cat}
{activeCategory === cat && (
<span className="ml-2 text-xs bg-white text-black bg-opacity-30 rounded-full px-2 py-1">
{(postsByCategory[cat] || []).length}
</span>
)}
<span className={`ml-2 text-xs rounded-full px-2 py-1 ${
activeCategory === cat
? 'bg-white text-black bg-opacity-30'
: 'bg-gray-200 dark:bg-gray-600 text-gray-700 dark:text-gray-300'
}`}>
{(postsByCategory[cat] || []).length}
</span>
</motion.button>
))}
</div>
Expand Down
Loading