"use client"; import React, { useState, useMemo, useEffect } from "react"; import { Header } from "@/components/Header"; import { MoodTracker } from "@/components/MoodTracker"; import { JournalCard } from "@/components/JournalCard"; import { NewPostModal } from "@/components/NewPostModal"; import { PostDetailModal } from "@/components/PostDetailModal"; import { INITIAL_POSTS, MOODS } from "@/components/mockData"; import { JournalPost, MoodType } from "@/components/types"; import { Dices, Feather, Sparkles, Filter, Bookmark, Coffee, RefreshCw } from "lucide-react"; export default function Home() { const [posts, setPosts] = useState(INITIAL_POSTS); const [activeMood, setActiveMood] = useState("all"); const [searchQuery, setSearchQuery] = useState(""); const [selectedTag, setSelectedTag] = useState(null); const [isNewPostOpen, setIsNewPostOpen] = useState(false); const [detailPost, setDetailPost] = useState(null); // Fetch posts from PostgreSQL API on mount useEffect(() => { async function loadPosts() { try { const res = await fetch("/api/posts"); if (res.ok) { const data = await res.json(); if (Array.isArray(data) && data.length > 0) { setPosts(data); } } } catch (err) { console.error("Failed to load posts from API:", err); } } loadPosts(); }, []); // Extract all unique tags const allTags = useMemo(() => { const set = new Set(); posts.forEach((p) => p.tags.forEach((t) => set.add(t))); return Array.from(set); }, [posts]); // Filtered posts const filteredPosts = useMemo(() => { return posts.filter((post) => { // Mood filter if (activeMood !== "all" && post.mood !== activeMood) { return false; } // Tag filter if (selectedTag && !post.tags.includes(selectedTag)) { return false; } // Search query if (searchQuery.trim()) { const q = searchQuery.toLowerCase(); const matchesContent = post.content.toLowerCase().includes(q); const matchesTitle = post.title?.toLowerCase().includes(q); const matchesTags = post.tags.some((t) => t.toLowerCase().includes(q)); const matchesMargin = post.marginNotes?.some((m) => m.toLowerCase().includes(q)); return matchesContent || matchesTitle || matchesTags || matchesMargin; } return true; }); }, [posts, activeMood, selectedTag, searchQuery]); const handleAddPost = async (newPost: JournalPost) => { setPosts([newPost, ...posts]); try { await fetch("/api/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newPost), }); } catch (err) { console.error("Failed to save post to database:", err); } }; const handleRandomPost = () => { if (posts.length === 0) return; const randomIndex = Math.floor(Math.random() * posts.length); setDetailPost(posts[randomIndex]); }; const handleTagClick = (tag: string) => { setSelectedTag(selectedTag === tag ? null : tag); }; const clearFilters = () => { setActiveMood("all"); setSelectedTag(null); setSearchQuery(""); }; return (
{/* Top Header */}
setIsNewPostOpen(true)} onRandomPostClick={handleRandomPost} postCount={posts.length} /> {/* Main Journal Canvas */}
{/* Floating Side Index Tabs (Notebook Edge Decoration) */}
DİZİN SEKMELERİ
{allTags.slice(0, 6).map((tag, idx) => { const isSelected = selectedTag === tag; const tabColors = [ "bg-[#FEF3C7] text-[#92400E] border-[#D97706]/40", "bg-[#FFE4E6] text-[#9F1239] border-[#E11D48]/40", "bg-[#D1FAE5] text-[#065F46] border-[#059669]/40", "bg-[#E0F2FE] text-[#075985] border-[#0284C7]/40", "bg-[#EDE9FE] text-[#5B21B6] border-[#7C3AED]/40", "bg-[#F3ECE2] text-[#18181B] border-[#18181B]/20", ]; const colorClass = tabColors[idx % tabColors.length]; return ( ); })}
{/* The Signature Hero: Mood Tracker & Weather Log */} { setActiveMood(mood); }} filteredCount={filteredPosts.length} /> {/* Active Filter Tags Indicator Bar */} {(selectedTag || activeMood !== "all" || searchQuery) && (
Aktif Filtreler: {activeMood !== "all" && ( Mood: {MOODS.find((m) => m.id === activeMood)?.label} )} {selectedTag && ( #{selectedTag} )} {searchQuery && ( “{searchQuery}” )}
)} {/* The Mixed-Media Journal Feed */} {filteredPosts.length > 0 ? (
{filteredPosts.map((post) => ( setDetailPost(p)} onTagClick={handleTagClick} /> ))}
) : ( /* Empty State */

Bu Filtrede Karalama Bulunamadı

Görünüşe göre bu ruh halinde henüz bir şey yazılmamış. Belki de bir fincan çay alıp aklına gelen ilk şeyi karalama vaktidir?

)} {/* Footer Scrapbook Note */}
"En iyi fikirler, en saçma karalamaların arasından çıkar."
© 2026 Mustafa Yıldız • mstfyldz journal • Craft with passion
{/* Modals */} setIsNewPostOpen(false)} onAddPost={handleAddPost} /> setDetailPost(null)} onTagClick={handleTagClick} />
); }