Rename ssr to website, website to spa, add spa nginx config

This commit is contained in:
Your Name committed 2026-06-03 09:38:15 +07:00
1 parent fc6bf0218e
commit 8514342c2f
103 files changed
+801 -768

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
import { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import Navbar from '../components/Navbar'
import Footer from '../components/Footer'
import { API_BASE, type Category, type Article } from '../types'
export default function ScentGuidePage() {
const [categories, setCategories] = useState<Category[]>([])
const [articles, setArticles] = useState<Article[]>([])
useEffect(() => {
fetch(`${API_BASE}/categories`).then(r => r.json()).then(setCategories).catch(console.error)
fetch(`${API_BASE}/articles?publishedOnly=true`).then(r => r.json()).then(setArticles).catch(console.error)
}, [])
return (
<div className="min-h-screen flex flex-col">
<Navbar categories={categories} />
{/* Header */}
<div className="pt-32 pb-16 px-6 text-center space-y-4 border-b border-white/5 bg-night-800/20">
<p className="text-cyan-glow uppercase tracking-[0.4em] text-xs font-semibold opacity-70">Journal</p>
<h1 className="text-5xl font-bold">Scent Guide</h1>
<p className="text-slate-400 max-w-lg mx-auto">
Explore our collection of articles, guides, and sensory knowledge.
</p>
</div>
<div className="flex-1 max-w-7xl mx-auto px-6 py-16 w-full">
{articles.length === 0 ? (
<div className="text-center text-slate-500 italic py-20">
Articles coming soon. Check back later!
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{articles.map(article => (
<Link
key={article.id}
to={`/article/${article.slug}`}
className="group block bg-night-950 rounded-2xl overflow-hidden border border-white/5 hover:border-cyan-glow/30 transition-all duration-300 hover:-translate-y-1 hover:shadow-2xl flex flex-col"
>
<div className="aspect-[4/3] bg-night-900 overflow-hidden shrink-0">
{article.coverImage ? (
<img src={article.coverImage} alt={article.title} className="w-full h-full object-cover opacity-80 group-hover:opacity-100 group-hover:scale-105 transition-all duration-500" />
) : (
<div className="w-full h-full bg-white/5 flex items-center justify-center">
<span className="text-slate-600 text-sm tracking-widest uppercase">No Image</span>
</div>
)}
</div>
<div className="p-6 space-y-3 flex-1 flex flex-col">
<p className="text-[10px] text-cyan-glow font-bold tracking-widest uppercase">
{new Date(article.createdAt).toLocaleDateString()}
</p>
<h3 className="text-xl font-bold leading-tight group-hover:text-cyan-glow transition-colors">{article.title}</h3>
{/* Remove HTML tags for purely excerpt preview */}
<div className="text-slate-400 text-sm line-clamp-3" dangerouslySetInnerHTML={{ __html: article.content }} />
</div>
</Link>
))}
</div>
)}
</div>
<Footer categories={categories} />
</div>
)
}