/* portal.jsx — zamestnanecký portál: nahlásenie a sledovanie požiadaviek.
   UI podľa dizajnu "Portál pre používateľov.html" (claude.ai/design), napojené na reálnu
   dátovú vrstvu window.PORTAL_API (portal-data.jsx) namiesto lokálnych mock dát — dizajnová
   predloha používala vlastné TIKETY z data.jsx a živý panel na prepínanie tónu/farby/rytmu
   (tweaks-panel.jsx protokol pre nástroj); tu je tón/paleta/rytmus pevne nastavený raz pri
   štarte (žiadny takýto ovládací panel sa zamestnancom nezobrazuje) a dáta idú zo SharePointu. */

function pozdrav() {
  const h = new Date().getHours();
  if (h < 10) return "Dobré ráno";
  if (h < 18) return "Dobrý deň";
  return "Dobrý večer";
}

const PORTAL_KONTAKT = { telefon: "+421 902 122 794", email: "helpdesk@proplusco.sk" };

// Spoločný stav pre výber príloh — použité v NovaPoziadavka aj DetailPoziadavky, aby sa
// tá istá logika (skrytý file input, blocklist prípon cez vyberPrilohy z ui.jsx) nepísala
// dvakrát v tom istom súbore.
function usePortalPrilohy(setChyba) {
  const [prilohy, setPrilohy] = useState([]);
  const fileInputRef = useRef(null);
  const pridatPrilohu = () => fileInputRef.current && fileInputRef.current.click();
  const onFilesVybrane = (e) => { setChyba(""); vyberPrilohy(e, setPrilohy, setChyba); };
  const odobratPrilohu = (id) => setPrilohy((a) => a.filter((x) => x.id !== id));
  return { prilohy, setPrilohy, fileInputRef, pridatPrilohu, onFilesVybrane, odobratPrilohu };
}

/* ====================== HLAVIČKA ====================== */
function PortalHeader({ ja, dark, setDark, onHome, onLogout, onSpatDoAdmin }) {
  return (
    <header style={{ position: "sticky", top: 0, zIndex: 20, background: "var(--surface)", borderBottom: "1px solid var(--stroke)" }}>
      <div style={{ maxWidth: 1080, margin: "0 auto", padding: "0 24px", height: 60, display: "flex", alignItems: "center", gap: 14 }}>
        <button onClick={onHome} style={{ display: "flex", alignItems: "center", gap: 11, border: "none", background: "transparent", padding: 0 }}>
          <span style={{ width: 34, height: 34, borderRadius: 9, background: "var(--accent)", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff" }}><Icon name="mail" size={19} /></span>
          <span style={{ textAlign: "left", lineHeight: 1.15 }}>
            <span style={{ display: "block", fontSize: 15, fontWeight: 700, letterSpacing: "-.01em", color: "var(--text)" }}>Podpora IT</span>
            <span style={{ display: "block", fontSize: 11, color: "var(--text-3)", fontWeight: 600 }}>PROPLUSCO spol. s r. o.</span>
          </span>
        </button>
        <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 6 }}>
          {onSpatDoAdmin && (
            <>
              <span style={{
                display: "inline-flex", alignItems: "center", gap: 5, padding: "4px 9px", borderRadius: 999,
                background: "var(--accent-tint)", color: "var(--accent)", fontSize: 11.5, fontWeight: 700,
              }}><Icon name="person" size={12} /> Náhľad admina</span>
              <Btn kind="subtle" size="sm" onClick={onSpatDoAdmin}>Späť do administrácie</Btn>
              <div style={{ width: 1, height: 22, background: "var(--stroke)", margin: "0 4px" }} />
            </>
          )}
          <IconBtn name={dark ? "sun" : "moon"} title={dark ? "Svetlý režim" : "Tmavý režim"} size={17} onClick={() => setDark(!dark)} />
          <div style={{ width: 1, height: 22, background: "var(--stroke)", margin: "0 4px" }} />
          <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
            <Avatar meno={ja.meno} farba={ja.farba || "var(--accent)"} size={32} photoKey={ja.email} />
            <div className="pf-userbox" style={{ lineHeight: 1.2 }}>
              <div style={{ fontSize: 12.5, fontWeight: 700 }}>{ja.meno}</div>
              <div style={{ fontSize: 11, color: "var(--text-3)", fontWeight: 600 }}>Zamestnanec</div>
            </div>
          </div>
          <IconBtn name="close" title="Odhlásiť sa" size={16} onClick={onLogout} />
        </div>
      </div>
    </header>
  );
}

