Skip to content
Open
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
78 changes: 60 additions & 18 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import BlogCard from "@/components/blog-card"
import Pagination from "@/components/pagination"
import Link from "next/link"
import Footer from "@/components/footer"
import { ModeToggle } from "@/components/mode-toggle"

interface BlogPost {
slug: string
Expand Down Expand Up @@ -98,25 +99,66 @@ export default function HomePage() {
const { posts, totalPages, hasNextPage, hasPrevPage } = paginatedData

return (
<div className="min-h-screen bg-gradient-to-br from-green-50 via-yellow-50 to-[#FFC517]/10">
{/* Header */}
<header className="border-b border-gradient-to-r from-[#228B22]/20 to-[#FFBF00]/20 bg-white/90 backdrop-blur-sm sticky top-0 z-50 shadow-sm">
<div className="max-w-6xl mx-auto px-4 py-6 flex justify-between items-center">
<div>
<h1 className="text-5xl font-bold font-playfair bg-gradient-to-r from-[#228B22] via-[#5A981A] via-[#91A511] via-[#ADAC0D] via-[#E4B905] to-[#FFBF00] bg-clip-text text-transparent drop-shadow-sm leading-tight pb-2">
Stable Viewpoints
</h1>
<p className="text-gray-600 mt-2 text-lg">Independent Articles about Stability</p>
</div>
<Link
href="/submit"
className="inline-flex items-center gap-2 bg-gradient-to-r from-[#228B22] to-[#91A511] hover:from-[#3E921E] hover:to-[#ADAC0D] text-white px-6 py-3 font-semibold transition-all duration-300 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5"
>
Submit an Article
</Link>
</div>
</header>
<div className="min-h-screen bg-gradient-to-br
from-green-50 via-yellow-50 to-[#FFC517]/10
dark:from-zinc-900 dark:via-zinc-900 dark:to-black
">
{/* Header */}
<header
className="
sticky top-0 z-50
border-b
border-zinc-200 dark:border-zinc-800
bg-white/90 dark:bg-zinc-900/90
backdrop-blur-sm
shadow-sm
"
>
<div className="max-w-6xl mx-auto px-4 py-6 flex justify-between items-center">
{/* Left: Title */}
<div>
<h1
className="
text-5xl font-bold font-playfair leading-tight pb-2
bg-gradient-to-r
from-[#228B22] via-[#E4B905] to-[#FFBF00]
bg-clip-text text-transparent
drop-shadow-sm
"
>
Stable Viewpoints
</h1>

<p className="mt-2 text-lg text-zinc-600 dark:text-zinc-400">
Independent Articles about Stability
</p>
</div>

{/* Right: Actions */}
<div className="flex items-center gap-4">
{/* Theme Toggle */}
{/* <ModeToggle /> */}

{/* Submit Button */}
<Link
href="/submit"
className="
inline-flex items-center gap-2
bg-gradient-to-r from-[#228B22] to-[#91A511]
hover:from-[#3E921E] hover:to-[#ADAC0D]
text-white
px-6 py-3 font-semibold
transition-all duration-300
shadow-lg hover:shadow-xl
transform hover:-translate-y-0.5
rounded-md
"
>
Submit an Article
</Link>
</div>
</div>
</header>
{/* Main Content */}
<main className="max-w-6xl mx-auto px-4 py-12">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
Expand Down
2 changes: 1 addition & 1 deletion components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const LinkedInIcon = () => (

export default function Footer() {
return (
<footer className="border-t border-gradient-to-r from-[#228B22]/20 to-[#FFBF00]/20 bg-gradient-to-r from-[#228B22]/5 via-[#91A511]/5 to-[#FFBF00]/5 backdrop-blur-sm mt-20">
<footer className="border-t border-gray-200 bg-gradient-to-r from-[#228B22]/5 via-[#91A511]/5 to-[#FFBF00]/5 backdrop-blur-sm mt-20">
<div className="max-w-6xl mx-auto px-4 py-12">
<div className="flex flex-col md:flex-row justify-between items-center gap-6">
<div className="text-center md:text-left">
Expand Down
29 changes: 29 additions & 0 deletions components/mode-toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"use client";

import { Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";

export function ModeToggle() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);

useEffect(() => setMounted(true), []);
if (!mounted) return null;

return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
aria-label="Toggle theme"
>
{theme === "dark" ? (
<Sun className="h-5 w-5" />
) : (
<Moon className="h-5 w-5" />
)}
</Button>
Comment on lines +8 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use resolvedTheme instead of theme for accurate theme detection.

When defaultTheme is "system" (as configured in ThemeProvider), the theme value can be "system" rather than the actual resolved theme ("dark" or "light"). This causes incorrect icon display and toggle behavior.

 export function ModeToggle() {
-  const { theme, setTheme } = useTheme();
+  const { resolvedTheme, setTheme } = useTheme();
   const [mounted, setMounted] = useState(false);

   useEffect(() => setMounted(true), []);
   if (!mounted) return null;

   return (
     <Button
       variant="ghost"
       size="icon"
-      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
+      onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
       aria-label="Toggle theme"
     >
-      {theme === "dark" ? (
+      {resolvedTheme === "dark" ? (
         <Sun className="h-5 w-5" />
       ) : (
         <Moon className="h-5 w-5" />
       )}
     </Button>
   );
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function ModeToggle() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null;
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
aria-label="Toggle theme"
>
{theme === "dark" ? (
<Sun className="h-5 w-5" />
) : (
<Moon className="h-5 w-5" />
)}
</Button>
export function ModeToggle() {
const { resolvedTheme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null;
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
aria-label="Toggle theme"
>
{resolvedTheme === "dark" ? (
<Sun className="h-5 w-5" />
) : (
<Moon className="h-5 w-5" />
)}
</Button>
);
}
🤖 Prompt for AI Agents
In components/mode-toggle.tsx around lines 8 to 27, the component uses `theme`
which can be the literal "system" when defaultTheme is "system", causing
incorrect icon and toggle behavior; switch to using `resolvedTheme` from
useTheme for accurate current theme detection (use it for rendering the Sun/Moon
icon) and use `setTheme(resolvedTheme === "dark" ? "light" : "dark")` for the
onClick toggle; keep the mounted guard and import/useResolvedTheme as provided
by next-themes (or destructure `resolvedTheme` from useTheme), and ensure you
fall back safely if `resolvedTheme` is undefined.

);
}
20 changes: 12 additions & 8 deletions components/theme-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
'use client'
"use client";

import * as React from 'react'
import {
ThemeProvider as NextThemesProvider,
type ThemeProviderProps,
} from 'next-themes'
import { ThemeProvider as NextThemesProvider } from "next-themes";

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>
export function ThemeProvider({ children }: { children: React.ReactNode }) {
return (
<NextThemesProvider
attribute="class"
defaultTheme="system"
enableSystem
>
{children}
</NextThemesProvider>
);
}
45 changes: 45 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
"start": "next start"
},
"dependencies": {
"@radix-ui/react-slot": "^1.2.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"gray-matter": "^4.0.3",
"lucide-react": "^0.454.0",
"next": "15.2.4",
"next-mdx-remote": "^5.0.0",
"next-themes": "^0.4.6",
"react": "^19",
"react-dom": "^19",
"serve": "^14.2.4",
Expand Down