Horoskop widget na naslovnici: slikce znamenj + povezava na znamenje
This commit is contained in:
parent
68fe291b55
commit
3c6079d720
@ -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>
|
||||
|
||||
@ -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]);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user