/* ====================== DOMOV ====================== */
function Domov({ ja, moje, onNovy, onDetail }) {
  const { PODKATEGORIE } = window.HELPDESK_DATA;
  // PODKATEGORIE je pre danú session nemenné (nemení sa počas behu appky) — bez useMemo by
  // sa toto flatMap+filter+map prepočítavalo pri každom prekreslení Domov (napr. pri
  // tichnutí toastu), zbytočne.
  const temy = useMemo(() => Object.keys(PODKATEGORIE).flatMap((k) => PODKATEGORIE[k].filter((t) => t !== "Iné").map((t) => ({ tema: t, kat: k }))), [PODKATEGORIE]);
  const otvorene = moje.filter((t) => !["Vyriešený", "Zatvorený"].includes(t.stav));
  const uzavrete = moje.filter((t) => ["Vyriešený", "Zatvorený"].includes(t.stav));
  const cakaNaMna = otvorene.filter((t) => t.stav === "Čaká na zákazníka").length;
  const [zobrazUzavrete, setZobrazUzavrete] = useState(false);

  return (
    <div className="pf-in">
      <div style={{ background: "var(--surface)", borderBottom: "1px solid var(--stroke)" }}>
        <div style={{ maxWidth: 1080, margin: "0 auto", padding: "var(--pf-hero) 24px calc(var(--pf-hero) * .9)" }}>
          <div style={{ fontSize: 13.5, color: "var(--text-2)", fontWeight: 600, marginBottom: 6 }}>{txt("eyebrow") || pozdrav() + ", " + (ja.meno || "").split(" ")[0]}</div>
          <h1 className="pf-hero-h1" style={{ margin: "0 0 10px", fontSize: "var(--pf-h1)", fontWeight: 700, letterSpacing: "-.025em", lineHeight: 1.15 }}>{txt("heroH1")}</h1>
          <p style={{ margin: "0 0 22px", fontSize: 14.5, color: "var(--text-2)", maxWidth: 560 }}>{txt("heroSub")}</p>
          <div style={{ display: "flex", gap: 10, flexWrap: "wrap", alignItems: "center" }}>
            <Btn kind="orange" icon="send" onClick={() => onNovy(null)}>{txt("ctaNew")}</Btn>
            <span style={{ fontSize: 12.5, color: "var(--text-3)", display: "inline-flex", alignItems: "center", gap: 6 }}>
              <Icon name="clock" size={14} /> {txt("hours")}
            </span>
          </div>
        </div>
      </div>

      <div style={{ maxWidth: 1080, margin: "0 auto", padding: "28px 24px 56px" }}>
        <h2 style={{ margin: "0 0 14px", fontSize: 15, fontWeight: 700 }}>{txt("quickStart")}</h2>
        <div className="pf-cards" style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(178px, 1fr))", gap: "var(--pf-gap)", marginBottom: 36 }}>
          {temy.map((x) => (
            <Tile key={x.tema} kompakt ikona={TEMA_IKONY[x.tema] || "note"} nadpis={x.tema} onClick={() => onNovy(x)} />
          ))}
        </div>

        <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 12, marginBottom: 14, flexWrap: "wrap" }}>
          <h2 style={{ margin: 0, fontSize: 15, fontWeight: 700 }}>
            {txt("myReq")}
            <span style={{ marginLeft: 8, fontSize: 12.5, fontWeight: 600, color: "var(--text-3)" }}>{otvorene.length} otvorených</span>
          </h2>
          {cakaNaMna > 0 && (
            <span style={{ fontSize: 12.5, fontWeight: 600, color: "var(--c-caka)", display: "inline-flex", alignItems: "center", gap: 6 }}>
              <Icon name="warning" size={14} /> {cakaNaMna} čaká na vašu odpoveď
            </span>
          )}
        </div>

        {otvorene.length === 0 ? (
          <div style={{ padding: "36px 24px", textAlign: "center", borderRadius: "var(--radius-lg)", border: "1px dashed var(--stroke-strong)", background: "var(--surface)" }}>
            <div style={{ color: "var(--green)", marginBottom: 8 }}><Icon name="checkCircle" size={28} /></div>
            <div style={{ fontWeight: 700, marginBottom: 4 }}>{txt("emptyT")}</div>
            <div style={{ fontSize: 13, color: "var(--text-2)" }}>{txt("emptyD")}</div>
          </div>
        ) : (
          <div style={{ display: "grid", gap: "var(--pf-gap)" }}>
            {otvorene.map((t) => <PoziadavkaKarta key={t.cislo} t={t} onClick={() => onDetail(t.cislo)} />)}
          </div>
        )}

        {uzavrete.length > 0 && (
          <div style={{ marginTop: 22 }}>
            <button onClick={() => setZobrazUzavrete((v) => !v)} style={{
              display: "inline-flex", alignItems: "center", gap: 7, border: "none", background: "transparent",
              color: "var(--text-2)", fontSize: 13, fontWeight: 600, padding: "6px 0",
            }}>
              <Icon name="chevronDown" size={15} style={{ transform: zobrazUzavrete ? "none" : "rotate(-90deg)", transition: "transform .15s" }} />
              Vyriešené požiadavky ({uzavrete.length})
            </button>
            {zobrazUzavrete && (
              <div style={{ display: "grid", gap: "var(--pf-gap)", marginTop: 10 }} className="pf-in">
                {uzavrete.map((t) => <PoziadavkaKarta key={t.cislo} t={t} onClick={() => onDetail(t.cislo)} />)}
              </div>
            )}
          </div>
        )}

        <div style={{ marginTop: 36, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }} className="pf-2col">
          <div style={{ padding: "16px 18px", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, fontWeight: 700, fontSize: 13.5, marginBottom: 6 }}>
              <Icon name="warning" size={16} style={{ color: "var(--p-vysoka)" }} /> Súrny prípad?
            </div>
            <div style={{ fontSize: 13, color: "var(--text-2)" }}>Ak nemôžete pracovať, volajte na <strong style={{ color: "var(--text)" }}>{PORTAL_KONTAKT.telefon}</strong>.</div>
          </div>
          <div style={{ padding: "16px 18px", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)" }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, fontWeight: 700, fontSize: 13.5, marginBottom: 6 }}>
              <Icon name="mail" size={16} style={{ color: "var(--accent)" }} /> Radšej e-mailom?
            </div>
            <div style={{ fontSize: 13, color: "var(--text-2)" }}>Napíšte na <a href={"mailto:" + PORTAL_KONTAKT.email}>{PORTAL_KONTAKT.email}</a> — požiadavka sa založí automaticky.</div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ====================== NOVÁ POŽIADAVKA ====================== */
function NovaPoziadavka({ ja, prednastavena, onSpat, onOdoslat }) {
  const { PODKATEGORIE } = window.HELPDESK_DATA;
  const [kat, setKat] = useState(prednastavena ? prednastavena.kat : null);
  const [tema, setTema] = useState(prednastavena ? prednastavena.tema : null);
  const [predmet, setPredmet] = useState("");
  const [popis, setPopis] = useState("");
  const [naliehavost, setNaliehavost] = useState("Stredná");
  const [tykaSa, setTykaSa] = useState([]);
  const [chyby, setChyby] = useState({});
  const [odosielam, setOdosielam] = useState(false);
  const [chybaOdoslania, setChybaOdoslania] = useState("");
  const { prilohy, fileInputRef, pridatPrilohu, onFilesVybrane, odobratPrilohu } = usePortalPrilohy(setChybaOdoslania);

  const rady = tema && RADY[tema] ? RADY[tema] : [];

  const odoslat = async () => {
    const c = {};
    if (!kat || !tema) c.tema = "Vyberte, čoho sa problém týka.";
    if (predmet.trim().length < 4) c.predmet = "Napíšte krátky výstižný nadpis.";
    if (popis.trim().length < 10) c.popis = "Opíšte problém aspoň jednou vetou — pomôže nám to rýchlejšie pomôcť.";
    setChyby(c);
    if (Object.keys(c).length || odosielam) return;
    setOdosielam(true);
    setChybaOdoslania("");
    try {
      await onOdoslat({ kategoria: kat, podkategoria: tema, predmet: predmet.trim(), popis: popis.trim(), priorita: naliehavost, prilohy, tykaSa });
    } catch (e) {
      setChybaOdoslania(e.message || "Odoslanie zlyhalo, skúste to prosím znova.");
      setOdosielam(false);
    }
  };

  const labelStyl = { fontSize: 13.5, fontWeight: 700, marginBottom: 8, display: "block" };
  const inputStyl = (chyba) => ({
    width: "100%", padding: "10px 12px", borderRadius: "var(--radius)", background: "var(--surface)", color: "var(--text)",
    border: "1px solid " + (chyba ? "var(--red)" : "var(--stroke-strong)"), fontSize: 14, outline: "none", fontFamily: "inherit",
  });
  const Chyba = ({ text }) => text ? (
    <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--red)", marginTop: 6 }}>
      <Icon name="warning" size={14} /> {text}
    </div>
  ) : null;

  return (
    <div className="pf-in" style={{ maxWidth: 1080, margin: "0 auto", padding: "22px 24px 56px" }}>
      <button onClick={onSpat} style={{ display: "inline-flex", alignItems: "center", gap: 6, border: "none", background: "transparent", color: "var(--text-2)", fontSize: 13, fontWeight: 600, padding: "6px 0", marginBottom: 14 }}>
        <Icon name="chevron" size={16} style={{ transform: "scaleX(-1)" }} /> Späť
      </button>

      <h1 style={{ margin: "0 0 6px", fontSize: 26, fontWeight: 700, letterSpacing: "-.02em" }}>{txt("formH1")}</h1>
      <p style={{ margin: "0 0 26px", fontSize: 14, color: "var(--text-2)" }}>{txt("formSub")}</p>

      <div style={{ display: "grid", gridTemplateColumns: "minmax(0,1.6fr) minmax(0,1fr)", gap: 24, alignItems: "start" }} className="pf-2col">
        <div>
          <section style={{ marginBottom: 26 }}>
            <span style={labelStyl}><span style={{ color: "var(--accent)" }}>1.</span> {txt("q1")}</span>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))", gap: 10, marginBottom: 12 }}>
              {Object.keys(PODKATEGORIE).map((k) => (
                <Tile key={k} kompakt ikona={KAT_IKONY[k] || "note"} nadpis={k} aktivna={kat === k}
                  onClick={() => { setKat(k); setTema(PODKATEGORIE[k][0]); setChyby((c) => ({ ...c, tema: null })); }} />
              ))}
            </div>
            {kat && (
              <div style={{ display: "flex", flexWrap: "wrap", gap: 8 }} className="pf-in">
                {PODKATEGORIE[kat].map((t) => {
                  const a = tema === t;
                  return (
                    <button key={t} onClick={() => setTema(t)} style={{
                      display: "inline-flex", alignItems: "center", gap: 7, padding: "7px 13px", borderRadius: 999, fontSize: 13, fontWeight: 600,
                      border: "1px solid " + (a ? "transparent" : "var(--stroke-strong)"),
                      background: a ? "var(--accent)" : "var(--surface)", color: a ? "#fff" : "var(--text-2)",
                    }}>
                      <Icon name={TEMA_IKONY[t] || "note"} size={14} /> {t}
                    </button>
                  );
                })}
              </div>
            )}
            <Chyba text={chyby.tema} />
          </section>

          <section style={{ marginBottom: 26 }}>
            <span style={labelStyl}><span style={{ color: "var(--accent)" }}>2.</span> {txt("q2")}</span>
            <input value={predmet} onChange={(e) => { setPredmet(e.target.value); setChyby((c) => ({ ...c, predmet: null })); }}
              placeholder="Krátky nadpis — napr. „Tlačiareň na 2. poschodí netlačí“" style={{ ...inputStyl(chyby.predmet), marginBottom: 4 }} />
            <Chyba text={chyby.predmet} />
            <textarea value={popis} onChange={(e) => { setPopis(e.target.value); setChyby((c) => ({ ...c, popis: null })); }}
              rows={5} placeholder="Popíšte, čo ste robili, čo sa stalo a čo ste už skúsili. Ak sa zobrazila chybová hláška, uveďte jej text."
              style={{ ...inputStyl(chyby.popis), marginTop: 10, resize: "vertical", minHeight: 110, lineHeight: 1.55 }} />
            <Chyba text={chyby.popis} />
            <div style={{ fontSize: 12, color: "var(--text-3)", marginTop: 8, display: "flex", alignItems: "center", gap: 6 }}>
              <Icon name="note" size={13} /> {txt("tip")}
            </div>
          </section>

          <section style={{ marginBottom: 26 }}>
            <span style={labelStyl}><span style={{ color: "var(--accent)" }}>3.</span> {txt("q3")}</span>
            <div style={{ display: "grid", gap: 8 }}>
              {naliehavosti().map((n) => {
                const a = naliehavost === n.id;
                return (
                  <button key={n.id} onClick={() => setNaliehavost(n.id)} style={{
                    display: "flex", alignItems: "flex-start", gap: 12, padding: "13px 15px", borderRadius: "var(--radius)", textAlign: "left",
                    background: a ? "var(--accent-tint)" : "var(--surface)",
                    border: "1px solid " + (a ? "color-mix(in srgb, var(--accent) 42%, transparent)" : "var(--stroke)"),
                  }}>
                    <span style={{
                      width: 18, height: 18, borderRadius: "50%", flex: "0 0 auto", marginTop: 1,
                      border: "2px solid " + (a ? "var(--accent)" : "var(--stroke-strong)"),
                      background: a ? "var(--accent)" : "transparent", display: "flex", alignItems: "center", justifyContent: "center",
                    }}>{a && <span style={{ width: 6, height: 6, borderRadius: "50%", background: "#fff" }} />}</span>
                    <span>
                      <span style={{ display: "block", fontSize: 13.5, fontWeight: 700, marginBottom: 2 }}>{n.nadpis}</span>
                      <span style={{ display: "block", fontSize: 12.5, color: "var(--text-2)" }}>{n.popis}</span>
                    </span>
                  </button>
                );
              })}
            </div>
          </section>

          <section style={{ marginBottom: 28 }}>
            <span style={labelStyl}><span style={{ color: "var(--accent)" }}>4.</span> Priložiť obrázok alebo súbor <span style={{ fontWeight: 600, color: "var(--text-3)" }}>(nepovinné)</span></span>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center" }}>
              {prilohy.map((p) => <AttachChip key={p.id} p={p} onRemove={() => odobratPrilohu(p.id)} />)}
              <input ref={fileInputRef} type="file" multiple onChange={onFilesVybrane} style={{ display: "none" }} />
              <Btn kind="default" size="sm" icon="paperclip" onClick={pridatPrilohu} disabled={odosielam}>Pridať súbor</Btn>
            </div>
            <div style={{ fontSize: 12, color: "var(--text-3)", marginTop: 8 }}>Snímka obrazovky pomôže najviac — stlačte <strong style={{ color: "var(--text-2)" }}>Win + Shift + S</strong>.</div>
          </section>

          <section style={{ marginBottom: 28 }}>
            <span style={labelStyl}>Týka sa to aj niekoho ďalšieho? <span style={{ fontWeight: 600, color: "var(--text-3)" }}>(nepovinné)</span></span>
            <PersonChips hodnoty={tykaSa} onZmena={setTykaSa} placeholder="Meno kolegu…" m365 hladaj={window.PORTAL_API.hladajOsoby} />
            <div style={{ fontSize: 12, color: "var(--text-3)", marginTop: 8 }}>Pridaný kolega uvidí túto požiadavku vo svojom portáli a môže na ňu tiež odpovedať.</div>
          </section>

          {chybaOdoslania && (
            <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--red)", marginBottom: 14 }}>
              <Icon name="warning" size={14} /> {chybaOdoslania}
            </div>
          )}

          <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
            <Btn kind="primary" icon="send" onClick={odoslat} disabled={odosielam}>{odosielam ? "Odosielam…" : txt("submit")}</Btn>
            <Btn kind="subtle" onClick={onSpat} disabled={odosielam}>Zrušiť</Btn>
          </div>
        </div>

        <aside style={{ display: "grid", gap: 12, position: "sticky", top: 76 }}>
          <div style={{ padding: "16px 18px", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)" }}>
            <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 12 }}>{txt("next")}</div>
            {[
              { i: "checkCircle", t: "Potvrdíme prijatie", d: "Hneď po odoslaní dostanete číslo požiadavky." },
              { i: "person", t: "Prevezme to technik", d: "Bežne do 2 hodín v pracovnom čase." },
              { i: "mail", t: "Ozveme sa vám", d: "E-mailom aj tu v portáli — môžete odpovedať." },
            ].map((x, i) => (
              <div key={i} style={{ display: "flex", gap: 11, marginBottom: i < 2 ? 14 : 0 }}>
                <span style={{ width: 28, height: 28, borderRadius: "50%", flex: "0 0 auto", display: "flex", alignItems: "center", justifyContent: "center", background: "color-mix(in srgb, var(--accent) 12%, transparent)", color: "var(--accent)" }}><Icon name={x.i} size={15} /></span>
                <span>
                  <span style={{ display: "block", fontSize: 13, fontWeight: 700 }}>{x.t}</span>
                  <span style={{ display: "block", fontSize: 12.5, color: "var(--text-2)" }}>{x.d}</span>
                </span>
              </div>
            ))}
          </div>

          {rady.length > 0 && (
            <div className="pf-in" style={{ padding: "16px 18px", borderRadius: "var(--radius-lg)", background: "var(--warn-tint)", border: "1px solid color-mix(in srgb, var(--p-vysoka) 26%, transparent)" }}>
              <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 10, display: "flex", alignItems: "center", gap: 7, color: "var(--p-vysoka)" }}>
                <Icon name="note" size={16} /> Možno to vyriešite hneď
              </div>
              {rady.map((r, i) => (
                <div key={i} style={{ marginBottom: i < rady.length - 1 ? 12 : 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 700, marginBottom: 2 }}>{r.t}</div>
                  <div style={{ fontSize: 12.5, color: "var(--text-2)" }}>{r.d}</div>
                </div>
              ))}
            </div>
          )}
        </aside>
      </div>
    </div>
  );
}

