Horoskop widget na naslovnici: slikce znamenj + povezava na znamenje

This commit is contained in:
sebastjan 2026-08-15 09:28:44 +02:00
parent 68fe291b55
commit 3c6079d720
2 changed files with 45 additions and 13 deletions

View File

@ -8,6 +8,7 @@ interface AIHoroscope {
signIndex: number;
signName: string;
general: string;
imageUrl?: string | null;
}
function MiniStars({ count, max = 5 }: { count: number; max?: number }) {
@ -44,6 +45,9 @@ export function HoroscopeWidget() {
// Prefer the real AI-generated horoscope for today; fall back to static text until loaded.
const aiForSign = aiHoroscopes.find((h) => h.signIndex === index);
const generalText = aiForSign?.general || getHoroscope(index).general;
const imageFor = (i: number) => aiHoroscopes.find((h) => h.signIndex === i)?.imageUrl || null;
const currentImage = imageFor(index);
const signPath = (i: number) => `/horoskop/${encodeURIComponent(SIGNS[i].name.toLowerCase())}`;
return (
<div
@ -51,7 +55,7 @@ export function HoroscopeWidget() {
style={{ background: "linear-gradient(135deg, hsl(250 30% 14%), hsl(270 25% 10%))" }}
onMouseEnter={() => setPaused(true)}
onMouseLeave={() => setPaused(false)}
onClick={() => navigate("/horoskop")}
onClick={() => navigate(signPath(index))}
data-testid="widget-horoscope"
>
<div className="p-3 flex items-center justify-between border-b border-white/10 flex-shrink-0">
@ -78,8 +82,18 @@ export function HoroscopeWidget() {
</div>
<div className="flex-1 flex flex-col">
<div className="p-4 flex items-center gap-3">
<div className="w-14 h-14 rounded-xl bg-white/5 border border-white/10 flex items-center justify-center flex-shrink-0">
<span className="text-3xl">{sign.symbol}</span>
<div className="w-14 h-14 rounded-xl bg-white/5 border border-white/10 overflow-hidden flex items-center justify-center flex-shrink-0">
{currentImage ? (
<img
src={currentImage}
alt={`Tageshoroskop ${sign.name}`}
loading="lazy"
className="w-full h-full object-cover"
data-testid="img-widget-horoscope-sign"
/>
) : (
<span className="text-3xl">{sign.symbol}</span>
)}
</div>
<div className="flex-1 min-w-0">
<p className="font-bold text-lg text-white">{sign.name}</p>
@ -107,15 +121,30 @@ export function HoroscopeWidget() {
<p className="text-[10px] text-amber-400 mt-2 group-hover:underline">Mehr lesen</p>
</div>
<div className="flex justify-center gap-1 pb-3">
{SIGNS.map((_, i) => (
<button
key={i}
onClick={(e) => { e.stopPropagation(); setIndex(i); }}
className={`w-1.5 h-1.5 rounded-full transition-all ${i === index ? "bg-amber-400 w-3" : "bg-white/15 hover:bg-white/30"}`}
data-testid={`button-horoscope-dot-${i}`}
/>
))}
<div className="grid grid-cols-6 gap-1 px-2 pb-3">
{SIGNS.map((s, i) => {
const img = imageFor(i);
return (
<button
key={s.name}
title={s.name}
onClick={(e) => { e.stopPropagation(); navigate(signPath(i)); }}
onMouseEnter={() => setIndex(i)}
className={`aspect-square rounded-md overflow-hidden border transition-all flex items-center justify-center ${
i === index
? "border-amber-400 ring-1 ring-amber-400/40"
: "border-white/10 hover:border-white/40 opacity-70 hover:opacity-100"
}`}
data-testid={`button-horoscope-thumb-${s.name.toLowerCase()}`}
>
{img ? (
<img src={img} alt={s.name} loading="lazy" className="w-full h-full object-cover" />
) : (
<span className="text-sm">{s.symbol}</span>
)}
</button>
);
})}
</div>
</div>
</div>

View File

@ -337,7 +337,10 @@ export default function HoroscopePage() {
useEffect(() => {
if (params.sign) {
const idx = SIGNS.findIndex((s) => s.name.toLowerCase() === params.sign?.toLowerCase());
let raw = params.sign;
try { raw = decodeURIComponent(params.sign); } catch { /* ostane surov */ }
const wanted = raw.toLowerCase();
const idx = SIGNS.findIndex((s) => s.name.toLowerCase() === wanted);
if (idx >= 0) setSelected(idx);
}
}, [params.sign]);