196 lines
8.8 KiB
TypeScript
196 lines
8.8 KiB
TypeScript
"use client";
|
||
|
||
import React from "react";
|
||
import { MOODS } from "./mockData";
|
||
import { MoodType } from "./types";
|
||
import { Zap, Moon, Sparkles, Feather, Camera, BookOpen, Sun, CloudRain, Wind, Radio } from "lucide-react";
|
||
|
||
interface MoodTrackerProps {
|
||
activeMood: MoodType;
|
||
onSelectMood: (mood: MoodType) => void;
|
||
filteredCount: number;
|
||
}
|
||
|
||
export const MoodTracker: React.FC<MoodTrackerProps> = ({
|
||
activeMood,
|
||
onSelectMood,
|
||
filteredCount,
|
||
}) => {
|
||
const activeMoodObj = MOODS.find((m) => m.id === activeMood) || MOODS[0];
|
||
|
||
const getMoodIcon = (iconName: string, className = "w-4 h-4") => {
|
||
switch (iconName) {
|
||
case "Zap":
|
||
return <Zap className={className} />;
|
||
case "Moon":
|
||
return <Moon className={className} />;
|
||
case "Sparkles":
|
||
return <Sparkles className={className} />;
|
||
case "Feather":
|
||
return <Feather className={className} />;
|
||
case "Camera":
|
||
return <Camera className={className} />;
|
||
default:
|
||
return <BookOpen className={className} />;
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="w-full relative mb-8">
|
||
{/* Notebook Top Header Card */}
|
||
<div className="notebook-sheet rounded-2xl p-5 sm:p-7 relative overflow-hidden transition-all duration-300">
|
||
{/* Top Paper Header Elements */}
|
||
<div className="flex flex-col md:flex-row md:items-start justify-between gap-4 pb-5 border-b border-[#18181B]/10">
|
||
<div>
|
||
<div className="flex items-center gap-2">
|
||
<span className="font-handwritten text-2xl sm:text-3xl text-[#18181B] font-bold tracking-tight">
|
||
MOOD TRACKER & WEATHER LOG
|
||
</span>
|
||
<span className="rubber-stamp text-[10px] text-[#E11D48] border-[#E11D48] rotate-[-2deg] hidden sm:inline-flex">
|
||
CANLI SİNYAL
|
||
</span>
|
||
</div>
|
||
<p className="text-xs sm:text-sm font-serif text-[#52525B] mt-1 max-w-xl">
|
||
Günün farklı saatlerindeki zihinsel dalgalanmalar, anlık aydınlanmalar ve saçma gözlemler haritası.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Stamped Date & Wax Seal Badge */}
|
||
<div className="flex items-center gap-3.5 self-start md:self-auto">
|
||
<div className="text-right font-mono">
|
||
<div className="text-xs uppercase tracking-wider text-[#787D89] font-semibold">GÜNCEL DURUM</div>
|
||
<div className="text-sm font-bold text-[#18181B] flex items-center justify-end gap-1.5 mt-0.5">
|
||
<span className="w-2 h-2 rounded-full bg-[#E11D48] animate-ping" />
|
||
<span>{activeMoodObj.stampText}</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Interactive Wax Seal */}
|
||
<button
|
||
onClick={() => onSelectMood("all")}
|
||
title="Tüm Arşive Dön"
|
||
aria-label="Tüm Arşive Dön"
|
||
className="wax-seal w-12 h-12 rounded-full flex flex-col items-center justify-center text-white cursor-pointer relative shrink-0"
|
||
>
|
||
<span className="font-heading font-black text-lg leading-none">M</span>
|
||
<span className="text-[7px] font-mono tracking-tighter uppercase opacity-80 leading-none">LOG</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* The Atmospheric Mood Frequency Wave */}
|
||
<div className="py-4 relative">
|
||
<div className="flex items-center justify-between text-[11px] font-mono text-[#787D89] mb-1">
|
||
<span className="flex items-center gap-1">
|
||
<Sun className="w-3.5 h-3.5 text-[#D97706]" /> 08:00 (Sabah Kahvesi)
|
||
</span>
|
||
<span className="flex items-center gap-1 hidden sm:flex">
|
||
<Wind className="w-3.5 h-3.5 text-[#0284C7]" /> 14:30 (Kaos & Fikirler)
|
||
</span>
|
||
<span className="flex items-center gap-1">
|
||
<CloudRain className="w-3.5 h-3.5 text-[#7C3AED]" /> 23:45 (Gece Melankolisi)
|
||
</span>
|
||
</div>
|
||
|
||
{/* SVG Wave Graphic */}
|
||
<div className="w-full h-28 sm:h-36 relative my-3 flex items-center justify-center">
|
||
<svg
|
||
className="w-full h-full"
|
||
viewBox="0 0 800 120"
|
||
preserveAspectRatio="xMidYMid meet"
|
||
fill="none"
|
||
xmlns="http://www.w3.org/2000/svg"
|
||
>
|
||
{/* Reference Grid lines */}
|
||
<line x1="0" y1="65" x2="800" y2="65" stroke="rgba(24, 24, 27, 0.08)" strokeDasharray="4 4" />
|
||
<line x1="0" y1="25" x2="800" y2="25" stroke="rgba(24, 24, 27, 0.04)" strokeDasharray="2 4" />
|
||
<line x1="0" y1="105" x2="800" y2="105" stroke="rgba(24, 24, 27, 0.04)" strokeDasharray="2 4" />
|
||
|
||
{/* Background gradient fill */}
|
||
<path
|
||
d="M 0 65 C 60 25, 140 25, 200 65 C 260 105, 340 105, 400 65 C 460 25, 540 25, 600 65 C 660 105, 740 105, 800 65 L 800 120 L 0 120 Z"
|
||
fill="url(#moodGradient)"
|
||
opacity="0.22"
|
||
/>
|
||
|
||
{/* Mathematically precise smooth continuous wave curve */}
|
||
<path
|
||
d="M 0 65 C 60 25, 140 25, 200 65 C 260 105, 340 105, 400 65 C 460 25, 540 25, 600 65 C 660 105, 740 105, 800 65"
|
||
stroke="#18181B"
|
||
strokeWidth="2.5"
|
||
strokeLinecap="round"
|
||
fill="none"
|
||
/>
|
||
|
||
{/* Perfectly round circles positioned exactly at wave peaks & valleys */}
|
||
<circle cx="100" cy="45" r="7" fill="#D97706" stroke="#FAF7F2" strokeWidth="2.5" />
|
||
<circle cx="300" cy="85" r="7" fill="#E11D48" stroke="#FAF7F2" strokeWidth="2.5" />
|
||
<circle cx="500" cy="45" r="7" fill="#059669" stroke="#FAF7F2" strokeWidth="2.5" />
|
||
<circle cx="700" cy="85" r="8" fill="#7C3AED" stroke="#FAF7F2" strokeWidth="2.5" className="animate-pulse" />
|
||
|
||
<defs>
|
||
<linearGradient id="moodGradient" x1="0" y1="0" x2="800" y2="0" gradientUnits="userSpaceOnUse">
|
||
<stop stopColor="#D97706" />
|
||
<stop offset="0.33" stopColor="#E11D48" />
|
||
<stop offset="0.66" stopColor="#059669" />
|
||
<stop offset="1" stopColor="#7C3AED" />
|
||
</linearGradient>
|
||
</defs>
|
||
</svg>
|
||
|
||
{/* Handwritten Mood Annotations on Wave */}
|
||
<div className="absolute top-1 left-[8%] text-xs font-handwritten text-[#D97706] rotate-[-4deg] hidden sm:block">
|
||
"kahve etkisi ⚡"
|
||
</div>
|
||
<div className="absolute bottom-1 left-[32%] text-xs font-handwritten text-[#E11D48] rotate-[3deg] hidden sm:block">
|
||
"ani fikir! 💡"
|
||
</div>
|
||
<div className="absolute top-1 left-[58%] text-xs font-handwritten text-[#059669] rotate-[-2deg] hidden sm:block">
|
||
"sakin anlar 🌿"
|
||
</div>
|
||
<div className="absolute bottom-1 right-[8%] text-xs font-handwritten text-[#7C3AED] rotate-[-3deg] hidden sm:block">
|
||
"gece kodu ☕"
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Live Broadcast Status Banner */}
|
||
<div className="mt-1 mb-5 px-3.5 py-2.5 rounded-xl bg-[#F4EFE6] border border-[#18181B]/10 flex items-center justify-between gap-3 text-xs">
|
||
<div className="flex items-center gap-2 text-[#18181B]">
|
||
<Radio className="w-3.5 h-3.5 text-[#E11D48] animate-pulse shrink-0" />
|
||
<span className="font-serif">
|
||
<strong>Şu anki Zihinsel Frekans:</strong> {activeMoodObj.label} • <em>{activeMoodObj.sublabel}</em>
|
||
</span>
|
||
</div>
|
||
<span className="font-mono text-[11px] text-[#787D89] shrink-0">
|
||
{filteredCount} sonuç gösteriliyor
|
||
</span>
|
||
</div>
|
||
|
||
{/* Mood Filter Pill Tabs */}
|
||
<div className="flex items-center gap-2 overflow-x-auto pb-1 scrollbar-none">
|
||
{MOODS.map((mood) => {
|
||
const isSelected = activeMood === mood.id;
|
||
return (
|
||
<button
|
||
key={mood.id}
|
||
onClick={() => onSelectMood(mood.id)}
|
||
className={`flex items-center gap-2 px-3.5 py-2 rounded-xl text-xs font-heading font-semibold transition-all duration-200 shrink-0 cursor-pointer ${
|
||
isSelected
|
||
? "bg-[#18181B] text-[#FAF7F2] shadow-sm translate-y-[-1px]"
|
||
: "bg-[#FAF7F2] text-[#52525B] hover:bg-[#EFE7D6] hover:text-[#18181B] border border-[#18181B]/10"
|
||
}`}
|
||
>
|
||
<span style={{ color: isSelected ? "#FAF7F2" : mood.color }}>
|
||
{getMoodIcon(mood.iconName, "w-3.5 h-3.5")}
|
||
</span>
|
||
<span>{mood.label}</span>
|
||
</button>
|
||
);
|
||
})}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|