/* ====================== POTVRDENIE ====================== */
function Potvrdenie({ ja, cislo, onDetail, onHome }) {
  return (
    <div className="pf-in" style={{ maxWidth: 560, margin: "0 auto", padding: "72px 24px", textAlign: "center" }}>
      <div style={{ width: 76, height: 76, borderRadius: "50%", margin: "0 auto 20px", background: "color-mix(in srgb, var(--green) 14%, transparent)", display: "flex", alignItems: "center", justifyContent: "center", animation: "pf-pop .3s ease" }}>
        <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="var(--green)" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M4 12.5 9.5 18 20 6.5" style={{ strokeDasharray: 48, animation: "pf-check .45s ease .1s both" }} />
        </svg>
      </div>
      <h1 style={{ margin: "0 0 10px", fontSize: 24, fontWeight: 700, letterSpacing: "-.02em" }}>{txt("okH1")}</h1>
      <p style={{ margin: "0 0 6px", fontSize: 14.5, color: "var(--text-2)" }}>{txt("okSub")}</p>
      <div style={{ fontSize: 22, fontWeight: 700, color: "var(--accent)", letterSpacing: "-.01em", marginBottom: 18, fontVariantNumeric: "tabular-nums" }}>{cislo}</div>
      <p style={{ margin: "0 0 26px", fontSize: 13.5, color: "var(--text-2)" }}>Potvrdenie sme poslali aj na <strong style={{ color: "var(--text)" }}>{ja.email}</strong>. Technik sa vám ozve bežne do 2 hodín.</p>
      <div style={{ display: "flex", gap: 10, justifyContent: "center", flexWrap: "wrap" }}>
        <Btn kind="primary" onClick={onDetail}>Zobraziť požiadavku</Btn>
        <Btn kind="default" onClick={onHome}>Späť na prehľad</Btn>
      </div>
    </div>
  );
}

/* ====================== TÝKA SA (pridanie ďalšej osoby) ====================== */
function TykaSaSekcia({ t, onZmena }) {
  const [chyba, setChyba] = useState("");
  const zmen = async (arr) => {
    setChyba("");
    try { await onZmena(arr); } catch (e) { setChyba(e.message || "Nepodarilo sa uložiť."); }
  };
  return (
    <div style={{ padding: "var(--pf-card-pad)", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)", marginBottom: 12 }}>
      <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 6 }}>Týka sa aj</div>
      <div style={{ fontSize: 12.5, color: "var(--text-2)", marginBottom: 12 }}>Pridaná osoba uvidí túto požiadavku vo svojom portáli a môže na ňu tiež odpovedať.</div>
      <PersonChips hodnoty={t.tykaSa || []} onZmena={zmen} placeholder="Pridať kolegu…" m365 hladaj={window.PORTAL_API.hladajOsoby} />
      {chyba && (
        <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--red)", marginTop: 8 }}>
          <Icon name="warning" size={14} /> {chyba}
        </div>
      )}
    </div>
  );
}

/* ====================== DETAIL POŽIADAVKY ====================== */
function DetailPoziadavky({ t, ja, onSpat, onOdpovedat, onPotvrdit, onZnovu, onSpokojnost, onZmenaTykaSa }) {
  const [text, setText] = useState("");
  const [hodnotenie, setHodnotenie] = useState(null);
  const [odosielam, setOdosielam] = useState(false);
  const [akcia, setAkcia] = useState(""); // "" | "potvrdit" | "znovu"
  const [chyba, setChyba] = useState("");
  const { prilohy, setPrilohy, fileInputRef, pridatPrilohu, onFilesVybrane, odobratPrilohu } = usePortalPrilohy(setChyba);
  const info = stavInfo(t.stav);
  const hotovo = ["Vyriešený", "Zatvorený"].includes(t.stav);
  // Interné poznámky sú odfiltrované už na dátovej vrstve (portal-data.jsx) — tento filter
  // je zámerná druhá poistka, nie jediná ochrana. Reset text/prilohy/hodnotenie/akcia pri
  // zmene tiketu rieši key={t.cislo} na tomto komponente v PortalApp (celý remount), nie
  // ručný reset efekt — bez key by hodnotenie z jedného tiketu "prekleslo" do ďalšieho.
  const viditelne = t.komunikacia.filter((m) => m.typ !== "Interná poznámka" && m.typ !== "Systémová udalosť");

  const odoslatOdpoved = async () => {
    const v = text.trim();
    if (!v || odosielam) return;
    setOdosielam(true);
    setChyba("");
    try {
      await onOdpovedat(v, prilohy);
      setText(""); setPrilohy([]);
    } catch (e) {
      setChyba(e.message || "Odoslanie zlyhalo, skúste to prosím znova.");
    } finally {
      setOdosielam(false);
    }
  };

  const klikPotvrdit = async () => {
    if (akcia) return;
    setAkcia("potvrdit"); setChyba("");
    try { await onPotvrdit(); } catch (e) { setChyba(e.message || "Potvrdenie zlyhalo."); } finally { setAkcia(""); }
  };
  const klikZnovu = async () => {
    if (akcia) return;
    setAkcia("znovu"); setChyba("");
    try { await onZnovu(); } catch (e) { setChyba(e.message || "Odoslanie zlyhalo."); } finally { setAkcia(""); }
  };
  const klikHodnotenie = (id) => {
    setHodnotenie(id);
    onSpokojnost(id).catch(() => {}); // best-effort, neblokuje UI
  };

  return (
    <div className="pf-in" style={{ maxWidth: 780, margin: "0 auto", padding: "22px 24px 56px" }}>
      <button onClick={onSpat} style={{ display: "inline-flex", alignItems: "center", gap: 6, border: "none", background: "transparent", color: "var(--text-2)", fontSize: 13, fontWeight: 600, padding: "6px 0", marginBottom: 14 }}>
        <Icon name="chevron" size={16} style={{ transform: "scaleX(-1)" }} /> Moje požiadavky
      </button>

      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 8, flexWrap: "wrap" }}>
        <span style={{ fontSize: 12.5, color: "var(--text-3)", fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{t.cislo}</span>
        <span style={{ fontSize: 12.5, color: "var(--text-3)" }}>· nahlásené {fmtDateTime(t.vytvorene)}</span>
      </div>
      <h1 style={{ margin: "0 0 20px", fontSize: 24, fontWeight: 700, letterSpacing: "-.02em", lineHeight: 1.25 }}>{t.predmet}</h1>

      <div style={{ padding: "var(--pf-card-pad)", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)", marginBottom: 12 }}>
        <Stepper stav={t.stav} />
        <div style={{ marginTop: 16, paddingTop: 14, borderTop: "1px solid var(--stroke)", display: "flex", gap: 11, alignItems: "flex-start" }}>
          <span style={{ color: info.farba, display: "inline-flex", marginTop: 1 }}><Icon name={hotovo ? "checkCircle" : "clock"} size={17} /></span>
          <div>
            <div style={{ fontSize: 13.5, color: "var(--text)", fontWeight: 600 }}>{info.pop}</div>
            {t.technik && !hotovo && (
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 10 }}>
                <Avatar meno={t.technik} farba="var(--accent)" size={26} />
                <span style={{ fontSize: 12.5, color: "var(--text-2)" }}>Vašu požiadavku rieši <strong style={{ color: "var(--text)" }}>{t.technik}</strong></span>
              </div>
            )}
          </div>
        </div>
      </div>

      <TykaSaSekcia t={t} onZmena={onZmenaTykaSa} />

      <div style={{ padding: "var(--pf-card-pad)", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)", marginBottom: 12 }}>
        <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 16 }}>Priebeh komunikácie</div>
        {viditelne.length === 0 ? (
          <div style={{ fontSize: 13, color: "var(--text-3)" }}>Zatiaľ žiadna komunikácia.</div>
        ) : (
          <div style={{ display: "grid", gap: 18 }}>
            {viditelne.map((m) => {
              const odoMna = m.typ === "Prijatý e-mail" || m.typ === "Odpoveď zákazníka";
              return (
                <div key={m.id} style={{ display: "flex", gap: 12 }}>
                  {/* photoKey priamo z e-mailu (nie hľadanie podľa mena) — dôležité najmä keď
                      raz na tiket pribudnú ďalší ľudia okrem žiadateľa, nech sa dajú vo
                      vlákne navzájom spoľahlivo rozoznať aj vizuálne, nielen menom. */}
                  <Avatar meno={m.autor} farba={odoMna ? (ja.farba || "var(--accent)") : "var(--p-stred)"} size={32} photoKey={m.autorEmail || null} />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 5, flexWrap: "wrap" }}>
                      <span style={{ fontSize: 13.5, fontWeight: 700 }}>{odoMna ? "Vy" : m.autor}</span>
                      {!odoMna && <span style={{ fontSize: 11.5, color: "var(--text-3)", fontWeight: 600 }}>IT podpora</span>}
                      <span style={{ marginLeft: "auto", fontSize: 11.5, color: "var(--text-3)" }}>{fmtDateTime(m.cas)}</span>
                    </div>
                    <div style={{
                      padding: "12px 14px", borderRadius: "var(--radius)", fontSize: 13.5, lineHeight: 1.55, whiteSpace: "pre-wrap", wordBreak: "break-word",
                      background: odoMna ? "var(--surface-2)" : "var(--accent-tint)",
                      border: "1px solid " + (odoMna ? "var(--stroke)" : "color-mix(in srgb, var(--accent) 20%, transparent)"),
                    }}>
                      {m.text}
                      {m.prilohy && m.prilohy.length > 0 && (
                        <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginTop: 12 }}>
                          {m.prilohy.map((p, i) => <AttachChip key={i} p={p} />)}
                        </div>
                      )}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {hotovo ? (
        <div style={{ padding: "var(--pf-card-pad)", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid var(--stroke)" }}>
          {t.stav === "Vyriešený" ? (
            <>
              <div style={{ fontSize: 14.5, fontWeight: 700, marginBottom: 6 }}>{txt("doneQ")}</div>
              <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 16 }}>{txt("doneD")}</div>
              <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
                <Btn kind="green" icon="check" onClick={klikPotvrdit} disabled={!!akcia}>{akcia === "potvrdit" ? "Potvrdzujem…" : txt("doneYes")}</Btn>
                <Btn kind="default" icon="reopen" onClick={klikZnovu} disabled={!!akcia}>{akcia === "znovu" ? "Odosielam…" : "Problém pretrváva"}</Btn>
              </div>
            </>
          ) : (
            <>
              <div style={{ display: "flex", alignItems: "center", gap: 9, fontSize: 14, fontWeight: 700, marginBottom: 14, color: "var(--green)" }}>
                <Icon name="checkCircle" size={18} /> Požiadavka je uzavretá
              </div>
              <div style={{ fontSize: 13.5, color: "var(--text-2)", marginBottom: 12 }}>Ako ste boli spokojní s riešením?</div>
              <div style={{ display: "flex", gap: 8, flexWrap: "wrap" }}>
                {[{ id: "dobre", t: "Spokojný", i: "checkCircle", c: "var(--green)" }, { id: "ok", t: "Dalo sa", i: "dot", c: "var(--p-vysoka)" }, { id: "zle", t: "Nespokojný", i: "warning", c: "var(--red)" }].map((o) => {
                  const a = hodnotenie === o.id;
                  return (
                    <button key={o.id} onClick={() => klikHodnotenie(o.id)} disabled={!!hodnotenie} style={{
                      display: "inline-flex", alignItems: "center", gap: 7, padding: "9px 15px", borderRadius: 999, fontSize: 13, fontWeight: 600,
                      border: "1px solid " + (a ? o.c : "var(--stroke-strong)"), color: a ? o.c : "var(--text-2)",
                      background: a ? "color-mix(in srgb, " + o.c + " 12%, transparent)" : "var(--surface)",
                      opacity: hodnotenie && !a ? 0.5 : 1,
                    }}><Icon name={o.i} size={15} /> {o.t}</button>
                  );
                })}
              </div>
              {hodnotenie && <div className="pf-in" style={{ fontSize: 12.5, color: "var(--text-3)", marginTop: 12 }}>Ďakujeme za spätnú väzbu — pomáha nám zlepšovať sa.</div>}
            </>
          )}
        </div>
      ) : (
        <div style={{ padding: "18px 20px", borderRadius: "var(--radius-lg)", background: "var(--surface)", border: "1px solid " + (t.stav === "Čaká na zákazníka" ? "color-mix(in srgb, var(--c-caka) 45%, transparent)" : "var(--stroke)") }}>
          <div style={{ fontSize: 13.5, fontWeight: 700, marginBottom: 10 }}>
            {t.stav === "Čaká na zákazníka" ? "Technik čaká na vašu odpoveď" : "Chcete niečo doplniť?"}
          </div>
          <textarea value={text} onChange={(e) => setText(e.target.value)} rows={3} placeholder="Napíšte odpoveď technikovi… (Enter odošle, Shift+Enter nový riadok)"
            onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); odoslatOdpoved(); } }}
            style={{ width: "100%", padding: "11px 13px", borderRadius: "var(--radius)", border: "1px solid var(--stroke-strong)", background: "var(--surface-2)", color: "var(--text)", fontSize: 13.5, lineHeight: 1.55, resize: "vertical", minHeight: 84, outline: "none", fontFamily: "inherit" }} />
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 10, flexWrap: "wrap" }}>
            {prilohy.map((p) => <AttachChip key={p.id} p={p} onRemove={() => odobratPrilohu(p.id)} />)}
            <input ref={fileInputRef} type="file" multiple onChange={onFilesVybrane} style={{ display: "none" }} />
            <Btn kind="subtle" size="sm" icon="paperclip" onClick={pridatPrilohu} disabled={odosielam}>Priložiť</Btn>
            <div style={{ marginLeft: "auto" }}>
              <Btn kind="primary" icon="send" disabled={!text.trim() || odosielam} onClick={odoslatOdpoved}>{odosielam ? "Odosielam…" : "Odoslať odpoveď"}</Btn>
            </div>
          </div>
        </div>
      )}

      {chyba && (
        <div style={{ marginTop: 12, display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: "var(--red)" }}>
          <Icon name="warning" size={14} /> {chyba}
        </div>
      )}
    </div>
  );
}

/* ====================== APP ====================== */
function PortalApp({ ja, onLogout, onSpatDoAdmin }) {
  const [dark, setDarkState] = useState(() => localStorage.getItem("hd_portal_dark") === "1");
  const setDark = (v) => { setDarkState(v); localStorage.setItem("hd_portal_dark", v ? "1" : "0"); };
  useEffect(() => { applyPortalTheme({ ...PORTAL_DEFAULT_TEMA, dark }); }, [dark]);

  // Technický workspace je fixný na 100vh s vlastným vnútorným skrolovaním panelov (preto
  // body/#root majú v HTML globálne overflow:hidden) — portál je ale bežná stránka, ktorá
  // má rásť podľa obsahu a skrolovať sa celá. Trieda sa odstráni pri odmountovaní, aby sa
  // po odhlásení/prepnutí naspäť na technický workspace nič nezmenilo.
  useEffect(() => {
    document.body.classList.add("pf-scroll");
    return () => { document.body.classList.remove("pf-scroll"); };
  }, []);

  const [moje, setMoje] = useState([]);
  const [nacitavam, setNacitavam] = useState(true);
  // Bez tohto by zlyhanie GET /api/portal/tikety (napr. chýbajúci GRAPH_CLIENT_SECRET vo
  // Worker-i) vyzeralo pre zamestnanca úplne rovnako ako "nemáš žiadne požiadavky" — ticho
  // zahodená chyba, žiadny signál, že niečo naozaj nefunguje.
  const [chybaNacitania, setChybaNacitania] = useState("");
  const [pohlad, setPohlad] = useState("home"); // home | novy | potvrdenie | detail
  const [aktivne, setAktivne] = useState(null);
  const [prednastavena, setPrednastavena] = useState(null);
  const [poslednaSprava, setPoslednaSprava] = useState(null);

  const nacitaj = useCallback(
    () => window.PORTAL_API.loadMoje(ja).then((data) => { setMoje(data); setChybaNacitania(""); }),
    [ja]
  );
  useEffect(() => {
    nacitaj()
      .catch((e) => setChybaNacitania(e.message || "Nepodarilo sa načítať vaše požiadavky."))
      .finally(() => setNacitavam(false));
  }, [nacitaj]);

  // Zámerne NEvolá reloadData (Root) — pre zamestnanca je window.HELPDESK_DATA len statická
  // konštanta (HELPDESK_STATICKE), niet čo v nej obnovovať. Volanie reloadData by navyše
  // spustilo Rootov "sonda, či som technik" krok znova pri KAŽDOM tichom obnovení (každých
  // 60s aj pri návrate do okna) — a keby si ten technický Graph token medzitým vyžadoval
  // interaktívne obnovenie, auth.jsx presmeruje CELÚ stránku preč (acquireTokenRedirect),
  // hoci išlo len o zahodený tichý pokus. Reálne dáta portálu ťahá len nacitaj() nižšie.
  // Tichý — na rozdiel od počiatočného nacitaj() v mount efekte vyššie zámerne bez
  // zobrazenia chyby: výpadok jedného 60s obnovenia uprostred práce nemá zamestnancovi
  // vyskočiť ako banner, len sa potichu skúsi nabudúce (rovnaký princíp ako na technickej
  // strane). .catch() tu je len proti nezachytenej Promise rejection v konzole.
  const obnov = useCallback(() => nacitaj().catch(() => {}), [nacitaj]);

  // Tichý auto-refresh — rovnaký vzor ako technická strana (App v app.jsx).
  useEffect(() => {
    const id = setInterval(() => { if (!document.hidden) obnov(); }, 60000);
    const onVisible = () => { if (!document.hidden) obnov(); };
    document.addEventListener("visibilitychange", onVisible);
    return () => { clearInterval(id); document.removeEventListener("visibilitychange", onVisible); };
  }, [obnov]);

  useEffect(() => { window.scrollTo(0, 0); }, [pohlad, aktivne]);

  const tiket = moje.find((t) => t.cislo === aktivne);
  const patch = (cislo, p) => setMoje((arr) => arr.map((t) => t.cislo === cislo ? { ...t, ...(typeof p === "function" ? p(t) : p) } : t));
  const flash = (text) => { setPoslednaSprava(text); setTimeout(() => setPoslednaSprava(null), 3000); };

  const ideNaDomov = () => { setPohlad("home"); setAktivne(null); };

  const odoslatNovu = async (f) => {
    const cislo = await window.PORTAL_API.vytvorTiket(ja, f);
    // Navigácia na potvrdenie NESMIE čakať na reload — tiket už reálne existuje, takže
    // zlyhanie reloadu (výpadok siete a pod.) by inak zamestnancovi ukázalo "Odoslanie
    // zlyhalo" a zvábilo ho odoslať to isté ešte raz (duplicitný tiket). Lokálny optimistický
    // záznam navyše ukáže práve priloženú prílohu hneď — mapSprava (data.jsx) prílohy
    // jednotlivých správ zatiaľ nesťahuje, takže po reloade na pozadí zase zmiznú z
    // pohľadu (existujúci limit celej appky, nielen portálu — má ho aj technická strana).
    const optimisticky = {
      _spItemId: null, cislo, predmet: f.predmet, stav: "Nový", priorita: f.priorita,
      kategoria: f.kategoria, podkategoria: f.podkategoria, technik: null,
      vytvorene: Date.now(), vyriesene: null, tykaSa: f.tykaSa || [],
      komunikacia: [{
        id: "lokalny_" + cislo, typ: "Odpoveď zákazníka", autor: ja.meno, autorEmail: ja.email, cas: Date.now(), text: f.popis,
        prilohy: (f.prilohy || []).map((p) => ({ nazov: p.nazov, velkost: p.velkost, typ: p.typ })),
      }],
    };
    setMoje((arr) => [optimisticky, ...arr]);
    setAktivne(cislo);
    setPohlad("potvrdenie");
    nacitaj().catch(() => {});
  };

  const odpovedat = async (text, prilohy) => {
    const nova = await window.PORTAL_API.posliOdpoved(ja, tiket, text, prilohy);
    patch(tiket.cislo, (t) => ({
      stav: t.stav === "Čaká na zákazníka" ? "V riešení" : t.stav,
      komunikacia: [...t.komunikacia, nova],
    }));
    flash("Odpoveď bola odoslaná technikovi");
  };

  const potvrditVyriesenie = async () => {
    await window.PORTAL_API.potvrditVyriesenie(ja, tiket);
    patch(tiket.cislo, { stav: "Zatvorený" });
    flash("Ďakujeme, požiadavku sme uzavreli");
  };

  const oznamitPretrvava = async () => {
    await window.PORTAL_API.oznamitPretrvava(ja, tiket);
    // vyriesene: undefined presne zrkadlí server (portal-data.jsx oznamitPretrvava čistí
    // DatumVyriesenia) — bez toho by lokálny stav a SharePoint dočasne (do budúceho
    // reloadu) rozišli.
    patch(tiket.cislo, { stav: "V riešení", vyriesene: undefined });
    flash("Dali sme technikovi vedieť, že problém pretrváva");
  };

  const zaznamenajSpokojnost = (hodnotenie) => window.PORTAL_API.zaznamenajSpokojnost(ja, tiket, hodnotenie);

  const zmenTykaSa = async (mena) => {
    const res = await window.PORTAL_API.nastavTykaSa(ja, tiket, mena);
    patch(tiket.cislo, { tykaSa: res.tykaSa });
  };

  if (nacitavam) return <ProplusoLoader text="Načítavam vaše požiadavky…" />;

  // Zlyhanie počiatočného načítania (napr. Worker bez GRAPH_CLIENT_SECRET) sa NESMIE
  // ukázať ako "0 otvorených požiadaviek" — to by vyzeralo, že zamestnanec proste nemá
  // žiadne tikety, hoci appka v skutočnosti vôbec nevie, koľko ich má.
  if (chybaNacitania && moje.length === 0) {
    return (
      <div style={{ height: "100vh", display: "flex", alignItems: "center", justifyContent: "center", padding: 24 }}>
        <div style={{ maxWidth: 420, textAlign: "center" }}>
          <div style={{ color: "var(--red)", marginBottom: 12 }}><Icon name="warning" size={32} /></div>
          <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 8 }}>Nepodarilo sa načítať vaše požiadavky</div>
          <div style={{ fontSize: 13, color: "var(--text-2)", marginBottom: 18 }}>{chybaNacitania}</div>
          <Btn kind="primary" icon="refresh" onClick={() => { setNacitavam(true); nacitaj().catch((e) => setChybaNacitania(e.message)).finally(() => setNacitavam(false)); }}>Skúsiť znova</Btn>
        </div>
      </div>
    );
  }

  return (
    <div>
      <PortalHeader ja={ja} dark={dark} setDark={setDark} onHome={ideNaDomov} onLogout={onLogout} onSpatDoAdmin={onSpatDoAdmin} />
      {pohlad === "home" && <Domov ja={ja} moje={moje} onNovy={(p) => { setPrednastavena(p); setPohlad("novy"); }} onDetail={(c) => { setAktivne(c); setPohlad("detail"); }} />}
      {pohlad === "novy" && <NovaPoziadavka ja={ja} prednastavena={prednastavena} onSpat={ideNaDomov} onOdoslat={odoslatNovu} />}
      {pohlad === "potvrdenie" && <Potvrdenie ja={ja} cislo={aktivne} onDetail={() => setPohlad("detail")} onHome={ideNaDomov} />}
      {pohlad === "detail" && tiket && (
        // key={t.cislo}: pri prepnutí na iný tiket sa má DetailPoziadavky vždy vykresliť
        // "od nuly" — bez toho by lokálny stav (hodnotenie spokojnosti, prebiehajúca akcia
        // potvrdiť/znovuotvoriť) prežil medzi rôznymi tiketmi a nový tiket by sa zobrazil,
        // akoby už mal odoslanú spätnú väzbu alebo zablokované tlačidlá.
        <DetailPoziadavky key={tiket.cislo} t={tiket} ja={ja} onSpat={ideNaDomov} onOdpovedat={odpovedat}
          onPotvrdit={potvrditVyriesenie} onZnovu={oznamitPretrvava} onSpokojnost={zaznamenajSpokojnost} onZmenaTykaSa={zmenTykaSa} />
      )}
      {pohlad === "detail" && !tiket && <CentrovanaSprava text="Táto požiadavka sa nenašla." />}
      {poslednaSprava && (
        <div style={{ position: "fixed", bottom: 22, left: "50%", transform: "translateX(-50%)", zIndex: 200, display: "flex", alignItems: "center", gap: 10, padding: "11px 18px", borderRadius: "var(--radius)", background: "var(--surface)", border: "1px solid var(--stroke)", boxShadow: "var(--shadow-lg)", fontSize: 13.5, fontWeight: 600, animation: "pf-fade .2s ease" }}>
          <Icon name="checkCircle" size={18} style={{ color: "var(--green)" }} /> {poslednaSprava}
        </div>
      )}
    </div>
  );
}

window.PortalApp = PortalApp;
