update
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e469]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e469]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 594 KiB |
@@ -0,0 +1,369 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- button "Otevřít navigaci" [ref=e12]:
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,369 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- button "Otevřít navigaci" [ref=e12]:
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 146 KiB |
@@ -0,0 +1,458 @@
|
|||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- banner:
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic: M
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub
|
||||||
|
- generic: klubový web a provoz v jednom
|
||||||
|
- generic:
|
||||||
|
- button [expanded]:
|
||||||
|
- img
|
||||||
|
- main:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic:
|
||||||
|
- heading [level=1]: Jeden systém pro web, obsah a provoz vašeho klubu.
|
||||||
|
- paragraph: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: produktová ukázka
|
||||||
|
- generic: Řídicí vrstva pro klubový web
|
||||||
|
- generic: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: homepage builder
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic: live preview
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: články
|
||||||
|
- generic: redakce
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: bannery
|
||||||
|
- generic:
|
||||||
|
- generic: komunikace
|
||||||
|
- generic: newsletter
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Match center
|
||||||
|
- generic: připraveno na víkend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: 1. tým
|
||||||
|
- generic: sobota 16:30
|
||||||
|
- generic:
|
||||||
|
- generic: Dorost U19
|
||||||
|
- generic: neděle 10:15
|
||||||
|
- generic:
|
||||||
|
- generic: Ženy
|
||||||
|
- generic: neděle 14:00
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: obsah
|
||||||
|
- generic: pod kontrolou
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: v publikaci
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Web + CMS
|
||||||
|
- generic: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Sportovní data
|
||||||
|
- generic: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Klubová agenda
|
||||||
|
- generic: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- generic:
|
||||||
|
- paragraph: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Partneři
|
||||||
|
- generic: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Přehled
|
||||||
|
- generic: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Platforma
|
||||||
|
- heading [level=2]: Navržené pro klub, který nechce skládat pět různých systémů.
|
||||||
|
- paragraph: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: MyUIbrix uvnitř
|
||||||
|
- generic: Skládání homepage bez front-end sprintu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Obsah
|
||||||
|
- generic: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Matchday
|
||||||
|
- generic: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- generic:
|
||||||
|
- paragraph: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Marketing
|
||||||
|
- generic: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- generic:
|
||||||
|
- paragraph: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- generic:
|
||||||
|
- paragraph: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Vedení klubu
|
||||||
|
- generic: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Ukázka produktu
|
||||||
|
- heading [level=2]: Editorial sports-tech bez generické šablony.
|
||||||
|
- paragraph: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: ukázková kompozice
|
||||||
|
- generic: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: bloky stránky
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Hero s hlavní kampaní
|
||||||
|
- generic:
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Novinky a články
|
||||||
|
- generic:
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Příští zápas + tabulka
|
||||||
|
- generic:
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Sponzoři a bannery
|
||||||
|
- generic:
|
||||||
|
- generic: "05"
|
||||||
|
- generic: Kontakty a mapa
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: preview
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro management
|
||||||
|
- generic: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- generic:
|
||||||
|
- paragraph: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro operativu
|
||||||
|
- generic: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro obsahový tým
|
||||||
|
- generic: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- generic:
|
||||||
|
- paragraph: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jak to funguje
|
||||||
|
- heading [level=2]: Od první identity klubu po každodenní publikaci.
|
||||||
|
- paragraph: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 01
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Nastavíte klubovou identitu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 02
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 03
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- generic:
|
||||||
|
- paragraph: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 04
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Publikujete a dál ladíte provoz
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: FAQ
|
||||||
|
- heading [level=2]: Krátké odpovědi na věci, které padnou nejdřív.
|
||||||
|
- paragraph: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: CTA a poptávka
|
||||||
|
- generic:
|
||||||
|
- heading [level=2]: Chcete si projít, jak bude MyClub fungovat pro váš klub?
|
||||||
|
- paragraph: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: pracující formulář
|
||||||
|
- generic: Pošlete poptávku přes stávající backend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jméno / klub
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic:
|
||||||
|
- generic: E-mail
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic:
|
||||||
|
- generic: Co chcete řešit
|
||||||
|
- textbox: Mám zájem o ukázku MyClubu
|
||||||
|
- generic:
|
||||||
|
- generic: Krátký kontext
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic:
|
||||||
|
- button:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: MyClub
|
||||||
|
- paragraph: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- dialog "MyClub" [ref=e483]:
|
||||||
|
- generic [ref=e484]:
|
||||||
|
- heading "MyClub" [level=2] [ref=e485]
|
||||||
|
- paragraph [ref=e486]: Klubový web, obsah a provoz v jednom editoru.
|
||||||
|
- generic [ref=e487]:
|
||||||
|
- link "Platforma" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e489] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e490] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e491] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e492] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e493] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- button "Close" [active] [ref=e494]:
|
||||||
|
- img
|
||||||
|
- generic [ref=e495]: Close
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- banner:
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic: M
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub
|
||||||
|
- generic: klubový web a provoz v jednom
|
||||||
|
- generic:
|
||||||
|
- button [expanded]:
|
||||||
|
- img
|
||||||
|
- main:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic:
|
||||||
|
- heading [level=1]: Jeden systém pro web, obsah a provoz vašeho klubu.
|
||||||
|
- paragraph: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: produktová ukázka
|
||||||
|
- generic: Řídicí vrstva pro klubový web
|
||||||
|
- generic: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: homepage builder
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic: live preview
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: články
|
||||||
|
- generic: redakce
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: bannery
|
||||||
|
- generic:
|
||||||
|
- generic: komunikace
|
||||||
|
- generic: newsletter
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Match center
|
||||||
|
- generic: připraveno na víkend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: 1. tým
|
||||||
|
- generic: sobota 16:30
|
||||||
|
- generic:
|
||||||
|
- generic: Dorost U19
|
||||||
|
- generic: neděle 10:15
|
||||||
|
- generic:
|
||||||
|
- generic: Ženy
|
||||||
|
- generic: neděle 14:00
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: obsah
|
||||||
|
- generic: pod kontrolou
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: v publikaci
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Web + CMS
|
||||||
|
- generic: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Sportovní data
|
||||||
|
- generic: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Klubová agenda
|
||||||
|
- generic: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- generic:
|
||||||
|
- paragraph: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Partneři
|
||||||
|
- generic: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Přehled
|
||||||
|
- generic: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Platforma
|
||||||
|
- heading [level=2]: Navržené pro klub, který nechce skládat pět různých systémů.
|
||||||
|
- paragraph: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: MyUIbrix uvnitř
|
||||||
|
- generic: Skládání homepage bez front-end sprintu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Obsah
|
||||||
|
- generic: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Matchday
|
||||||
|
- generic: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- generic:
|
||||||
|
- paragraph: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Marketing
|
||||||
|
- generic: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- generic:
|
||||||
|
- paragraph: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- generic:
|
||||||
|
- paragraph: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Vedení klubu
|
||||||
|
- generic: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Ukázka produktu
|
||||||
|
- heading [level=2]: Editorial sports-tech bez generické šablony.
|
||||||
|
- paragraph: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: ukázková kompozice
|
||||||
|
- generic: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: bloky stránky
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Hero s hlavní kampaní
|
||||||
|
- generic:
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Novinky a články
|
||||||
|
- generic:
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Příští zápas + tabulka
|
||||||
|
- generic:
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Sponzoři a bannery
|
||||||
|
- generic:
|
||||||
|
- generic: "05"
|
||||||
|
- generic: Kontakty a mapa
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: preview
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro management
|
||||||
|
- generic: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- generic:
|
||||||
|
- paragraph: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro operativu
|
||||||
|
- generic: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro obsahový tým
|
||||||
|
- generic: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- generic:
|
||||||
|
- paragraph: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jak to funguje
|
||||||
|
- heading [level=2]: Od první identity klubu po každodenní publikaci.
|
||||||
|
- paragraph: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 01
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Nastavíte klubovou identitu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 02
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 03
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- generic:
|
||||||
|
- paragraph: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 04
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Publikujete a dál ladíte provoz
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: FAQ
|
||||||
|
- heading [level=2]: Krátké odpovědi na věci, které padnou nejdřív.
|
||||||
|
- paragraph: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: CTA a poptávka
|
||||||
|
- generic:
|
||||||
|
- heading [level=2]: Chcete si projít, jak bude MyClub fungovat pro váš klub?
|
||||||
|
- paragraph: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: pracující formulář
|
||||||
|
- generic: Pošlete poptávku přes stávající backend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jméno / klub
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic:
|
||||||
|
- generic: E-mail
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic:
|
||||||
|
- generic: Co chcete řešit
|
||||||
|
- textbox: Mám zájem o ukázku MyClubu
|
||||||
|
- generic:
|
||||||
|
- generic: Krátký kontext
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic:
|
||||||
|
- button:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: MyClub
|
||||||
|
- paragraph: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- dialog "MyClub" [ref=e483]:
|
||||||
|
- generic [ref=e484]:
|
||||||
|
- heading "MyClub" [level=2] [ref=e485]
|
||||||
|
- paragraph [ref=e486]: Klubový web, obsah a provoz v jednom editoru.
|
||||||
|
- generic [ref=e487]:
|
||||||
|
- link "Platforma" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e489] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e490] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e491] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e492] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e493] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- button "Close" [active] [ref=e494]:
|
||||||
|
- img
|
||||||
|
- generic [ref=e495]: Close
|
||||||
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,477 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- banner:
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic: M
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub
|
||||||
|
- generic: klubový web a provoz v jednom
|
||||||
|
- navigation:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic:
|
||||||
|
- heading [level=1]: Jeden systém pro web, obsah a provoz vašeho klubu.
|
||||||
|
- paragraph: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: produktová ukázka
|
||||||
|
- generic: Řídicí vrstva pro klubový web
|
||||||
|
- generic: white mode only
|
||||||
|
- generic: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: homepage builder
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic: live preview
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: články
|
||||||
|
- generic: redakce
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: bannery
|
||||||
|
- generic:
|
||||||
|
- generic: komunikace
|
||||||
|
- generic: newsletter
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Match center
|
||||||
|
- generic: připraveno na víkend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: 1. tým
|
||||||
|
- generic: sobota 16:30
|
||||||
|
- generic:
|
||||||
|
- generic: Dorost U19
|
||||||
|
- generic: neděle 10:15
|
||||||
|
- generic:
|
||||||
|
- generic: Ženy
|
||||||
|
- generic: neděle 14:00
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: obsah
|
||||||
|
- generic: pod kontrolou
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: v publikaci
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Web + CMS
|
||||||
|
- generic: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Sportovní data
|
||||||
|
- generic: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Klubová agenda
|
||||||
|
- generic: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- generic:
|
||||||
|
- paragraph: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Partneři
|
||||||
|
- generic: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Přehled
|
||||||
|
- generic: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Platforma
|
||||||
|
- heading [level=2]: Navržené pro klub, který nechce skládat pět různých systémů.
|
||||||
|
- paragraph: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: MyUIbrix uvnitř
|
||||||
|
- generic: Skládání homepage bez front-end sprintu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Obsah
|
||||||
|
- generic: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Matchday
|
||||||
|
- generic: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- generic:
|
||||||
|
- paragraph: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Marketing
|
||||||
|
- generic: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- generic:
|
||||||
|
- paragraph: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- generic:
|
||||||
|
- paragraph: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Vedení klubu
|
||||||
|
- generic: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Ukázka produktu
|
||||||
|
- heading [level=2]: Editorial sports-tech bez generické šablony.
|
||||||
|
- paragraph: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: ukázková kompozice
|
||||||
|
- generic: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: bloky stránky
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Hero s hlavní kampaní
|
||||||
|
- generic:
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Novinky a články
|
||||||
|
- generic:
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Příští zápas + tabulka
|
||||||
|
- generic:
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Sponzoři a bannery
|
||||||
|
- generic:
|
||||||
|
- generic: "05"
|
||||||
|
- generic: Kontakty a mapa
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: preview
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro management
|
||||||
|
- generic: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- generic:
|
||||||
|
- paragraph: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro operativu
|
||||||
|
- generic: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro obsahový tým
|
||||||
|
- generic: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- generic:
|
||||||
|
- paragraph: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jak to funguje
|
||||||
|
- heading [level=2]: Od první identity klubu po každodenní publikaci.
|
||||||
|
- paragraph: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 01
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Nastavíte klubovou identitu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 02
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 03
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- generic:
|
||||||
|
- paragraph: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 04
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Publikujete a dál ladíte provoz
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: FAQ
|
||||||
|
- heading [level=2]: Krátké odpovědi na věci, které padnou nejdřív.
|
||||||
|
- paragraph: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: CTA a poptávka
|
||||||
|
- generic:
|
||||||
|
- heading [level=2]: Chcete si projít, jak bude MyClub fungovat pro váš klub?
|
||||||
|
- paragraph: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: pracující formulář
|
||||||
|
- generic: Pošlete poptávku přes stávající backend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jméno / klub
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic:
|
||||||
|
- generic: E-mail
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic:
|
||||||
|
- generic: Co chcete řešit
|
||||||
|
- textbox: Mám zájem o ukázku MyClubu
|
||||||
|
- generic:
|
||||||
|
- generic: Krátký kontext
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic:
|
||||||
|
- button:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: MyClub
|
||||||
|
- paragraph: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- dialog "MyClub" [ref=e483]:
|
||||||
|
- generic [ref=e484]:
|
||||||
|
- heading "MyClub" [level=2] [ref=e485]
|
||||||
|
- paragraph [ref=e486]: Klubový web, obsah a provoz v jednom editoru.
|
||||||
|
- generic [ref=e487]:
|
||||||
|
- link "Platforma" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e489] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e490] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e491] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e492] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e493] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- button "Close" [ref=e494]:
|
||||||
|
- img
|
||||||
|
- generic [ref=e495]: Close
|
||||||
@@ -0,0 +1,477 @@
|
|||||||
|
- generic [active]:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- banner:
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic: M
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub
|
||||||
|
- generic: klubový web a provoz v jednom
|
||||||
|
- navigation:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic:
|
||||||
|
- heading [level=1]: Jeden systém pro web, obsah a provoz vašeho klubu.
|
||||||
|
- paragraph: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: produktová ukázka
|
||||||
|
- generic: Řídicí vrstva pro klubový web
|
||||||
|
- generic: white mode only
|
||||||
|
- generic: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: homepage builder
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic: live preview
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: články
|
||||||
|
- generic: redakce
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: bannery
|
||||||
|
- generic:
|
||||||
|
- generic: komunikace
|
||||||
|
- generic: newsletter
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Match center
|
||||||
|
- generic: připraveno na víkend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: 1. tým
|
||||||
|
- generic: sobota 16:30
|
||||||
|
- generic:
|
||||||
|
- generic: Dorost U19
|
||||||
|
- generic: neděle 10:15
|
||||||
|
- generic:
|
||||||
|
- generic: Ženy
|
||||||
|
- generic: neděle 14:00
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: obsah
|
||||||
|
- generic: pod kontrolou
|
||||||
|
- generic:
|
||||||
|
- generic: partneři
|
||||||
|
- generic: v publikaci
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Web + CMS
|
||||||
|
- generic: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Sportovní data
|
||||||
|
- generic: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Klubová agenda
|
||||||
|
- generic: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- generic:
|
||||||
|
- paragraph: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Partneři
|
||||||
|
- generic: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Přehled
|
||||||
|
- generic: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Platforma
|
||||||
|
- heading [level=2]: Navržené pro klub, který nechce skládat pět různých systémů.
|
||||||
|
- paragraph: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: MyUIbrix uvnitř
|
||||||
|
- generic: Skládání homepage bez front-end sprintu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Obsah
|
||||||
|
- generic: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- generic:
|
||||||
|
- paragraph: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Matchday
|
||||||
|
- generic: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- generic:
|
||||||
|
- paragraph: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Marketing
|
||||||
|
- generic: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- generic:
|
||||||
|
- paragraph: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Komunikace
|
||||||
|
- generic: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- generic:
|
||||||
|
- paragraph: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Vedení klubu
|
||||||
|
- generic: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Ukázka produktu
|
||||||
|
- heading [level=2]: Editorial sports-tech bez generické šablony.
|
||||||
|
- paragraph: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: ukázková kompozice
|
||||||
|
- generic: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: bloky stránky
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Hero s hlavní kampaní
|
||||||
|
- generic:
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Novinky a články
|
||||||
|
- generic:
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Příští zápas + tabulka
|
||||||
|
- generic:
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Sponzoři a bannery
|
||||||
|
- generic:
|
||||||
|
- generic: "05"
|
||||||
|
- generic: Kontakty a mapa
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: preview
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro management
|
||||||
|
- generic: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- generic:
|
||||||
|
- paragraph: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro operativu
|
||||||
|
- generic: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- generic: Pro obsahový tým
|
||||||
|
- generic: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- generic:
|
||||||
|
- paragraph: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jak to funguje
|
||||||
|
- heading [level=2]: Od první identity klubu po každodenní publikaci.
|
||||||
|
- paragraph: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 01
|
||||||
|
- generic: "01"
|
||||||
|
- generic: Nastavíte klubovou identitu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 02
|
||||||
|
- generic: "02"
|
||||||
|
- generic: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- generic:
|
||||||
|
- paragraph: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 03
|
||||||
|
- generic: "03"
|
||||||
|
- generic: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- generic:
|
||||||
|
- paragraph: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: krok 04
|
||||||
|
- generic: "04"
|
||||||
|
- generic: Publikujete a dál ladíte provoz
|
||||||
|
- generic:
|
||||||
|
- paragraph: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: FAQ
|
||||||
|
- heading [level=2]: Krátké odpovědi na věci, které padnou nejdřív.
|
||||||
|
- paragraph: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- heading [level=3]:
|
||||||
|
- button:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: CTA a poptávka
|
||||||
|
- generic:
|
||||||
|
- heading [level=2]: Chcete si projít, jak bude MyClub fungovat pro váš klub?
|
||||||
|
- paragraph: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- paragraph: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- img
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: pracující formulář
|
||||||
|
- generic: Pošlete poptávku přes stávající backend
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- generic: Jméno / klub
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic:
|
||||||
|
- generic: E-mail
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic:
|
||||||
|
- generic: Co chcete řešit
|
||||||
|
- textbox: Mám zájem o ukázku MyClubu
|
||||||
|
- generic:
|
||||||
|
- generic: Krátký kontext
|
||||||
|
- textbox:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic:
|
||||||
|
- button:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo:
|
||||||
|
- generic:
|
||||||
|
- generic:
|
||||||
|
- paragraph: MyClub
|
||||||
|
- paragraph: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic:
|
||||||
|
- link:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- text: Platforma
|
||||||
|
- link:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Ukázka
|
||||||
|
- link:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- text: Jak to funguje
|
||||||
|
- link:
|
||||||
|
- /url: "#faq"
|
||||||
|
- text: FAQ
|
||||||
|
- link:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Kontakt
|
||||||
|
- dialog "MyClub" [ref=e483]:
|
||||||
|
- generic [ref=e484]:
|
||||||
|
- heading "MyClub" [level=2] [ref=e485]
|
||||||
|
- paragraph [ref=e486]: Klubový web, obsah a provoz v jednom editoru.
|
||||||
|
- generic [ref=e487]:
|
||||||
|
- link "Platforma" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e489] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e490] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e491] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e492] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e493] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- button "Close" [ref=e494]:
|
||||||
|
- img
|
||||||
|
- generic [ref=e495]: Close
|
||||||
|
After Width: | Height: | Size: 274 KiB |
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 341 KiB |
@@ -0,0 +1,387 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [active] [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- paragraph [ref=e505]: Zadejte prosím jméno nebo název klubu.
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- paragraph [ref=e506]: Zadejte prosím platný e-mail.
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- paragraph [ref=e507]: Doplňte prosím alespoň krátký kontext, co chcete řešit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,387 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [active] [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- paragraph [ref=e505]: Zadejte prosím jméno nebo název klubu.
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- paragraph [ref=e506]: Zadejte prosím platný e-mail.
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- paragraph [ref=e507]: Doplňte prosím alespoň krátký kontext, co chcete řešit.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 357 KiB |
@@ -0,0 +1,388 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: FK Example
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: test@example.com
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Chci produktovou ukázku
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- paragraph [ref=e508]: Failed to save message
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: FK Example
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: test@example.com
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Chci produktovou ukázku
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- paragraph [ref=e508]: Failed to save message
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 345 KiB |
@@ -0,0 +1,388 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: FK Example
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: test@example.com
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Chci produktovou ukázku
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- paragraph [ref=e508]: Failed to save message
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,388 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e496]:
|
||||||
|
- link "Platforma" [ref=e497] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e498] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e499] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e500] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e501] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e503] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e13]:
|
||||||
|
- generic [ref=e15]:
|
||||||
|
- generic [ref=e16]:
|
||||||
|
- generic [ref=e17]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e18]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e19]
|
||||||
|
- paragraph [ref=e20]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- link "Domluvit ukázku" [ref=e22] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e23] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- generic [ref=e25]:
|
||||||
|
- generic [ref=e26]:
|
||||||
|
- img [ref=e27]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e29]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- img [ref=e32]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e34]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e35]:
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- img [ref=e37]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e39]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- generic [ref=e43]:
|
||||||
|
- generic [ref=e44]:
|
||||||
|
- paragraph [ref=e45]: produktová ukázka
|
||||||
|
- generic [ref=e46]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e504]: white mode only
|
||||||
|
- generic [ref=e47]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- generic [ref=e56]: homepage builder
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e59]:
|
||||||
|
- generic [ref=e60]:
|
||||||
|
- img [ref=e61]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e65]: live preview
|
||||||
|
- generic [ref=e73]:
|
||||||
|
- generic [ref=e74]:
|
||||||
|
- generic [ref=e75]: články
|
||||||
|
- generic [ref=e76]: redakce
|
||||||
|
- generic [ref=e77]:
|
||||||
|
- generic [ref=e78]: partneři
|
||||||
|
- generic [ref=e79]: bannery
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]: komunikace
|
||||||
|
- generic [ref=e82]: newsletter
|
||||||
|
- generic [ref=e83]:
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- img [ref=e85]
|
||||||
|
- generic [ref=e87]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e88]:
|
||||||
|
- img [ref=e89]
|
||||||
|
- generic [ref=e92]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e93]:
|
||||||
|
- generic [ref=e94]:
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- generic [ref=e96]:
|
||||||
|
- img [ref=e97]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e103]: připraveno na víkend
|
||||||
|
- generic [ref=e104]:
|
||||||
|
- generic [ref=e105]:
|
||||||
|
- generic [ref=e106]: 1. tým
|
||||||
|
- generic [ref=e107]: sobota 16:30
|
||||||
|
- generic [ref=e108]:
|
||||||
|
- generic [ref=e109]: Dorost U19
|
||||||
|
- generic [ref=e110]: neděle 10:15
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]: Ženy
|
||||||
|
- generic [ref=e113]: neděle 14:00
|
||||||
|
- generic [ref=e114]:
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]:
|
||||||
|
- img [ref=e117]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e119]
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- generic [ref=e124]: obsah
|
||||||
|
- generic [ref=e125]: pod kontrolou
|
||||||
|
- generic [ref=e126]:
|
||||||
|
- generic [ref=e127]: partneři
|
||||||
|
- generic [ref=e128]: v publikaci
|
||||||
|
- generic [ref=e131]:
|
||||||
|
- generic [ref=e132]:
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- img [ref=e135]
|
||||||
|
- generic [ref=e138]: Web + CMS
|
||||||
|
- generic [ref=e139]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e141]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e142]:
|
||||||
|
- generic [ref=e143]:
|
||||||
|
- img [ref=e145]
|
||||||
|
- generic [ref=e151]: Sportovní data
|
||||||
|
- generic [ref=e152]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e154]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e155]:
|
||||||
|
- generic [ref=e156]:
|
||||||
|
- img [ref=e158]
|
||||||
|
- generic [ref=e162]: Klubová agenda
|
||||||
|
- generic [ref=e163]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e165]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e166]:
|
||||||
|
- generic [ref=e167]:
|
||||||
|
- img [ref=e169]
|
||||||
|
- generic [ref=e172]: Komunikace
|
||||||
|
- generic [ref=e173]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e175]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e176]:
|
||||||
|
- generic [ref=e177]:
|
||||||
|
- img [ref=e179]
|
||||||
|
- generic [ref=e182]: Partneři
|
||||||
|
- generic [ref=e183]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e185]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e186]:
|
||||||
|
- generic [ref=e187]:
|
||||||
|
- img [ref=e189]
|
||||||
|
- generic [ref=e191]: Přehled
|
||||||
|
- generic [ref=e192]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e194]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e196]:
|
||||||
|
- generic [ref=e197]:
|
||||||
|
- generic [ref=e198]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e199]
|
||||||
|
- paragraph [ref=e200]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e201]:
|
||||||
|
- generic [ref=e202]:
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- img [ref=e205]
|
||||||
|
- generic [ref=e208]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e209]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e211]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e212]:
|
||||||
|
- generic [ref=e213]:
|
||||||
|
- img [ref=e215]
|
||||||
|
- generic [ref=e218]: Obsah
|
||||||
|
- generic [ref=e219]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e221]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e222]:
|
||||||
|
- generic [ref=e223]:
|
||||||
|
- img [ref=e225]
|
||||||
|
- generic [ref=e231]: Matchday
|
||||||
|
- generic [ref=e232]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e234]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e235]:
|
||||||
|
- generic [ref=e236]:
|
||||||
|
- img [ref=e238]
|
||||||
|
- generic [ref=e241]: Marketing
|
||||||
|
- generic [ref=e242]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e244]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e245]:
|
||||||
|
- generic [ref=e246]:
|
||||||
|
- img [ref=e248]
|
||||||
|
- generic [ref=e251]: Komunikace
|
||||||
|
- generic [ref=e252]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e254]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e255]:
|
||||||
|
- generic [ref=e256]:
|
||||||
|
- img [ref=e258]
|
||||||
|
- generic [ref=e260]: Vedení klubu
|
||||||
|
- generic [ref=e261]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e263]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e265]:
|
||||||
|
- generic [ref=e266]:
|
||||||
|
- generic [ref=e267]:
|
||||||
|
- generic [ref=e268]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e269]
|
||||||
|
- paragraph [ref=e270]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e271]:
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]: ukázková kompozice
|
||||||
|
- generic [ref=e274]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e275]:
|
||||||
|
- generic [ref=e276]:
|
||||||
|
- generic [ref=e277]:
|
||||||
|
- generic [ref=e278]: bloky stránky
|
||||||
|
- img [ref=e279]
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]: "01"
|
||||||
|
- generic [ref=e285]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e286]:
|
||||||
|
- generic [ref=e287]: "02"
|
||||||
|
- generic [ref=e288]: Novinky a články
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]: "03"
|
||||||
|
- generic [ref=e291]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e292]:
|
||||||
|
- generic [ref=e293]: "04"
|
||||||
|
- generic [ref=e294]: Sponzoři a bannery
|
||||||
|
- generic [ref=e295]:
|
||||||
|
- generic [ref=e296]: "05"
|
||||||
|
- generic [ref=e297]: Kontakty a mapa
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: preview
|
||||||
|
- img [ref=e301]
|
||||||
|
- generic [ref=e320]:
|
||||||
|
- generic [ref=e321]:
|
||||||
|
- generic [ref=e322]:
|
||||||
|
- img [ref=e324]
|
||||||
|
- generic [ref=e327]: Pro management
|
||||||
|
- generic [ref=e328]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e330]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e331]:
|
||||||
|
- generic [ref=e332]:
|
||||||
|
- img [ref=e334]
|
||||||
|
- generic [ref=e336]: Pro operativu
|
||||||
|
- generic [ref=e337]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e339]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e340]:
|
||||||
|
- generic [ref=e341]:
|
||||||
|
- img [ref=e343]
|
||||||
|
- generic [ref=e348]: Pro obsahový tým
|
||||||
|
- generic [ref=e349]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e351]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e353]:
|
||||||
|
- generic [ref=e354]:
|
||||||
|
- generic [ref=e355]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e356]
|
||||||
|
- paragraph [ref=e357]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e358]:
|
||||||
|
- generic [ref=e359]:
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: krok 01
|
||||||
|
- generic [ref=e363]: "01"
|
||||||
|
- generic [ref=e364]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e366]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]:
|
||||||
|
- generic [ref=e370]: krok 02
|
||||||
|
- generic [ref=e371]: "02"
|
||||||
|
- generic [ref=e372]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e374]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]:
|
||||||
|
- generic [ref=e378]: krok 03
|
||||||
|
- generic [ref=e379]: "03"
|
||||||
|
- generic [ref=e380]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e382]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]:
|
||||||
|
- generic [ref=e386]: krok 04
|
||||||
|
- generic [ref=e387]: "04"
|
||||||
|
- generic [ref=e388]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e390]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]:
|
||||||
|
- generic [ref=e394]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e395]
|
||||||
|
- paragraph [ref=e396]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e401]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e402]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e404]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e405]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e407]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e408]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e410]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e411]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e413]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e414]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e417]:
|
||||||
|
- generic [ref=e418]:
|
||||||
|
- generic [ref=e419]: CTA a poptávka
|
||||||
|
- generic [ref=e420]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e421]
|
||||||
|
- paragraph [ref=e422]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e423]:
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- img [ref=e426]
|
||||||
|
- paragraph [ref=e428]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e429]:
|
||||||
|
- img [ref=e431]
|
||||||
|
- paragraph [ref=e433]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e434]:
|
||||||
|
- img [ref=e436]
|
||||||
|
- paragraph [ref=e438]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e439]:
|
||||||
|
- generic [ref=e440]:
|
||||||
|
- img [ref=e441]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e444]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e445]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e446]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- generic [ref=e448]:
|
||||||
|
- generic [ref=e449]: pracující formulář
|
||||||
|
- generic [ref=e450]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e452]:
|
||||||
|
- generic [ref=e453]:
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e456]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: FK Example
|
||||||
|
- generic [ref=e457]:
|
||||||
|
- generic [ref=e458]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e459]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: test@example.com
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e462]: Chci produktovou ukázku
|
||||||
|
- generic [ref=e463]:
|
||||||
|
- generic [ref=e464]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e465]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e466]:
|
||||||
|
- button "Domluvit ukázku" [ref=e467]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e468]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e469]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- paragraph [ref=e509]: Failed to save message
|
||||||
|
- contentinfo [ref=e471]:
|
||||||
|
- generic [ref=e472]:
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- paragraph [ref=e474]: MyClub
|
||||||
|
- paragraph [ref=e475]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e476]:
|
||||||
|
- link "Platforma" [ref=e477] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e478] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e479] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e480] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e481] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 345 KiB |
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e469]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,384 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e469]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
@@ -0,0 +1,386 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: Chci produktovou ukázku
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [active] [ref=e469]: Mám zájem o ukázku MyClubu
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 375 KiB |
@@ -0,0 +1,388 @@
|
|||||||
|
- generic [ref=e3]:
|
||||||
|
- banner [ref=e4]:
|
||||||
|
- generic [ref=e5]:
|
||||||
|
- link "M MyClub klubový web a provoz v jednom" [ref=e6] [cursor=pointer]:
|
||||||
|
- /url: "#top"
|
||||||
|
- generic [ref=e7]: M
|
||||||
|
- generic [ref=e8]:
|
||||||
|
- generic [ref=e9]: MyClub
|
||||||
|
- generic [ref=e10]: klubový web a provoz v jednom
|
||||||
|
- navigation [ref=e11]:
|
||||||
|
- link "Platforma" [ref=e12] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e13] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e14] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e15] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e16] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- link "Domluvit ukázku" [ref=e18] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- main [ref=e19]:
|
||||||
|
- generic [ref=e21]:
|
||||||
|
- generic [ref=e22]:
|
||||||
|
- generic [ref=e23]: MyClub SaaS pro sportovní kluby
|
||||||
|
- generic [ref=e24]:
|
||||||
|
- heading "Jeden systém pro web, obsah a provoz vašeho klubu." [level=1] [ref=e25]
|
||||||
|
- paragraph [ref=e26]: MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
- generic [ref=e27]:
|
||||||
|
- link "Domluvit ukázku" [ref=e28] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- link "Projít produktovou vrstvu" [ref=e29] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- text: Projít produktovou vrstvu
|
||||||
|
- img
|
||||||
|
- generic [ref=e30]:
|
||||||
|
- generic [ref=e31]:
|
||||||
|
- generic [ref=e32]:
|
||||||
|
- img [ref=e33]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e35]: MyUIbrix jako vestavěný editor homepage.
|
||||||
|
- generic [ref=e36]:
|
||||||
|
- generic [ref=e37]:
|
||||||
|
- img [ref=e38]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e40]: Klubová data, obsah a komunikace bez pluginové skládačky.
|
||||||
|
- generic [ref=e41]:
|
||||||
|
- generic [ref=e42]:
|
||||||
|
- img [ref=e43]
|
||||||
|
- text: Přímý benefit
|
||||||
|
- paragraph [ref=e45]: Připravené fungovat vedle stávajícího backendu a publikace.
|
||||||
|
- generic [ref=e47]:
|
||||||
|
- generic [ref=e48]:
|
||||||
|
- generic [ref=e49]:
|
||||||
|
- generic [ref=e50]:
|
||||||
|
- paragraph [ref=e51]: produktová ukázka
|
||||||
|
- generic [ref=e52]: Řídicí vrstva pro klubový web
|
||||||
|
- generic [ref=e53]: white mode only
|
||||||
|
- generic [ref=e54]: MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
- generic [ref=e55]:
|
||||||
|
- generic [ref=e56]:
|
||||||
|
- generic [ref=e57]:
|
||||||
|
- generic [ref=e63]: homepage builder
|
||||||
|
- generic [ref=e64]:
|
||||||
|
- generic [ref=e66]:
|
||||||
|
- generic [ref=e67]:
|
||||||
|
- img [ref=e68]
|
||||||
|
- text: Hero + novinky + zápasy
|
||||||
|
- generic [ref=e72]: live preview
|
||||||
|
- generic [ref=e80]:
|
||||||
|
- generic [ref=e81]:
|
||||||
|
- generic [ref=e82]: články
|
||||||
|
- generic [ref=e83]: redakce
|
||||||
|
- generic [ref=e84]:
|
||||||
|
- generic [ref=e85]: partneři
|
||||||
|
- generic [ref=e86]: bannery
|
||||||
|
- generic [ref=e87]:
|
||||||
|
- generic [ref=e88]: komunikace
|
||||||
|
- generic [ref=e89]: newsletter
|
||||||
|
- generic [ref=e90]:
|
||||||
|
- generic [ref=e91]:
|
||||||
|
- img [ref=e92]
|
||||||
|
- generic [ref=e94]: Zápasy a tabulky v klubovém layoutu
|
||||||
|
- generic [ref=e95]:
|
||||||
|
- img [ref=e96]
|
||||||
|
- generic [ref=e99]: Kontakty a newsletter bez externí skládačky
|
||||||
|
- generic [ref=e100]:
|
||||||
|
- generic [ref=e101]:
|
||||||
|
- generic [ref=e102]:
|
||||||
|
- generic [ref=e103]:
|
||||||
|
- img [ref=e104]
|
||||||
|
- text: Match center
|
||||||
|
- generic [ref=e110]: připraveno na víkend
|
||||||
|
- generic [ref=e111]:
|
||||||
|
- generic [ref=e112]:
|
||||||
|
- generic [ref=e113]: 1. tým
|
||||||
|
- generic [ref=e114]: sobota 16:30
|
||||||
|
- generic [ref=e115]:
|
||||||
|
- generic [ref=e116]: Dorost U19
|
||||||
|
- generic [ref=e117]: neděle 10:15
|
||||||
|
- generic [ref=e118]:
|
||||||
|
- generic [ref=e119]: Ženy
|
||||||
|
- generic [ref=e120]: neděle 14:00
|
||||||
|
- generic [ref=e121]:
|
||||||
|
- generic [ref=e122]:
|
||||||
|
- generic [ref=e123]:
|
||||||
|
- img [ref=e124]
|
||||||
|
- text: Přehled vedení
|
||||||
|
- img [ref=e126]
|
||||||
|
- generic [ref=e129]:
|
||||||
|
- generic [ref=e130]:
|
||||||
|
- generic [ref=e131]: obsah
|
||||||
|
- generic [ref=e132]: pod kontrolou
|
||||||
|
- generic [ref=e133]:
|
||||||
|
- generic [ref=e134]: partneři
|
||||||
|
- generic [ref=e135]: v publikaci
|
||||||
|
- generic [ref=e138]:
|
||||||
|
- generic [ref=e139]:
|
||||||
|
- generic [ref=e140]:
|
||||||
|
- img [ref=e142]
|
||||||
|
- generic [ref=e145]: Web + CMS
|
||||||
|
- generic [ref=e146]: Jedno prostředí pro veřejný web i správu obsahu
|
||||||
|
- paragraph [ref=e148]: Stránky, články, galerie, bannery a homepage builder bez přepínání mezi nástroji.
|
||||||
|
- generic [ref=e149]:
|
||||||
|
- generic [ref=e150]:
|
||||||
|
- img [ref=e152]
|
||||||
|
- generic [ref=e158]: Sportovní data
|
||||||
|
- generic [ref=e159]: Zápasy, výsledky a tabulky v klubovém kontextu
|
||||||
|
- paragraph [ref=e161]: Připravené pro klubový provoz, včetně hráčů, týmů, rozpisů a matchday obsahu.
|
||||||
|
- generic [ref=e162]:
|
||||||
|
- generic [ref=e163]:
|
||||||
|
- img [ref=e165]
|
||||||
|
- generic [ref=e169]: Klubová agenda
|
||||||
|
- generic [ref=e170]: Týmy, hráči, kontakty a role přehledně pohromadě
|
||||||
|
- paragraph [ref=e172]: Obsahový tým, vedení klubu i operativa pracují nad jedním zdrojem pravdy.
|
||||||
|
- generic [ref=e173]:
|
||||||
|
- generic [ref=e174]:
|
||||||
|
- img [ref=e176]
|
||||||
|
- generic [ref=e179]: Komunikace
|
||||||
|
- generic [ref=e180]: Newsletter, kontaktní formuláře a engagement bez doplňků
|
||||||
|
- paragraph [ref=e182]: Komunikace s fanoušky, členy a partnery vychází přímo z klubového obsahu.
|
||||||
|
- generic [ref=e183]:
|
||||||
|
- generic [ref=e184]:
|
||||||
|
- img [ref=e186]
|
||||||
|
- generic [ref=e189]: Partneři
|
||||||
|
- generic [ref=e190]: Sponzoři, bannery a promo plochy bez ručního chaosu
|
||||||
|
- paragraph [ref=e192]: Klubová monetizace se řídí stejně snadno jako redakční obsah.
|
||||||
|
- generic [ref=e193]:
|
||||||
|
- generic [ref=e194]:
|
||||||
|
- img [ref=e196]
|
||||||
|
- generic [ref=e198]: Přehled
|
||||||
|
- generic [ref=e199]: Analytika a provozní kontrola v jednom dashboardu
|
||||||
|
- paragraph [ref=e201]: Vidíte, co klub publikuje, co funguje a co má smysl dál posílit.
|
||||||
|
- generic [ref=e203]:
|
||||||
|
- generic [ref=e204]:
|
||||||
|
- generic [ref=e205]: Platforma
|
||||||
|
- heading "Navržené pro klub, který nechce skládat pět různých systémů." [level=2] [ref=e206]
|
||||||
|
- paragraph [ref=e207]: Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack.
|
||||||
|
- generic [ref=e208]:
|
||||||
|
- generic [ref=e209]:
|
||||||
|
- generic [ref=e210]:
|
||||||
|
- img [ref=e212]
|
||||||
|
- generic [ref=e215]: MyUIbrix uvnitř
|
||||||
|
- generic [ref=e216]: Skládání homepage bez front-end sprintu
|
||||||
|
- paragraph [ref=e218]: Hero sekce, novinky, zápasy, bannery, kontakty i další bloky poskládáte vizuálně a s okamžitým náhledem.
|
||||||
|
- generic [ref=e219]:
|
||||||
|
- generic [ref=e220]:
|
||||||
|
- img [ref=e222]
|
||||||
|
- generic [ref=e225]: Obsah
|
||||||
|
- generic [ref=e226]: Redakce, články, galerie a videa v jednotném workflow
|
||||||
|
- paragraph [ref=e228]: Klubový obsah má společná média, kategorie, vyhledávání i publikaci napříč veřejným webem.
|
||||||
|
- generic [ref=e229]:
|
||||||
|
- generic [ref=e230]:
|
||||||
|
- img [ref=e232]
|
||||||
|
- generic [ref=e238]: Matchday
|
||||||
|
- generic [ref=e239]: Sportovní sekce, které nejsou jen statická tabulka
|
||||||
|
- paragraph [ref=e241]: Matches, standings, hráči a soutěže vypadají jako součást produktu, ne jako externí widget.
|
||||||
|
- generic [ref=e242]:
|
||||||
|
- generic [ref=e243]:
|
||||||
|
- img [ref=e245]
|
||||||
|
- generic [ref=e248]: Marketing
|
||||||
|
- generic [ref=e249]: Sponzoři, bannery a kampaně navázané na klubový obsah
|
||||||
|
- paragraph [ref=e251]: Promo plochy i partnerské sekce spravujete ve stejném systému jako články a homepage.
|
||||||
|
- generic [ref=e252]:
|
||||||
|
- generic [ref=e253]:
|
||||||
|
- img [ref=e255]
|
||||||
|
- generic [ref=e258]: Komunikace
|
||||||
|
- generic [ref=e259]: Newslettery, kontakty, komentáře a ankety bez lepení pluginů
|
||||||
|
- paragraph [ref=e261]: Fan engagement a klubové formuláře jsou součást platformy, ne další externí vrstva.
|
||||||
|
- generic [ref=e262]:
|
||||||
|
- generic [ref=e263]:
|
||||||
|
- img [ref=e265]
|
||||||
|
- generic [ref=e267]: Vedení klubu
|
||||||
|
- generic [ref=e268]: Výsledky, aktivita a provozní signály na jednom místě
|
||||||
|
- paragraph [ref=e270]: Obsah, návštěvnost a klubová agenda zůstávají čitelné i pro tým, který nechce složitou enterprise správu.
|
||||||
|
- generic [ref=e272]:
|
||||||
|
- generic [ref=e273]:
|
||||||
|
- generic [ref=e274]:
|
||||||
|
- generic [ref=e275]: Ukázka produktu
|
||||||
|
- heading "Editorial sports-tech bez generické šablony." [level=2] [ref=e276]
|
||||||
|
- paragraph [ref=e277]: Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu.
|
||||||
|
- generic [ref=e278]:
|
||||||
|
- generic [ref=e279]:
|
||||||
|
- generic [ref=e280]: ukázková kompozice
|
||||||
|
- generic [ref=e281]: Homepage builder, který řídí rytmus celého klubu
|
||||||
|
- generic [ref=e282]:
|
||||||
|
- generic [ref=e283]:
|
||||||
|
- generic [ref=e284]:
|
||||||
|
- generic [ref=e285]: bloky stránky
|
||||||
|
- img [ref=e286]
|
||||||
|
- generic [ref=e289]:
|
||||||
|
- generic [ref=e290]:
|
||||||
|
- generic [ref=e291]: "01"
|
||||||
|
- generic [ref=e292]: Hero s hlavní kampaní
|
||||||
|
- generic [ref=e293]:
|
||||||
|
- generic [ref=e294]: "02"
|
||||||
|
- generic [ref=e295]: Novinky a články
|
||||||
|
- generic [ref=e296]:
|
||||||
|
- generic [ref=e297]: "03"
|
||||||
|
- generic [ref=e298]: Příští zápas + tabulka
|
||||||
|
- generic [ref=e299]:
|
||||||
|
- generic [ref=e300]: "04"
|
||||||
|
- generic [ref=e301]: Sponzoři a bannery
|
||||||
|
- generic [ref=e302]:
|
||||||
|
- generic [ref=e303]: "05"
|
||||||
|
- generic [ref=e304]: Kontakty a mapa
|
||||||
|
- generic [ref=e306]:
|
||||||
|
- generic [ref=e307]: preview
|
||||||
|
- img [ref=e308]
|
||||||
|
- generic [ref=e327]:
|
||||||
|
- generic [ref=e328]:
|
||||||
|
- generic [ref=e329]:
|
||||||
|
- img [ref=e331]
|
||||||
|
- generic [ref=e334]: Pro management
|
||||||
|
- generic [ref=e335]: Méně nástrojů, méně překlepů, méně ruční koordinace
|
||||||
|
- paragraph [ref=e337]: Jedna platforma pro veřejný web, provozní data i komunikaci s partnery a komunitou.
|
||||||
|
- generic [ref=e338]:
|
||||||
|
- generic [ref=e339]:
|
||||||
|
- img [ref=e341]
|
||||||
|
- generic [ref=e343]: Pro operativu
|
||||||
|
- generic [ref=e344]: Rychlá reakce na zápasový víkend i změny v klubu
|
||||||
|
- paragraph [ref=e346]: Obsah, bannery, kontakty a homepage bloky upravíte bez čekání na nový deploy celé prezentace.
|
||||||
|
- generic [ref=e347]:
|
||||||
|
- generic [ref=e348]:
|
||||||
|
- img [ref=e350]
|
||||||
|
- generic [ref=e355]: Pro obsahový tým
|
||||||
|
- generic [ref=e356]: Média, články a vizuální skladba webu pod jednou střechou
|
||||||
|
- paragraph [ref=e358]: Redaktor i admin pracují nad stejným systémem a neřeší, kam co ručně kopírovat.
|
||||||
|
- generic [ref=e360]:
|
||||||
|
- generic [ref=e361]:
|
||||||
|
- generic [ref=e362]: Jak to funguje
|
||||||
|
- heading "Od první identity klubu po každodenní publikaci." [level=2] [ref=e363]
|
||||||
|
- paragraph [ref=e364]: Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu.
|
||||||
|
- generic [ref=e365]:
|
||||||
|
- generic [ref=e366]:
|
||||||
|
- generic [ref=e367]:
|
||||||
|
- generic [ref=e368]:
|
||||||
|
- generic [ref=e369]: krok 01
|
||||||
|
- generic [ref=e370]: "01"
|
||||||
|
- generic [ref=e371]: Nastavíte klubovou identitu
|
||||||
|
- paragraph [ref=e373]: Barvy, navigaci, kontakty, role, mapu a základní klubový obsah připravíte bez ohýbání obecného CMS.
|
||||||
|
- generic [ref=e374]:
|
||||||
|
- generic [ref=e375]:
|
||||||
|
- generic [ref=e376]:
|
||||||
|
- generic [ref=e377]: krok 02
|
||||||
|
- generic [ref=e378]: "02"
|
||||||
|
- generic [ref=e379]: Poskládáte veřejný web v MyUIbrixu
|
||||||
|
- paragraph [ref=e381]: Homepage builder drží vzhled webu pod kontrolou i ve chvíli, kdy potřebujete rychle změnit pořadí bloků a akcenty.
|
||||||
|
- generic [ref=e382]:
|
||||||
|
- generic [ref=e383]:
|
||||||
|
- generic [ref=e384]:
|
||||||
|
- generic [ref=e385]: krok 03
|
||||||
|
- generic [ref=e386]: "03"
|
||||||
|
- generic [ref=e387]: Napojíte sportovní a obsahové vrstvy
|
||||||
|
- paragraph [ref=e389]: Zprávy, zápasy, tabulky, hráče, partnery i newsletter propojujete v jednom toku práce.
|
||||||
|
- generic [ref=e390]:
|
||||||
|
- generic [ref=e391]:
|
||||||
|
- generic [ref=e392]:
|
||||||
|
- generic [ref=e393]: krok 04
|
||||||
|
- generic [ref=e394]: "04"
|
||||||
|
- generic [ref=e395]: Publikujete a dál ladíte provoz
|
||||||
|
- paragraph [ref=e397]: Obsahový tým publikuje, vedení sleduje přehled a klub má jednu platformu připravenou pro další růst.
|
||||||
|
- generic [ref=e399]:
|
||||||
|
- generic [ref=e400]:
|
||||||
|
- generic [ref=e401]: FAQ
|
||||||
|
- heading "Krátké odpovědi na věci, které padnou nejdřív." [level=2] [ref=e402]
|
||||||
|
- paragraph [ref=e403]: Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení.
|
||||||
|
- generic [ref=e406]:
|
||||||
|
- heading "Je MyClub jen pro fotbalový klub?" [level=3] [ref=e408]:
|
||||||
|
- button "Je MyClub jen pro fotbalový klub?" [ref=e409]:
|
||||||
|
- text: Je MyClub jen pro fotbalový klub?
|
||||||
|
- img
|
||||||
|
- heading "Musí každou změnu řešit vývojář?" [level=3] [ref=e411]:
|
||||||
|
- button "Musí každou změnu řešit vývojář?" [ref=e412]:
|
||||||
|
- text: Musí každou změnu řešit vývojář?
|
||||||
|
- img
|
||||||
|
- heading "Co všechno v landingu myslíte pojmem provoz klubu?" [level=3] [ref=e414]:
|
||||||
|
- button "Co všechno v landingu myslíte pojmem provoz klubu?" [ref=e415]:
|
||||||
|
- text: Co všechno v landingu myslíte pojmem provoz klubu?
|
||||||
|
- img
|
||||||
|
- heading "Dá se MyClub nasadit vedle stávajícího backendu?" [level=3] [ref=e417]:
|
||||||
|
- button "Dá se MyClub nasadit vedle stávajícího backendu?" [ref=e418]:
|
||||||
|
- text: Dá se MyClub nasadit vedle stávajícího backendu?
|
||||||
|
- img
|
||||||
|
- heading "Jak vypadá první krok po odeslání formuláře?" [level=3] [ref=e420]:
|
||||||
|
- button "Jak vypadá první krok po odeslání formuláře?" [ref=e421]:
|
||||||
|
- text: Jak vypadá první krok po odeslání formuláře?
|
||||||
|
- img
|
||||||
|
- generic [ref=e424]:
|
||||||
|
- generic [ref=e425]:
|
||||||
|
- generic [ref=e426]: CTA a poptávka
|
||||||
|
- generic [ref=e427]:
|
||||||
|
- heading "Chcete si projít, jak bude MyClub fungovat pro váš klub?" [level=2] [ref=e428]
|
||||||
|
- paragraph [ref=e429]: Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
- generic [ref=e430]:
|
||||||
|
- generic [ref=e431]:
|
||||||
|
- img [ref=e433]
|
||||||
|
- paragraph [ref=e435]: Ukázka podle typu klubu a vašeho současného webu.
|
||||||
|
- generic [ref=e436]:
|
||||||
|
- img [ref=e438]
|
||||||
|
- paragraph [ref=e440]: Průchod obsahem, MyUIbrix builderem i provozní agendou.
|
||||||
|
- generic [ref=e441]:
|
||||||
|
- img [ref=e443]
|
||||||
|
- paragraph [ref=e445]: Doporučení, jak navázat na stávající backend a publikaci.
|
||||||
|
- generic [ref=e446]:
|
||||||
|
- generic [ref=e447]:
|
||||||
|
- img [ref=e448]
|
||||||
|
- text: Technická poznámka
|
||||||
|
- paragraph [ref=e451]:
|
||||||
|
- text: V developmentu funguje formulář přes Vite proxy na
|
||||||
|
- code [ref=e452]: localhost:8080
|
||||||
|
- text: . V produkci může zůstat same-origin nebo využít
|
||||||
|
- code [ref=e453]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- generic [ref=e454]:
|
||||||
|
- generic [ref=e455]:
|
||||||
|
- generic [ref=e456]: pracující formulář
|
||||||
|
- generic [ref=e457]: Pošlete poptávku přes stávající backend
|
||||||
|
- generic [ref=e459]:
|
||||||
|
- generic [ref=e460]:
|
||||||
|
- generic [ref=e461]:
|
||||||
|
- generic [ref=e462]: Jméno / klub
|
||||||
|
- textbox "Jméno / klub" [ref=e463]:
|
||||||
|
- /placeholder: Například FK Example / Jan Novák
|
||||||
|
- text: FK Example
|
||||||
|
- generic [ref=e464]:
|
||||||
|
- generic [ref=e465]: E-mail
|
||||||
|
- textbox "E-mail" [ref=e466]:
|
||||||
|
- /placeholder: vas@email.cz
|
||||||
|
- text: test@example.com
|
||||||
|
- generic [ref=e467]:
|
||||||
|
- generic [ref=e468]: Co chcete řešit
|
||||||
|
- textbox "Co chcete řešit" [ref=e469]: Chci produktovou ukázku
|
||||||
|
- generic [ref=e470]:
|
||||||
|
- generic [ref=e471]: Krátký kontext
|
||||||
|
- textbox "Krátký kontext" [ref=e472]:
|
||||||
|
- /placeholder: Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit.
|
||||||
|
- text: Zajímá mě, jak rychle umíme přepnout klubový web, obsah a zápasy do jednoho produktu.
|
||||||
|
- generic [ref=e473]:
|
||||||
|
- button "Domluvit ukázku" [ref=e474]:
|
||||||
|
- text: Domluvit ukázku
|
||||||
|
- img
|
||||||
|
- paragraph [ref=e475]:
|
||||||
|
- text: Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo nastavit
|
||||||
|
- code [ref=e476]: VITE_API_BASE_URL
|
||||||
|
- text: .
|
||||||
|
- paragraph [ref=e489]: Server zprávu přijal, ale nepodařilo se ji uložit. Zkontrolujte databázi a nastavení kontaktního formuláře na backendu.
|
||||||
|
- contentinfo [ref=e478]:
|
||||||
|
- generic [ref=e479]:
|
||||||
|
- generic [ref=e480]:
|
||||||
|
- paragraph [ref=e481]: MyClub
|
||||||
|
- paragraph [ref=e482]: Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
- generic [ref=e483]:
|
||||||
|
- link "Platforma" [ref=e484] [cursor=pointer]:
|
||||||
|
- /url: "#platforma"
|
||||||
|
- link "Ukázka" [ref=e485] [cursor=pointer]:
|
||||||
|
- /url: "#ukazka"
|
||||||
|
- link "Jak to funguje" [ref=e486] [cursor=pointer]:
|
||||||
|
- /url: "#workflow"
|
||||||
|
- link "FAQ" [ref=e487] [cursor=pointer]:
|
||||||
|
- /url: "#faq"
|
||||||
|
- link "Kontakt" [ref=e488] [cursor=pointer]:
|
||||||
|
- /url: "#kontakt"
|
||||||
|
After Width: | Height: | Size: 388 KiB |
@@ -47,7 +47,6 @@ class OfflineSyncService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.initializeNetworkListener();
|
this.initializeNetworkListener();
|
||||||
this.loadSyncQueue();
|
this.loadSyncQueue();
|
||||||
this.startPeriodicSync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initializeNetworkListener() {
|
private initializeNetworkListener() {
|
||||||
@@ -61,6 +60,9 @@ class OfflineSyncService {
|
|||||||
const stored = await AsyncStorage.getItem(SYNC_QUEUE_KEY);
|
const stored = await AsyncStorage.getItem(SYNC_QUEUE_KEY);
|
||||||
if (stored) {
|
if (stored) {
|
||||||
this.syncQueue = JSON.parse(stored);
|
this.syncQueue = JSON.parse(stored);
|
||||||
|
if (this.syncQueue.length > 0) {
|
||||||
|
this.startPeriodicSync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load sync queue:', error);
|
console.error('Failed to load sync queue:', error);
|
||||||
@@ -76,6 +78,10 @@ class OfflineSyncService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private startPeriodicSync() {
|
private startPeriodicSync() {
|
||||||
|
if (this.syncInterval) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Try to sync every 30 seconds when online
|
// Try to sync every 30 seconds when online
|
||||||
this.syncInterval = setInterval(() => {
|
this.syncInterval = setInterval(() => {
|
||||||
if (this.isOnline && this.syncQueue.length > 0) {
|
if (this.isOnline && this.syncQueue.length > 0) {
|
||||||
@@ -99,6 +105,7 @@ class OfflineSyncService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.syncQueue.push(syncItem);
|
this.syncQueue.push(syncItem);
|
||||||
|
this.startPeriodicSync();
|
||||||
this.saveSyncQueue();
|
this.saveSyncQueue();
|
||||||
|
|
||||||
// Try to sync immediately if online
|
// Try to sync immediately if online
|
||||||
@@ -135,6 +142,10 @@ class OfflineSyncService {
|
|||||||
|
|
||||||
this.syncQueue = remainingItems;
|
this.syncQueue = remainingItems;
|
||||||
this.saveSyncQueue();
|
this.saveSyncQueue();
|
||||||
|
|
||||||
|
if (this.syncQueue.length === 0) {
|
||||||
|
this.stopPeriodicSync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async processSyncItem(item: SyncItem, api: any) {
|
private async processSyncItem(item: SyncItem, api: any) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"lastUpdated":"2026-03-13T11:35:34+01:00"}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"baseURL": "http://127.0.0.1:8080/api/v1",
|
||||||
|
"duration_ms": 97,
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"path": "/events/upcoming",
|
||||||
|
"file": "events_upcoming.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/public/team-logo-overrides",
|
||||||
|
"file": "team_logo_overrides.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/competition-aliases",
|
||||||
|
"file": "competition_aliases.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/settings",
|
||||||
|
"file": "settings.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/seo",
|
||||||
|
"file": "seo.json",
|
||||||
|
"ok": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/articles?page=1\u0026page_size=10\u0026published=true",
|
||||||
|
"file": "articles.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/sponsors",
|
||||||
|
"file": "sponsors.json",
|
||||||
|
"ok": false,
|
||||||
|
"error": "unexpected status 500"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastUpdated": "2026-03-13T11:35:34+01:00"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"additional_meta":"","canonical_base_url":"","default_og_image_url":"","enable_indexing":false,"meta_keywords":"","site_description":"","site_title":"","twitter_handle":""}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"etag":"","fetched_at":"2026-03-13T11:35:34+01:00","last_modified":""}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package goosemigrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"fotbal-club/internal/dbschema"
|
||||||
|
|
||||||
|
"github.com/pressly/goose/v3"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
gormlogger "gorm.io/gorm/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
goose.AddMigrationContext(upBootstrapLegacySchema, downBootstrapLegacySchema)
|
||||||
|
}
|
||||||
|
|
||||||
|
func upBootstrapLegacySchema(ctx context.Context, tx *sql.Tx) error {
|
||||||
|
if _, err := tx.ExecContext(ctx, `
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||||
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||||
|
`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
gormDB, err := gorm.Open(postgres.New(postgres.Config{Conn: tx}), &gorm.Config{
|
||||||
|
DisableForeignKeyConstraintWhenMigrating: true,
|
||||||
|
Logger: gormlogger.Default.LogMode(gormlogger.Silent),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbschema.AutoMigrate(gormDB)
|
||||||
|
}
|
||||||
|
|
||||||
|
func downBootstrapLegacySchema(context.Context, *sql.Tx) error {
|
||||||
|
return errors.New("bootstrap schema migration is irreversible")
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- name: ListRecentOrderSummaries :many
|
||||||
|
SELECT
|
||||||
|
o.id,
|
||||||
|
o.order_number,
|
||||||
|
o.status,
|
||||||
|
o.total_amount_cents,
|
||||||
|
o.currency,
|
||||||
|
o.shipping_method,
|
||||||
|
o.shipping_price_cents,
|
||||||
|
o.created_at,
|
||||||
|
COALESCE(p.status, '') AS payment_status,
|
||||||
|
COALESCE(s.status, '') AS shipping_status
|
||||||
|
FROM eshop_orders AS o
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT ep.status
|
||||||
|
FROM eshop_payments AS ep
|
||||||
|
WHERE ep.order_id = o.id
|
||||||
|
AND ep.deleted_at IS NULL
|
||||||
|
ORDER BY ep.created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
) AS p ON TRUE
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT sl.status
|
||||||
|
FROM eshop_shipping_labels AS sl
|
||||||
|
WHERE sl.order_id = o.id
|
||||||
|
AND sl.deleted_at IS NULL
|
||||||
|
ORDER BY sl.created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
) AS s ON TRUE
|
||||||
|
WHERE o.deleted_at IS NULL
|
||||||
|
ORDER BY o.created_at DESC
|
||||||
|
LIMIT $1;
|
||||||
|
|
||||||
|
-- name: SummarizeOrderRevenue :one
|
||||||
|
SELECT
|
||||||
|
COUNT(*)::bigint AS order_count,
|
||||||
|
COALESCE(SUM(total_amount_cents), 0)::bigint AS gross_revenue_cents,
|
||||||
|
COALESCE(SUM(shipping_price_cents), 0)::bigint AS shipping_revenue_cents
|
||||||
|
FROM eshop_orders
|
||||||
|
WHERE deleted_at IS NULL
|
||||||
|
AND created_at >= $1
|
||||||
|
AND created_at < $2;
|
||||||
|
|
||||||
|
-- name: ListOrderStatusBreakdown :many
|
||||||
|
SELECT
|
||||||
|
status,
|
||||||
|
COUNT(*)::bigint AS order_count
|
||||||
|
FROM eshop_orders
|
||||||
|
WHERE deleted_at IS NULL
|
||||||
|
GROUP BY status
|
||||||
|
ORDER BY order_count DESC, status ASC;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
CREATE TABLE users (
|
||||||
|
id SERIAL PRIMARY KEY
|
||||||
|
);
|
||||||
@@ -51,7 +51,9 @@ func main() {
|
|||||||
// Optional migrations for eshop-specific tables only (will be added later)
|
// Optional migrations for eshop-specific tables only (will be added later)
|
||||||
runMigrations, _ := strconv.ParseBool(os.Getenv("RUN_MIGRATIONS"))
|
runMigrations, _ := strconv.ParseBool(os.Getenv("RUN_MIGRATIONS"))
|
||||||
if runMigrations {
|
if runMigrations {
|
||||||
log.Println("[eshop] RUN_MIGRATIONS is true, but no eshop-specific migrations are defined yet")
|
if err := database.MigrateDB(dbInstance); err != nil {
|
||||||
|
log.Fatalf("[eshop] Failed to run database migrations: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Gin router with a similar hardened stack as the main backend
|
// Initialize Gin router with a similar hardened stack as the main backend
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ COPY . .
|
|||||||
|
|
||||||
# Build app
|
# Build app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
ENV GENERATE_SOURCEMAP=false
|
|
||||||
ENV CI=true
|
|
||||||
ENV TSC_COMPILE_ON_ERROR=true
|
|
||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
<body>
|
<body>
|
||||||
<noscript>Pro zobrazení e-shopu je potřeba povolit JavaScript.</noscript>
|
<noscript>Pro zobrazení e-shopu je potřeba povolit JavaScript.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/index.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -3,10 +3,11 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "vite",
|
||||||
"build": "react-scripts build",
|
"dev": "vite",
|
||||||
"test": "react-scripts test",
|
"build": "vite build",
|
||||||
"eject": "react-scripts eject"
|
"preview": "vite preview",
|
||||||
|
"test": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^2.8.2",
|
"@chakra-ui/react": "^2.8.2",
|
||||||
@@ -15,18 +16,22 @@
|
|||||||
"@stripe/react-stripe-js": "^5.4.1",
|
"@stripe/react-stripe-js": "^5.4.1",
|
||||||
"@stripe/stripe-js": "^8.5.3",
|
"@stripe/stripe-js": "^8.5.3",
|
||||||
"@tanstack/react-query": "^4.36.1",
|
"@tanstack/react-query": "^4.36.1",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.13.6",
|
||||||
|
"dompurify": "^3.3.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.30.2",
|
||||||
"react-scripts": "5.0.1",
|
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.2.45",
|
"@types/react": "^18.2.45",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@types/react-router-dom": "^5.3.3"
|
"@types/react-router-dom": "^5.3.3",
|
||||||
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
|
"jsdom": "^26.1.0",
|
||||||
|
"vite": "^6.3.5",
|
||||||
|
"vitest": "^3.1.1"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useParams } from 'react-router-dom';
|
|||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { getProduct, addToCart, EshopProductVariant } from '../services/eshopApi';
|
import { getProduct, addToCart, EshopProductVariant } from '../services/eshopApi';
|
||||||
import { Box, Heading, Text, Image, Badge, HStack, VStack, Button, Select, useToast } from '@chakra-ui/react';
|
import { Box, Heading, Text, Image, Badge, HStack, VStack, Button, Select, useToast } from '@chakra-ui/react';
|
||||||
|
import { sanitizeRichHtml } from '../utils/sanitizeHtml';
|
||||||
|
|
||||||
const formatPrice = (cents: number, currency: string) => {
|
const formatPrice = (cents: number, currency: string) => {
|
||||||
const value = cents / 100;
|
const value = cents / 100;
|
||||||
@@ -20,6 +21,7 @@ const ProductDetailPage: React.FC = () => {
|
|||||||
enabled: !!slug,
|
enabled: !!slug,
|
||||||
});
|
});
|
||||||
const [variantId, setVariantId] = useState<number | undefined>(undefined);
|
const [variantId, setVariantId] = useState<number | undefined>(undefined);
|
||||||
|
const descriptionHtml = React.useMemo(() => sanitizeRichHtml(data?.description_html), [data?.description_html]);
|
||||||
|
|
||||||
if (isLoading) return <Text>Načítání produktu…</Text>;
|
if (isLoading) return <Text>Načítání produktu…</Text>;
|
||||||
if (isError || !data) return <Text>Produkt nebyl nalezen.</Text>;
|
if (isError || !data) return <Text>Produkt nebyl nalezen.</Text>;
|
||||||
@@ -76,9 +78,9 @@ const ProductDetailPage: React.FC = () => {
|
|||||||
<Button colorScheme="blue" onClick={handleAddToCart} maxW="260px">
|
<Button colorScheme="blue" onClick={handleAddToCart} maxW="260px">
|
||||||
Přidat do košíku
|
Přidat do košíku
|
||||||
</Button>
|
</Button>
|
||||||
{data.description_html && (
|
{descriptionHtml && (
|
||||||
<Box mt={4} fontSize="sm" color="gray.700">
|
<Box mt={4} fontSize="sm" color="gray.700">
|
||||||
<div dangerouslySetInnerHTML={{ __html: data.description_html }} />
|
<div dangerouslySetInnerHTML={{ __html: descriptionHtml }} />
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/// <reference types="react-scripts" />
|
/// <reference types="vite/client" />
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
|
const ADDITIONAL_TAGS = ['iframe'];
|
||||||
|
const ADDITIONAL_ATTRS = ['allow', 'allowfullscreen', 'class', 'rel', 'style', 'target'];
|
||||||
|
|
||||||
|
export function sanitizeRichHtml(html: string | null | undefined): string {
|
||||||
|
const sanitized = DOMPurify.sanitize(html ?? '', {
|
||||||
|
USE_PROFILES: { html: true },
|
||||||
|
ADD_TAGS: ADDITIONAL_TAGS,
|
||||||
|
ADD_ATTR: ADDITIONAL_ATTRS,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof window === 'undefined' || !sanitized) {
|
||||||
|
return sanitized;
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = window.document.createElement('template');
|
||||||
|
template.innerHTML = sanitized;
|
||||||
|
|
||||||
|
template.content.querySelectorAll<HTMLAnchorElement>('a[target="_blank"]').forEach((anchor) => {
|
||||||
|
const rel = new Set((anchor.getAttribute('rel') ?? '').split(/\s+/).filter(Boolean));
|
||||||
|
rel.add('noopener');
|
||||||
|
rel.add('noreferrer');
|
||||||
|
anchor.setAttribute('rel', Array.from(rel).join(' '));
|
||||||
|
});
|
||||||
|
|
||||||
|
return template.innerHTML;
|
||||||
|
}
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"baseUrl": "src",
|
"baseUrl": "src",
|
||||||
"types": []
|
"types": ["vite/client", "vitest/globals"]
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
|
function buildProcessEnv(mode: string, env: Record<string, string>, base: string) {
|
||||||
|
const processEnv: Record<string, string> = {
|
||||||
|
NODE_ENV: mode === 'production' ? 'production' : mode,
|
||||||
|
PUBLIC_URL: base === '/' ? '' : base.replace(/\/$/, ''),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(env)) {
|
||||||
|
if (key.startsWith('REACT_APP_')) {
|
||||||
|
processEnv[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineConfig(({ mode }) => {
|
||||||
|
const env = loadEnv(mode, process.cwd(), '');
|
||||||
|
const base = env.PUBLIC_URL ? (env.PUBLIC_URL.endsWith('/') ? env.PUBLIC_URL : `${env.PUBLIC_URL}/`) : '/';
|
||||||
|
const processEnv = buildProcessEnv(mode, env, base);
|
||||||
|
|
||||||
|
return {
|
||||||
|
base,
|
||||||
|
publicDir: 'public',
|
||||||
|
plugins: [react()],
|
||||||
|
define: {
|
||||||
|
'process.env': JSON.stringify(processEnv),
|
||||||
|
global: 'globalThis',
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'build',
|
||||||
|
assetsDir: 'static',
|
||||||
|
emptyOutDir: true,
|
||||||
|
sourcemap: false,
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 3100,
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://127.0.0.1:8082',
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 4174,
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
environment: 'jsdom',
|
||||||
|
globals: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -15,27 +15,7 @@ COPY . .
|
|||||||
|
|
||||||
# Build the app with production settings
|
# Build the app with production settings
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
# Disable ESLint during build to avoid CRA/ESLint v9 plugin incompatibilities
|
|
||||||
ENV DISABLE_ESLINT_PLUGIN=true
|
|
||||||
# Skip CRA preflight checks (peer deps, eslint presence) to prevent extra work in CI builds
|
|
||||||
ENV SKIP_PREFLIGHT_CHECK=true
|
|
||||||
# Disable source maps to reduce memory usage
|
|
||||||
ENV GENERATE_SOURCEMAP=false
|
|
||||||
# Reduce memory footprint - Node.js in Docker needs more conservative settings
|
|
||||||
ENV NODE_OPTIONS="--max-old-space-size=1024"
|
ENV NODE_OPTIONS="--max-old-space-size=1024"
|
||||||
# Limit webpack parallelism to reduce memory usage
|
|
||||||
ENV CI=true
|
|
||||||
# Allow build to continue even if TypeScript diagnostics exist; avoids heavy TS checks from blocking
|
|
||||||
ENV TSC_COMPILE_ON_ERROR=true
|
|
||||||
# Disable ForkTsCheckerWebpackPlugin via craco filter to further reduce memory
|
|
||||||
ENV DISABLE_TS_TYPECHECK=true
|
|
||||||
# Disable ESLint plugin completely
|
|
||||||
ENV ESLINT_NO_DEV_ERRORS=true
|
|
||||||
|
|
||||||
# Clean npm cache before build to free up memory
|
|
||||||
RUN npm cache clean --force 2>/dev/null || true
|
|
||||||
|
|
||||||
# Build with standard npm
|
|
||||||
RUN --mount=type=cache,target=/root/.npm \
|
RUN --mount=type=cache,target=/root/.npm \
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
webpack: {
|
|
||||||
alias: {
|
|
||||||
'@': path.resolve(__dirname, 'src/')
|
|
||||||
},
|
|
||||||
configure: (webpackConfig) => {
|
|
||||||
// Always remove ESLint for better performance
|
|
||||||
webpackConfig.plugins = (webpackConfig.plugins || []).filter((plugin) => {
|
|
||||||
const name = plugin && plugin.constructor && plugin.constructor.name;
|
|
||||||
if (name === 'ESLintWebpackPlugin') return false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Optimize for production builds
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
|
||||||
// Reduce memory usage during build
|
|
||||||
webpackConfig.optimization = {
|
|
||||||
...webpackConfig.optimization,
|
|
||||||
splitChunks: {
|
|
||||||
chunks: 'all',
|
|
||||||
cacheGroups: {
|
|
||||||
defaultVendors: {
|
|
||||||
test: /[\\/]node_modules[\\/]/,
|
|
||||||
priority: -10,
|
|
||||||
reuseExistingChunk: true,
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
minChunks: 2,
|
|
||||||
priority: -20,
|
|
||||||
reuseExistingChunk: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Use single runtime chunk
|
|
||||||
runtimeChunk: 'single',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Limit parallelism of existing minimizers to lower memory footprint
|
|
||||||
if (Array.isArray(webpackConfig.optimization.minimizer)) {
|
|
||||||
webpackConfig.optimization.minimizer = webpackConfig.optimization.minimizer.map((minimizer) => {
|
|
||||||
const name = minimizer && minimizer.constructor && minimizer.constructor.name;
|
|
||||||
if (name === 'TerserPlugin') {
|
|
||||||
if (minimizer.options) {
|
|
||||||
minimizer.options.parallel = false;
|
|
||||||
minimizer.options.extractComments = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (name === 'CssMinimizerPlugin' || name === 'CssMinimizerWebpackPlugin') {
|
|
||||||
if (minimizer.options) {
|
|
||||||
minimizer.options.parallel = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return minimizer;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable source maps if env variable is set
|
|
||||||
if (process.env.GENERATE_SOURCEMAP === 'false') {
|
|
||||||
webpackConfig.devtool = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return webpackConfig;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
|
<meta name="theme-color" content="#000000" />
|
||||||
|
<meta name="color-scheme" content="light dark" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="Oficiální webové stránky fotbalového klubu - aktuality, zápasy, tabulky, hráči a fotogalerie"
|
||||||
|
/>
|
||||||
|
<link rel="apple-touch-icon" href="/logo192.png" />
|
||||||
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link rel="preconnect" href="https://www.youtube.com" crossorigin />
|
||||||
|
<link rel="preconnect" href="https://i.ytimg.com" crossorigin />
|
||||||
|
<link rel="preconnect" href="https://s.ytimg.com" crossorigin />
|
||||||
|
<link rel="preconnect" href="https://www.google.com" crossorigin />
|
||||||
|
<title>Fotbal Club</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/index.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -3,18 +3,15 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "craco start",
|
"start": "vite",
|
||||||
"build": "craco build",
|
"dev": "vite",
|
||||||
"test": "craco test",
|
"build": "vite build",
|
||||||
"eject": "react-scripts eject",
|
"preview": "vite preview",
|
||||||
"dev": "bun start",
|
"test": "vitest run"
|
||||||
"dev:fast": "bun --hot start",
|
|
||||||
"build:bun": "bun run build"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^2.1.1",
|
"@chakra-ui/icons": "^2.1.1",
|
||||||
"@chakra-ui/react": "^2.8.2",
|
"@chakra-ui/react": "^2.8.2",
|
||||||
"@craco/craco": "^7.1.0",
|
|
||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@hookform/resolvers": "^3.3.4",
|
"@hookform/resolvers": "^3.3.4",
|
||||||
@@ -26,15 +23,15 @@
|
|||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"@tinymce/tinymce-react": "^6.3.0",
|
"@tinymce/tinymce-react": "^6.3.0",
|
||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/node": "^16.18.126",
|
"@types/node": "^20.17.47",
|
||||||
"@types/qrcode": "^1.5.6",
|
"@types/qrcode": "^1.5.6",
|
||||||
"@types/react": "^18.2.45",
|
"@types/react": "^18.2.45",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@types/react-frame-component": "^4.1.6",
|
"@types/react-frame-component": "^4.1.6",
|
||||||
"axios": "^1.6.2",
|
"axios": "^1.13.6",
|
||||||
"chart.js": "^4.4.1",
|
"chart.js": "^4.4.1",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"dompurify": "^3.2.6",
|
"dompurify": "^3.3.0",
|
||||||
"framer-motion": "^10.16.4",
|
"framer-motion": "^10.16.4",
|
||||||
"i18next": "^23.7.16",
|
"i18next": "^23.7.16",
|
||||||
"i18next-browser-languagedetector": "^7.2.0",
|
"i18next-browser-languagedetector": "^7.2.0",
|
||||||
@@ -58,8 +55,7 @@
|
|||||||
"react-image-crop": "^11.0.10",
|
"react-image-crop": "^11.0.10",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-quill": "^2.0.0",
|
"react-quill": "^2.0.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.30.2",
|
||||||
"react-scripts": "5.0.1",
|
|
||||||
"react-simple-maps": "^3.0.0",
|
"react-simple-maps": "^3.0.0",
|
||||||
"react-syntax-highlighter": "^15.6.6",
|
"react-syntax-highlighter": "^15.6.6",
|
||||||
"tinymce": "^8.2.2",
|
"tinymce": "^8.2.2",
|
||||||
@@ -76,9 +72,12 @@
|
|||||||
"@types/react-chartjs-2": "^2.0.2",
|
"@types/react-chartjs-2": "^2.0.2",
|
||||||
"@types/react-image-crop": "^8.1.6",
|
"@types/react-image-crop": "^8.1.6",
|
||||||
"@types/react-syntax-highlighter": "^15.5.13",
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
|
"@vitejs/plugin-react": "^4.4.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"http-proxy-middleware": "^3.0.5"
|
"jsdom": "^26.1.0",
|
||||||
|
"vite": "^6.3.5",
|
||||||
|
"vitest": "^3.1.1"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<!-- Club favicon/logo -->
|
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
||||||
<!-- Optional SVG logo if available in public folder (keeps ICO as fallback) -->
|
|
||||||
<!-- <link rel="icon" type="image/svg+xml" href="%PUBLIC_URL%/logo.svg" /> -->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
<meta name="color-scheme" content="light dark" />
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
content="Oficiální webové stránky fotbalového klubu - aktuality, zápasy, tabulky, hráči a fotogalerie"
|
|
||||||
/>
|
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
||||||
<!--
|
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
||||||
-->
|
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
||||||
<!-- Performance: preconnect to Google Fonts origins used by the app -->
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
||||||
<!-- Performance: preconnect to YouTube origins for faster video/thumbnail loads -->
|
|
||||||
<link rel="preconnect" href="https://www.youtube.com" crossorigin />
|
|
||||||
<link rel="preconnect" href="https://i.ytimg.com" crossorigin />
|
|
||||||
<link rel="preconnect" href="https://s.ytimg.com" crossorigin />
|
|
||||||
<link rel="preconnect" href="https://www.google.com" crossorigin />
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
<title>Fotbal Club</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
|
||||||
-->
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import React, { lazy, Suspense } from 'react';
|
import React, { lazy, Suspense } from 'react';
|
||||||
import { ChakraProvider, extendTheme, Spinner, Center, Box } from '@chakra-ui/react';
|
import { ChakraProvider, Spinner, Center, Box } from '@chakra-ui/react';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet } from 'react-router-dom';
|
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet } from 'react-router-dom';
|
||||||
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
import { AuthProvider, useAuth } from './contexts/AuthContext';
|
||||||
import { ClubThemeProvider } from './contexts/ClubThemeContext';
|
import { ClubThemeProvider } from './contexts/ClubThemeContext';
|
||||||
import { HelmetProvider } from 'react-helmet-async';
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
import { theme } from './App';
|
import { theme } from './theme/siteTheme';
|
||||||
import { useUmami } from './hooks/useUmami';
|
import { useUmami } from './hooks/useUmami';
|
||||||
import { useFontLoader } from './hooks/useFontLoader';
|
import { useFontLoader } from './hooks/useFontLoader';
|
||||||
import DefaultSEO from './components/seo/DefaultSEO';
|
import DefaultSEO from './components/seo/DefaultSEO';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { ChakraProvider, extendTheme } from '@chakra-ui/react';
|
import { ChakraProvider } from '@chakra-ui/react';
|
||||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet, useLocation } from 'react-router-dom';
|
import { BrowserRouter as Router, Routes, Route, Navigate, Outlet, useLocation } from 'react-router-dom';
|
||||||
import './styles/custom-scrollbar.css';
|
import './styles/custom-scrollbar.css';
|
||||||
@@ -94,6 +94,7 @@ import { useUmami } from './hooks/useUmami';
|
|||||||
import { checkin } from './services/engagement';
|
import { checkin } from './services/engagement';
|
||||||
import { useFontLoader } from './hooks/useFontLoader';
|
import { useFontLoader } from './hooks/useFontLoader';
|
||||||
import { usePublicSettings } from './hooks/usePublicSettings';
|
import { usePublicSettings } from './hooks/usePublicSettings';
|
||||||
|
import { theme } from './theme/siteTheme';
|
||||||
import { logAction } from './services/actionLog';
|
import { logAction } from './services/actionLog';
|
||||||
|
|
||||||
const RouteLogger: React.FC = () => {
|
const RouteLogger: React.FC = () => {
|
||||||
@@ -117,159 +118,6 @@ const queryClient = new QueryClient({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Theme configuration drawing colors from ClubTheme CSS variables for personalization
|
|
||||||
export const theme = extendTheme({
|
|
||||||
config: {
|
|
||||||
initialColorMode: 'light',
|
|
||||||
useSystemColorMode: false,
|
|
||||||
},
|
|
||||||
// Provide a brand color scale so colorScheme="brand" components style correctly
|
|
||||||
colors: {
|
|
||||||
brand: {
|
|
||||||
50: '#e6f7ff',
|
|
||||||
100: '#b3e0ff',
|
|
||||||
200: '#80caff',
|
|
||||||
300: '#4db3ff',
|
|
||||||
400: '#1a9cff',
|
|
||||||
500: 'var(--club-primary, #0b5cff)',
|
|
||||||
600: '#0066cc',
|
|
||||||
700: '#004d99',
|
|
||||||
800: '#003366',
|
|
||||||
900: '#001a33',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Semantic tokens allow live updates when ClubThemeContext changes CSS variables
|
|
||||||
semanticTokens: {
|
|
||||||
colors: {
|
|
||||||
'brand.primary': {
|
|
||||||
default: 'var(--club-primary, #0b5cff)',
|
|
||||||
},
|
|
||||||
'brand.secondary': {
|
|
||||||
default: 'var(--club-secondary, #ffd200)',
|
|
||||||
},
|
|
||||||
'brand.accent': {
|
|
||||||
default: 'var(--club-accent, #141414)',
|
|
||||||
},
|
|
||||||
'text.onPrimary': {
|
|
||||||
default: 'var(--club-text-on-primary, #ffffff)',
|
|
||||||
},
|
|
||||||
'bg.app': {
|
|
||||||
default: '#f8f9fb',
|
|
||||||
_dark: '#0f1115',
|
|
||||||
},
|
|
||||||
'text.app': {
|
|
||||||
default: '#1a1a1a',
|
|
||||||
_dark: '#e8eaf0',
|
|
||||||
},
|
|
||||||
// Backdrop/outline shades
|
|
||||||
'border.subtle': {
|
|
||||||
default: 'rgba(0,0,0,0.06)',
|
|
||||||
_dark: 'rgba(255,255,255,0.12)',
|
|
||||||
},
|
|
||||||
'bg.card': {
|
|
||||||
default: '#ffffff',
|
|
||||||
_dark: '#1a1d29',
|
|
||||||
},
|
|
||||||
'bg.elevated': {
|
|
||||||
default: '#ffffff',
|
|
||||||
_dark: '#242831',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
styles: {
|
|
||||||
global: {
|
|
||||||
'html, body, #root': {
|
|
||||||
height: '100%',
|
|
||||||
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
body: {
|
|
||||||
bg: 'bg.app',
|
|
||||||
color: 'text.app',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
'h1, h2, h3, h4, h5, h6': {
|
|
||||||
fontFamily: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
a: {
|
|
||||||
transition: 'color 0.2s ease',
|
|
||||||
},
|
|
||||||
'::selection': {
|
|
||||||
background: 'brand.accent',
|
|
||||||
color: 'black',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
Container: {
|
|
||||||
baseStyle: {
|
|
||||||
px: { base: 4, md: 6 },
|
|
||||||
},
|
|
||||||
sizes: {
|
|
||||||
'7xl': '88rem',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Button: {
|
|
||||||
baseStyle: {
|
|
||||||
fontWeight: '700',
|
|
||||||
borderRadius: 'md',
|
|
||||||
letterSpacing: '0.4px',
|
|
||||||
_hover: { transform: 'translateY(-1px)', boxShadow: 'md' },
|
|
||||||
_active: { transform: 'translateY(0)' },
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
solid: {
|
|
||||||
bg: 'brand.primary',
|
|
||||||
color: 'text.onPrimary',
|
|
||||||
_hover: { filter: 'brightness(0.95)' },
|
|
||||||
},
|
|
||||||
outline: {
|
|
||||||
border: '2px solid',
|
|
||||||
borderColor: 'brand.primary',
|
|
||||||
color: 'brand.primary',
|
|
||||||
_hover: { bg: 'rgba(0,0,0,0.02)' },
|
|
||||||
},
|
|
||||||
ghost: {
|
|
||||||
color: 'brand.secondary',
|
|
||||||
_hover: { bg: 'rgba(0,0,0,0.04)' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Card: {
|
|
||||||
baseStyle: {
|
|
||||||
container: {
|
|
||||||
borderRadius: 'lg',
|
|
||||||
boxShadow: 'sm',
|
|
||||||
overflow: 'hidden',
|
|
||||||
transition: 'all 0.2s',
|
|
||||||
borderWidth: '1px',
|
|
||||||
borderColor: 'border.subtle',
|
|
||||||
_hover: { transform: 'translateY(-4px)', boxShadow: 'lg' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Divider: {
|
|
||||||
baseStyle: {
|
|
||||||
borderColor: 'border.subtle',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Heading: {
|
|
||||||
baseStyle: {
|
|
||||||
fontFamily: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Text: {
|
|
||||||
baseStyle: {
|
|
||||||
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fonts: {
|
|
||||||
heading: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
body: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Component to initialize analytics inside Router context
|
// Component to initialize analytics inside Router context
|
||||||
const AnalyticsInitializer: React.FC = () => {
|
const AnalyticsInitializer: React.FC = () => {
|
||||||
useUmami();
|
useUmami();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { useAuth } from '../../contexts/AuthContext';
|
|||||||
import { Pencil, Trash2, Send, CheckCircle2 } from 'lucide-react';
|
import { Pencil, Trash2, Send, CheckCircle2 } from 'lucide-react';
|
||||||
import { Link as RouterLink } from 'react-router-dom';
|
import { Link as RouterLink } from 'react-router-dom';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { sanitizeRichHtml } from '../../utils/sanitizeHtml';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
targetType: 'article' | 'event' | 'gallery_album' | 'youtube_video';
|
targetType: 'article' | 'event' | 'gallery_album' | 'youtube_video';
|
||||||
@@ -382,7 +383,7 @@ const CommentsSection: React.FC<Props> = ({ targetType, targetId }) => {
|
|||||||
</VStack>
|
</VStack>
|
||||||
) : (
|
) : (
|
||||||
c.content_html ? (
|
c.content_html ? (
|
||||||
<Box sx={{ '.cw': { textDecoration: 'underline dotted', cursor: 'help' } }} dangerouslySetInnerHTML={{ __html: c.content_html }} />
|
<Box sx={{ '.cw': { textDecoration: 'underline dotted', cursor: 'help' } }} dangerouslySetInnerHTML={{ __html: sanitizeRichHtml(c.content_html) }} />
|
||||||
) : (
|
) : (
|
||||||
<Text whiteSpace="pre-wrap">{c.content}</Text>
|
<Text whiteSpace="pre-wrap">{c.content}</Text>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useCountdown } from '../../hooks/useCountdown';
|
||||||
|
|
||||||
|
const formatVerboseCountdown = (timeRemaining: number) => {
|
||||||
|
if (timeRemaining <= 0) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalSeconds = Math.floor(timeRemaining / 1000);
|
||||||
|
const days = Math.floor(totalSeconds / 86400);
|
||||||
|
const hours = Math.floor((totalSeconds % 86400) / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const seconds = totalSeconds % 60;
|
||||||
|
|
||||||
|
return `${days} d ${hours} h ${minutes} m ${seconds} s`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const buildKickoffIso = (date?: string, time?: string) => {
|
||||||
|
if (!date) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${date}T${(time || '00:00')}:00`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MatchCountdownText: React.FC<{
|
||||||
|
targetDate?: string | Date | null;
|
||||||
|
fallback?: string;
|
||||||
|
startedLabel?: string;
|
||||||
|
}> = ({ targetDate = null, fallback = '—', startedLabel = 'Začátek' }) => {
|
||||||
|
const { targetTime, timeRemaining } = useCountdown(targetDate, 1000);
|
||||||
|
|
||||||
|
if (!targetTime) {
|
||||||
|
return <>{fallback}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeRemaining <= 0) {
|
||||||
|
return <>{startedLabel}</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{formatVerboseCountdown(timeRemaining)}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default React.memo(MatchCountdownText);
|
||||||
@@ -130,6 +130,8 @@ interface ElementPosition {
|
|||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DragInsertPosition = 'before' | 'after';
|
||||||
|
|
||||||
const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onConfigChange }) => {
|
const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onConfigChange }) => {
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const isAdmin = user?.role === 'admin';
|
const isAdmin = user?.role === 'admin';
|
||||||
@@ -149,6 +151,7 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
const [elementOrder, setElementOrder] = useState<string[]>([]);
|
const [elementOrder, setElementOrder] = useState<string[]>([]);
|
||||||
const [draggedElement, setDraggedElement] = useState<string | null>(null);
|
const [draggedElement, setDraggedElement] = useState<string | null>(null);
|
||||||
const [dragOverElement, setDragOverElement] = useState<string | null>(null);
|
const [dragOverElement, setDragOverElement] = useState<string | null>(null);
|
||||||
|
const [dragOverPlacement, setDragOverPlacement] = useState<DragInsertPosition | null>(null);
|
||||||
const [viewport, setViewport] = useState<'desktop' | 'tablet' | 'mobile'>('desktop');
|
const [viewport, setViewport] = useState<'desktop' | 'tablet' | 'mobile'>('desktop');
|
||||||
const [elementStyles, setElementStyles] = useState<Record<string, any>>({});
|
const [elementStyles, setElementStyles] = useState<Record<string, any>>({});
|
||||||
const [showStylePanel, setShowStylePanel] = useState(false);
|
const [showStylePanel, setShowStylePanel] = useState(false);
|
||||||
@@ -163,6 +166,7 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
const [pendingInsertIndex, setPendingInsertIndex] = useState<number | null>(null);
|
const [pendingInsertIndex, setPendingInsertIndex] = useState<number | null>(null);
|
||||||
const [containerGridCols, setContainerGridCols] = useState<number>(0);
|
const [containerGridCols, setContainerGridCols] = useState<number>(0);
|
||||||
const elementOrderRef = useRef<string[]>([]);
|
const elementOrderRef = useRef<string[]>([]);
|
||||||
|
const draggedElementRef = useRef<string | null>(null);
|
||||||
useEffect(() => { elementOrderRef.current = elementOrder; }, [elementOrder]);
|
useEffect(() => { elementOrderRef.current = elementOrder; }, [elementOrder]);
|
||||||
const applyVisualReorderRef = useRef<(order: string[]) => void>(() => {});
|
const applyVisualReorderRef = useRef<(order: string[]) => void>(() => {});
|
||||||
|
|
||||||
@@ -221,6 +225,53 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
return getDefaultVariant(elementName);
|
return getDefaultVariant(elementName);
|
||||||
}, [getAvailableVariants, getDefaultVariant]);
|
}, [getAvailableVariants, getDefaultVariant]);
|
||||||
|
|
||||||
|
const getDropPlacement = useCallback((clientY: number, rect: Pick<DOMRect, 'top' | 'height'>): DragInsertPosition => {
|
||||||
|
return clientY < rect.top + (rect.height / 2) ? 'before' : 'after';
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const reorderElements = useCallback((
|
||||||
|
currentOrder: string[],
|
||||||
|
draggedName: string,
|
||||||
|
targetName: string,
|
||||||
|
placement: DragInsertPosition = 'before'
|
||||||
|
) => {
|
||||||
|
const draggedIndex = currentOrder.indexOf(draggedName);
|
||||||
|
const targetIndex = currentOrder.indexOf(targetName);
|
||||||
|
|
||||||
|
if (draggedIndex === -1 || targetIndex === -1 || draggedName === targetName) {
|
||||||
|
return currentOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextOrder = [...currentOrder];
|
||||||
|
nextOrder.splice(draggedIndex, 1);
|
||||||
|
const adjustedTargetIndex = nextOrder.indexOf(targetName);
|
||||||
|
const insertionIndex = placement === 'after' ? adjustedTargetIndex + 1 : adjustedTargetIndex;
|
||||||
|
nextOrder.splice(Math.max(0, insertionIndex), 0, draggedName);
|
||||||
|
const unchanged = nextOrder.length === currentOrder.length && nextOrder.every((name, index) => name === currentOrder[index]);
|
||||||
|
return unchanged ? currentOrder : nextOrder;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const resetDragState = useCallback(() => {
|
||||||
|
draggedElementRef.current = null;
|
||||||
|
setDraggedElement(null);
|
||||||
|
setDragOverElement(null);
|
||||||
|
setDragOverPlacement(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const commitElementOrderChange = useCallback((nextOrder: string[]) => {
|
||||||
|
setElementOrder(nextOrder);
|
||||||
|
setHasChanges(true);
|
||||||
|
|
||||||
|
if (isEditing) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
applyVisualReorderRef.current(nextOrder);
|
||||||
|
window.dispatchEvent(new CustomEvent('myuibrix-reorder', {
|
||||||
|
detail: { order: nextOrder, previewMode: true }
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [isEditing]);
|
||||||
|
|
||||||
// Draggable panel handlers
|
// Draggable panel handlers
|
||||||
const handlePanelMouseDown = useCallback((panelName: string, e: React.MouseEvent) => {
|
const handlePanelMouseDown = useCallback((panelName: string, e: React.MouseEvent) => {
|
||||||
// Only allow dragging from header area
|
// Only allow dragging from header area
|
||||||
@@ -681,6 +732,8 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
const overlay = document.createElement('div');
|
const overlay = document.createElement('div');
|
||||||
overlay.className = 'elementor-overlay';
|
overlay.className = 'elementor-overlay';
|
||||||
|
overlay.dataset.elementName = elementName;
|
||||||
|
overlay.setAttribute('data-editor-overlay', elementName);
|
||||||
overlay.style.cssText = `
|
overlay.style.cssText = `
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -732,6 +785,31 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const dragHandleBtn = document.createElement('button');
|
||||||
|
dragHandleBtn.textContent = '::';
|
||||||
|
dragHandleBtn.title = 'Přetáhnout pro změnu pořadí';
|
||||||
|
dragHandleBtn.setAttribute('aria-label', `Přetáhnout ${elementName}`);
|
||||||
|
dragHandleBtn.setAttribute('data-editor-drag-handle', elementName);
|
||||||
|
dragHandleBtn.style.cssText = `
|
||||||
|
background: ${secondaryColor};
|
||||||
|
color: ${clubTheme.textOnSecondary || 'white'};
|
||||||
|
border: none;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: grab;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
`;
|
||||||
|
dragHandleBtn.draggable = true;
|
||||||
|
dragHandleBtn.onmouseover = () => dragHandleBtn.style.transform = 'scale(1.1)';
|
||||||
|
dragHandleBtn.onmouseout = () => dragHandleBtn.style.transform = 'scale(1)';
|
||||||
|
|
||||||
// Edit button
|
// Edit button
|
||||||
const editBtn = document.createElement('button');
|
const editBtn = document.createElement('button');
|
||||||
editBtn.innerHTML = '⚙️';
|
editBtn.innerHTML = '⚙️';
|
||||||
@@ -842,6 +920,7 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use safeDOM to build overlay structure
|
// Use safeDOM to build overlay structure
|
||||||
|
safeDOM.appendChild(actionsBar, dragHandleBtn);
|
||||||
safeDOM.appendChild(actionsBar, editBtn);
|
safeDOM.appendChild(actionsBar, editBtn);
|
||||||
safeDOM.appendChild(actionsBar, moveUpBtn);
|
safeDOM.appendChild(actionsBar, moveUpBtn);
|
||||||
safeDOM.appendChild(actionsBar, moveDownBtn);
|
safeDOM.appendChild(actionsBar, moveDownBtn);
|
||||||
@@ -866,6 +945,24 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const applyOverlayIdleState = () => {
|
||||||
|
overlay.style.boxShadow = '';
|
||||||
|
if (selectedElement !== elementName) {
|
||||||
|
overlay.style.border = `2px dashed ${primaryColor}`;
|
||||||
|
overlay.style.background = `${primaryColor}15`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyOverlayDropIndicator = (placement: DragInsertPosition) => {
|
||||||
|
overlay.style.border = `3px solid ${secondaryColor}`;
|
||||||
|
overlay.style.background = `${secondaryColor}18`;
|
||||||
|
overlay.style.boxShadow = placement === 'before'
|
||||||
|
? `inset 0 4px 0 ${secondaryColor}`
|
||||||
|
: `inset 0 -4px 0 ${secondaryColor}`;
|
||||||
|
setDragOverElement(elementName);
|
||||||
|
setDragOverPlacement(placement);
|
||||||
|
};
|
||||||
|
|
||||||
// Click to auto-select and open style panel
|
// Click to auto-select and open style panel
|
||||||
overlay.addEventListener('click', (e) => {
|
overlay.addEventListener('click', (e) => {
|
||||||
// Don't trigger if clicking on action buttons
|
// Don't trigger if clicking on action buttons
|
||||||
@@ -895,6 +992,7 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
overlay.addEventListener('mouseleave', () => {
|
overlay.addEventListener('mouseleave', () => {
|
||||||
setHoveredElement(null);
|
setHoveredElement(null);
|
||||||
|
overlay.style.boxShadow = '';
|
||||||
if (selectedElement !== elementName) {
|
if (selectedElement !== elementName) {
|
||||||
overlay.style.border = '2px dashed transparent';
|
overlay.style.border = '2px dashed transparent';
|
||||||
overlay.style.background = 'transparent';
|
overlay.style.background = 'transparent';
|
||||||
@@ -958,57 +1056,77 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
// per-column insert handled by elementor-col-picker buttons above
|
// per-column insert handled by elementor-col-picker buttons above
|
||||||
|
|
||||||
// Make overlay draggable
|
dragHandleBtn.addEventListener('dragstart', (e) => {
|
||||||
overlay.draggable = true;
|
|
||||||
overlay.addEventListener('dragstart', (e) => {
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
try { (e as DragEvent).dataTransfer?.setData('text/plain', elementName); } catch {}
|
try { (e as DragEvent).dataTransfer?.setData('text/plain', elementName); } catch {}
|
||||||
|
try {
|
||||||
|
if ((e as DragEvent).dataTransfer) {
|
||||||
|
(e as DragEvent).dataTransfer!.effectAllowed = 'move';
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
draggedElementRef.current = elementName;
|
||||||
setDraggedElement(elementName);
|
setDraggedElement(elementName);
|
||||||
|
setDragOverElement(null);
|
||||||
|
setDragOverPlacement(null);
|
||||||
|
dragHandleBtn.style.cursor = 'grabbing';
|
||||||
overlay.style.opacity = '0.5';
|
overlay.style.opacity = '0.5';
|
||||||
});
|
});
|
||||||
|
|
||||||
overlay.addEventListener('dragend', (e) => {
|
dragHandleBtn.addEventListener('dragend', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
dragHandleBtn.style.cursor = 'grab';
|
||||||
overlay.style.opacity = '1';
|
overlay.style.opacity = '1';
|
||||||
setDraggedElement(null);
|
overlay.style.boxShadow = '';
|
||||||
|
resetDragState();
|
||||||
|
});
|
||||||
|
|
||||||
|
overlay.addEventListener('dragenter', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
const activeDragged = draggedElementRef.current;
|
||||||
|
if (activeDragged && activeDragged !== elementName) {
|
||||||
|
const placement = getDropPlacement((e as DragEvent).clientY, overlay.getBoundingClientRect());
|
||||||
|
applyOverlayDropIndicator(placement);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
overlay.addEventListener('dragover', (e) => {
|
overlay.addEventListener('dragover', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
try { (e as DragEvent).dataTransfer!.dropEffect = 'move'; } catch {}
|
try { (e as DragEvent).dataTransfer!.dropEffect = 'move'; } catch {}
|
||||||
if (draggedElement && draggedElement !== elementName) {
|
const activeDragged = draggedElementRef.current;
|
||||||
overlay.style.border = `3px solid ${secondaryColor}`;
|
if (activeDragged && activeDragged !== elementName) {
|
||||||
setDragOverElement(elementName);
|
const placement = getDropPlacement((e as DragEvent).clientY, overlay.getBoundingClientRect());
|
||||||
|
applyOverlayDropIndicator(placement);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
overlay.addEventListener('dragleave', (e) => {
|
overlay.addEventListener('dragleave', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (selectedElement !== elementName) {
|
const nextTarget = document.elementFromPoint((e as DragEvent).clientX, (e as DragEvent).clientY);
|
||||||
overlay.style.border = `2px dashed ${primaryColor}`;
|
if (nextTarget && overlay.contains(nextTarget)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
applyOverlayIdleState();
|
||||||
setDragOverElement(null);
|
setDragOverElement(null);
|
||||||
|
setDragOverPlacement(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
overlay.addEventListener('drop', (e) => {
|
overlay.addEventListener('drop', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (draggedElement && draggedElement !== elementName) {
|
const activeDragged = draggedElementRef.current;
|
||||||
// Reorder elements
|
if (activeDragged && activeDragged !== elementName) {
|
||||||
const newOrder = [...elementOrderRef.current];
|
const placement = dragOverPlacement || getDropPlacement((e as DragEvent).clientY, overlay.getBoundingClientRect());
|
||||||
const draggedIndex = newOrder.indexOf(draggedElement as string);
|
const newOrder = reorderElements(elementOrderRef.current, activeDragged, elementName, placement);
|
||||||
const targetIndex = newOrder.indexOf(elementName);
|
|
||||||
|
|
||||||
if (draggedIndex !== -1 && targetIndex !== -1) {
|
if (newOrder !== elementOrderRef.current) {
|
||||||
newOrder.splice(draggedIndex, 1);
|
pushHistorySnapshot();
|
||||||
newOrder.splice(targetIndex, 0, draggedElement as string);
|
commitElementOrderChange(newOrder);
|
||||||
setElementOrder(newOrder);
|
|
||||||
setHasChanges(true);
|
|
||||||
applyVisualReorderRef.current(newOrder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
overlay.style.border = `2px dashed ${primaryColor}`;
|
applyOverlayIdleState();
|
||||||
|
resetDragState();
|
||||||
setDragOverElement(null);
|
setDragOverElement(null);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1069,7 +1187,22 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
clearTimeout(debounceTimerRef.current);
|
clearTimeout(debounceTimerRef.current);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, [isEditing, selectedElement, pageType, elementOrder, visibleElements]);
|
}, [
|
||||||
|
isEditing,
|
||||||
|
selectedElement,
|
||||||
|
pageType,
|
||||||
|
elementOrder,
|
||||||
|
visibleElements,
|
||||||
|
containerGridCols,
|
||||||
|
primaryColor,
|
||||||
|
secondaryColor,
|
||||||
|
clubTheme.textOnSecondary,
|
||||||
|
getDropPlacement,
|
||||||
|
reorderElements,
|
||||||
|
resetDragState,
|
||||||
|
pushHistorySnapshot,
|
||||||
|
commitElementOrderChange,
|
||||||
|
]);
|
||||||
|
|
||||||
// Update selected element overlay styling
|
// Update selected element overlay styling
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -1425,17 +1558,8 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
const newOrder = [...elementOrder];
|
const newOrder = [...elementOrder];
|
||||||
[newOrder[currentIndex - 1], newOrder[currentIndex]] = [newOrder[currentIndex], newOrder[currentIndex - 1]];
|
[newOrder[currentIndex - 1], newOrder[currentIndex]] = [newOrder[currentIndex], newOrder[currentIndex - 1]];
|
||||||
setElementOrder(newOrder);
|
commitElementOrderChange(newOrder);
|
||||||
setHasChanges(true);
|
}, [elementOrder, commitElementOrderChange, pushHistorySnapshot]);
|
||||||
|
|
||||||
// Trigger reorder event and apply visual reordering
|
|
||||||
if (isEditing) {
|
|
||||||
applyVisualReorder(newOrder);
|
|
||||||
window.dispatchEvent(new CustomEvent('myuibrix-reorder', {
|
|
||||||
detail: { order: newOrder, previewMode: true }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [elementOrder, isEditing, applyVisualReorder]);
|
|
||||||
|
|
||||||
const handleMoveDown = useCallback((elementName: string) => {
|
const handleMoveDown = useCallback((elementName: string) => {
|
||||||
pushHistorySnapshot();
|
pushHistorySnapshot();
|
||||||
@@ -1444,83 +1568,70 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
const newOrder = [...elementOrder];
|
const newOrder = [...elementOrder];
|
||||||
[newOrder[currentIndex], newOrder[currentIndex + 1]] = [newOrder[currentIndex + 1], newOrder[currentIndex]];
|
[newOrder[currentIndex], newOrder[currentIndex + 1]] = [newOrder[currentIndex + 1], newOrder[currentIndex]];
|
||||||
setElementOrder(newOrder);
|
commitElementOrderChange(newOrder);
|
||||||
setHasChanges(true);
|
}, [elementOrder, commitElementOrderChange, pushHistorySnapshot]);
|
||||||
|
|
||||||
// Trigger reorder event and apply visual reordering
|
|
||||||
if (isEditing) {
|
|
||||||
applyVisualReorder(newOrder);
|
|
||||||
window.dispatchEvent(new CustomEvent('myuibrix-reorder', {
|
|
||||||
detail: { order: newOrder, previewMode: true }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [elementOrder, isEditing, applyVisualReorder]);
|
|
||||||
|
|
||||||
|
|
||||||
// Drag and drop handlers with improved state management
|
// Drag and drop handlers with improved state management
|
||||||
const handleDragStart = useCallback((elementName: string, e: React.DragEvent) => {
|
const handleDragStart = useCallback((elementName: string, e: React.DragEvent) => {
|
||||||
|
const handle = (e.target as HTMLElement | null)?.closest('[data-drag-handle="true"]');
|
||||||
|
if (!handle) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
e.dataTransfer.setData('text/html', elementName);
|
e.dataTransfer.setData('text/plain', elementName);
|
||||||
|
draggedElementRef.current = elementName;
|
||||||
setDraggedElement(elementName);
|
setDraggedElement(elementName);
|
||||||
|
setDragOverElement(null);
|
||||||
|
setDragOverPlacement(null);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDragOver = useCallback((e: React.DragEvent, elementName: string) => {
|
const handleDragOver = useCallback((e: React.DragEvent, elementName: string) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.dataTransfer.dropEffect = 'move';
|
e.dataTransfer.dropEffect = 'move';
|
||||||
if (draggedElement !== elementName) {
|
const activeDragged = draggedElementRef.current;
|
||||||
|
if (activeDragged && activeDragged !== elementName) {
|
||||||
|
const placement = getDropPlacement(e.clientY, (e.currentTarget as HTMLElement).getBoundingClientRect());
|
||||||
setDragOverElement(elementName);
|
setDragOverElement(elementName);
|
||||||
|
setDragOverPlacement(placement);
|
||||||
}
|
}
|
||||||
}, [draggedElement]);
|
}, [getDropPlacement]);
|
||||||
|
|
||||||
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
const handleDragLeave = useCallback((e: React.DragEvent) => {
|
||||||
// Only clear if we're leaving to a non-child element
|
// Only clear if we're leaving to a non-child element
|
||||||
const relatedTarget = e.relatedTarget as HTMLElement;
|
const relatedTarget = e.relatedTarget as HTMLElement;
|
||||||
if (!relatedTarget || !(e.currentTarget as HTMLElement).contains(relatedTarget)) {
|
if (!relatedTarget || !(e.currentTarget as HTMLElement).contains(relatedTarget)) {
|
||||||
setDragOverElement(null);
|
setDragOverElement(null);
|
||||||
|
setDragOverPlacement(null);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDragEnd = useCallback(() => {
|
const handleDragEnd = useCallback(() => {
|
||||||
setDraggedElement(null);
|
resetDragState();
|
||||||
setDragOverElement(null);
|
}, [resetDragState]);
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleDrop = useCallback((e: React.DragEvent, targetElementName: string) => {
|
const handleDrop = useCallback((e: React.DragEvent, targetElementName: string) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
const activeDragged = draggedElementRef.current;
|
||||||
|
|
||||||
if (!draggedElement || draggedElement === targetElementName) {
|
if (!activeDragged || activeDragged === targetElementName) {
|
||||||
setDraggedElement(null);
|
resetDragState();
|
||||||
setDragOverElement(null);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newOrder = [...elementOrder];
|
const placement = dragOverPlacement || getDropPlacement(e.clientY, (e.currentTarget as HTMLElement).getBoundingClientRect());
|
||||||
const draggedIndex = newOrder.indexOf(draggedElement);
|
const newOrder = reorderElements(elementOrder, activeDragged, targetElementName, placement);
|
||||||
const targetIndex = newOrder.indexOf(targetElementName);
|
|
||||||
|
|
||||||
if (draggedIndex === -1 || targetIndex === -1) {
|
if (newOrder === elementOrder) {
|
||||||
setDraggedElement(null);
|
resetDragState();
|
||||||
setDragOverElement(null);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove dragged element and insert at target position
|
pushHistorySnapshot();
|
||||||
newOrder.splice(draggedIndex, 1);
|
commitElementOrderChange(newOrder);
|
||||||
newOrder.splice(targetIndex, 0, draggedElement);
|
resetDragState();
|
||||||
|
}, [dragOverPlacement, elementOrder, getDropPlacement, reorderElements, pushHistorySnapshot, commitElementOrderChange, resetDragState]);
|
||||||
setElementOrder(newOrder);
|
|
||||||
setHasChanges(true);
|
|
||||||
setDraggedElement(null);
|
|
||||||
setDragOverElement(null);
|
|
||||||
|
|
||||||
// Apply visual reordering
|
|
||||||
if (isEditing) {
|
|
||||||
applyVisualReorder(newOrder);
|
|
||||||
window.dispatchEvent(new CustomEvent('myuibrix-reorder', {
|
|
||||||
detail: { order: newOrder, previewMode: true }
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [draggedElement, elementOrder, isEditing, applyVisualReorder]);
|
|
||||||
|
|
||||||
// Start with a blank layout: hide all elements and clear order
|
// Start with a blank layout: hide all elements and clear order
|
||||||
const handleStartBlank = useCallback(() => {
|
const handleStartBlank = useCallback(() => {
|
||||||
@@ -2661,6 +2772,8 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
|
|
||||||
const isDragging = draggedElement === elementName;
|
const isDragging = draggedElement === elementName;
|
||||||
const isDragOver = dragOverElement === elementName;
|
const isDragOver = dragOverElement === elementName;
|
||||||
|
const isDragOverBefore = isDragOver && dragOverPlacement === 'before';
|
||||||
|
const isDragOverAfter = isDragOver && dragOverPlacement === 'after';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -2668,16 +2781,24 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
p={3}
|
p={3}
|
||||||
borderRadius="lg"
|
borderRadius="lg"
|
||||||
border="2px"
|
border="2px"
|
||||||
borderColor={isDragOver ? primaryColor : isSelected ? secondaryColor : 'gray.200'}
|
borderColor={isSelected ? secondaryColor : isDragOver ? primaryColor : 'gray.200'}
|
||||||
bgGradient={isDragging ? 'linear(to-r, gray.100, gray.200)' : isSelected ? `linear(135deg, ${secondaryColor}15, ${secondaryColor}25)` : isVisible ? 'linear(to-r, white, gray.50)' : 'linear(to-r, gray.100, gray.150)'}
|
bgGradient={isDragging ? 'linear(to-r, gray.100, gray.200)' : isSelected ? `linear(135deg, ${secondaryColor}15, ${secondaryColor}25)` : isVisible ? 'linear(to-r, white, gray.50)' : 'linear(to-r, gray.100, gray.150)'}
|
||||||
cursor={isDragging ? 'grabbing' : 'grab'}
|
cursor={isDragging ? 'grabbing' : 'grab'}
|
||||||
opacity={isDragging ? 0.6 : isVisible ? 1 : 0.5}
|
opacity={isDragging ? 0.6 : isVisible ? 1 : 0.5}
|
||||||
transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
|
transition="all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
|
||||||
transform={isDragOver ? 'scale(1.03) translateX(8px)' : undefined}
|
transform={isDragOver ? 'scale(1.02) translateX(6px)' : undefined}
|
||||||
boxShadow={isSelected ? '0 4px 12px rgba(0,0,0,0.1)' : '0 2px 4px rgba(0,0,0,0.05)'}
|
boxShadow={
|
||||||
|
isDragOverBefore
|
||||||
|
? `inset 0 4px 0 ${primaryColor}, 0 6px 16px rgba(0,0,0,0.12)`
|
||||||
|
: isDragOverAfter
|
||||||
|
? `inset 0 -4px 0 ${primaryColor}, 0 6px 16px rgba(0,0,0,0.12)`
|
||||||
|
: isSelected
|
||||||
|
? '0 4px 12px rgba(0,0,0,0.1)'
|
||||||
|
: '0 2px 4px rgba(0,0,0,0.05)'
|
||||||
|
}
|
||||||
_hover={{
|
_hover={{
|
||||||
borderColor: secondaryColor,
|
borderColor: secondaryColor,
|
||||||
transform: isDragOver ? 'scale(1.03) translateX(8px)' : 'translateX(6px) translateY(-2px)',
|
transform: isDragOver ? 'scale(1.02) translateX(6px)' : 'translateX(6px) translateY(-2px)',
|
||||||
boxShadow: '0 6px 16px rgba(0,0,0,0.12)'
|
boxShadow: '0 6px 16px rgba(0,0,0,0.12)'
|
||||||
}}
|
}}
|
||||||
draggable
|
draggable
|
||||||
@@ -2708,13 +2829,21 @@ const MyUIbrixStyleEditor: React.FC<MyUIbrixStyleEditorProps> = ({ pageType, onC
|
|||||||
>
|
>
|
||||||
<Flex align="center" justify="space-between">
|
<Flex align="center" justify="space-between">
|
||||||
<HStack flex={1} spacing={2}>
|
<HStack flex={1} spacing={2}>
|
||||||
|
<Box
|
||||||
|
data-drag-handle="true"
|
||||||
|
p={1.5}
|
||||||
|
borderRadius="md"
|
||||||
|
bg={isDragOver ? `${primaryColor}18` : 'gray.100'}
|
||||||
|
cursor={isDragging ? 'grabbing' : 'grab'}
|
||||||
|
_hover={{ bg: `${primaryColor}15` }}
|
||||||
|
>
|
||||||
<Icon
|
<Icon
|
||||||
as={FaGripVertical}
|
as={FaGripVertical}
|
||||||
boxSize={4}
|
boxSize={4}
|
||||||
color="gray.400"
|
color="gray.500"
|
||||||
cursor="grab"
|
pointerEvents="none"
|
||||||
_active={{ cursor: 'grabbing' }}
|
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
p={2}
|
p={2}
|
||||||
bg={isSelected ? secondaryColor : `${secondaryColor}20`}
|
bg={isSelected ? secondaryColor : `${secondaryColor}20`}
|
||||||
|
|||||||
@@ -0,0 +1,129 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
type HomeCardsSkeletonProps = {
|
||||||
|
actionWidth?: number | string;
|
||||||
|
cardCount?: number;
|
||||||
|
cardHeight?: number | string;
|
||||||
|
columns?: string;
|
||||||
|
layout?: 'grid' | 'carousel' | 'list';
|
||||||
|
minCardWidth?: number | string;
|
||||||
|
titleWidth?: number | string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SkeletonBar: React.FC<{ height?: number | string; width?: number | string }> = ({
|
||||||
|
height = 14,
|
||||||
|
width = '100%',
|
||||||
|
}) => (
|
||||||
|
<div
|
||||||
|
className="skeleton"
|
||||||
|
style={{
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
borderRadius: 999,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const SectionHeadSkeleton: React.FC<{
|
||||||
|
actionWidth?: number | string;
|
||||||
|
titleWidth?: number | string;
|
||||||
|
}> = ({
|
||||||
|
actionWidth = 104,
|
||||||
|
titleWidth = 180,
|
||||||
|
}) => (
|
||||||
|
<div className="section-head" style={{ marginTop: 0 }}>
|
||||||
|
<SkeletonBar height={24} width={titleWidth} />
|
||||||
|
<SkeletonBar height={14} width={actionWidth} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const HomeHeroSkeleton: React.FC = () => (
|
||||||
|
<div className="hero-grid" aria-hidden="true">
|
||||||
|
<div className="hero-card big skeleton" style={{ borderRadius: 16 }} />
|
||||||
|
<div className="small-col">
|
||||||
|
<div className="hero-card small skeleton" style={{ borderRadius: 16 }} />
|
||||||
|
<div className="hero-card small skeleton" style={{ borderRadius: 16 }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const HomeCardsSkeleton: React.FC<HomeCardsSkeletonProps> = ({
|
||||||
|
actionWidth,
|
||||||
|
cardCount = 3,
|
||||||
|
cardHeight = 220,
|
||||||
|
columns = 'repeat(3, minmax(0, 1fr))',
|
||||||
|
layout = 'grid',
|
||||||
|
minCardWidth = 260,
|
||||||
|
titleWidth,
|
||||||
|
}) => {
|
||||||
|
const containerStyle: React.CSSProperties =
|
||||||
|
layout === 'carousel'
|
||||||
|
? {
|
||||||
|
display: 'flex',
|
||||||
|
gap: 18,
|
||||||
|
overflow: 'hidden',
|
||||||
|
padding: '8px 2px 16px 2px',
|
||||||
|
}
|
||||||
|
: layout === 'list'
|
||||||
|
? {
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr',
|
||||||
|
gap: 12,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: columns,
|
||||||
|
gap: 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div aria-hidden="true">
|
||||||
|
<SectionHeadSkeleton actionWidth={actionWidth} titleWidth={titleWidth} />
|
||||||
|
<div style={containerStyle}>
|
||||||
|
{Array.from({ length: cardCount }).map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="card skeleton"
|
||||||
|
style={{
|
||||||
|
borderRadius: 16,
|
||||||
|
flex: layout === 'carousel' ? '0 0 auto' : undefined,
|
||||||
|
height: cardHeight,
|
||||||
|
minWidth: layout === 'carousel' ? minCardWidth : undefined,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const HomeStandingsSkeleton: React.FC = () => (
|
||||||
|
<div aria-hidden="true">
|
||||||
|
<SectionHeadSkeleton actionWidth={92} titleWidth={140} />
|
||||||
|
<div className="table-card">
|
||||||
|
<div className="standings">
|
||||||
|
{Array.from({ length: 8 }).map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="standing-row skeleton"
|
||||||
|
style={{ borderRadius: 12 }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const HomeSponsorsSkeleton: React.FC = () => (
|
||||||
|
<div aria-hidden="true">
|
||||||
|
<div className="sponsors-grid">
|
||||||
|
{Array.from({ length: 8 }).map((_, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="sponsor-tile skeleton"
|
||||||
|
style={{ minHeight: 90, borderRadius: 12 }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FiChevronLeft, FiChevronRight } from 'react-icons/fi';
|
import { FiChevronLeft, FiChevronRight } from 'react-icons/fi';
|
||||||
import { TeamLogo } from '../common/TeamLogo';
|
import { TeamLogo } from '../common/TeamLogo';
|
||||||
|
import MatchCountdownText from '../common/MatchCountdownText';
|
||||||
import { sanitizeClubName } from '../../utils/url';
|
import { sanitizeClubName } from '../../utils/url';
|
||||||
|
|
||||||
export type NextMatchData = {
|
export type NextMatchData = {
|
||||||
@@ -17,11 +18,12 @@ const NextMatch: React.FC<{
|
|||||||
data: NextMatchData | null;
|
data: NextMatchData | null;
|
||||||
competitionName?: string;
|
competitionName?: string;
|
||||||
countdown?: string;
|
countdown?: string;
|
||||||
|
kickoffIso?: string | null;
|
||||||
onPrev?: () => void;
|
onPrev?: () => void;
|
||||||
onNext?: () => void;
|
onNext?: () => void;
|
||||||
onOpen?: () => void;
|
onOpen?: () => void;
|
||||||
elementProps?: any;
|
elementProps?: any;
|
||||||
}> = ({ data, competitionName, countdown, onPrev, onNext, onOpen, elementProps }) => {
|
}> = ({ data, competitionName, countdown, kickoffIso = null, onPrev, onNext, onOpen, elementProps }) => {
|
||||||
const show = data;
|
const show = data;
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
@@ -63,7 +65,7 @@ const NextMatch: React.FC<{
|
|||||||
{competitionName && (
|
{competitionName && (
|
||||||
<div style={{ fontSize: '0.8rem', opacity: 0.85, marginBottom: 4 }}>{competitionName}</div>
|
<div style={{ fontSize: '0.8rem', opacity: 0.85, marginBottom: 4 }}>{competitionName}</div>
|
||||||
)}
|
)}
|
||||||
{countdown || '—'}
|
{countdown ? countdown : <MatchCountdownText targetDate={kickoffIso} />}
|
||||||
<div style={{ fontSize: '0.8rem', opacity: 0.85 }}>Začátek zápasu</div>
|
<div style={{ fontSize: '0.8rem', opacity: 0.85 }}>Začátek zápasu</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,23 @@ export interface NavbarData {
|
|||||||
hasGallery: boolean;
|
hasGallery: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CachedNavigationData = Pick<NavbarData, 'categories' | 'dynamicNavItems'>;
|
||||||
|
type CachedAvailabilityData = Pick<
|
||||||
|
NavbarData,
|
||||||
|
'hasTables' | 'hasActivities' | 'hasPlayers' | 'hasArticles' | 'hasVideos' | 'hasGallery'
|
||||||
|
>;
|
||||||
|
|
||||||
|
type CacheEntry<T> = {
|
||||||
|
expiresAt: number;
|
||||||
|
value: T;
|
||||||
|
};
|
||||||
|
|
||||||
|
const NAVBAR_CACHE_TTL_MS = 5 * 60 * 1000;
|
||||||
|
let cachedNavigationData: CacheEntry<CachedNavigationData> | null = null;
|
||||||
|
let navigationRequest: Promise<CachedNavigationData> | null = null;
|
||||||
|
let cachedAvailabilityData: CacheEntry<CachedAvailabilityData> | null = null;
|
||||||
|
let availabilityRequest: Promise<CachedAvailabilityData> | null = null;
|
||||||
|
|
||||||
export const useNavbarData = (isAdmin: boolean, settings?: any): NavbarData => {
|
export const useNavbarData = (isAdmin: boolean, settings?: any): NavbarData => {
|
||||||
const [categories, setCategories] = useState<Category[] | null>(null);
|
const [categories, setCategories] = useState<Category[] | null>(null);
|
||||||
const [dynamicNavItems, setDynamicNavItems] = useState<NavigationItem[]>([]);
|
const [dynamicNavItems, setDynamicNavItems] = useState<NavigationItem[]>([]);
|
||||||
@@ -30,63 +47,90 @@ export const useNavbarData = (isAdmin: boolean, settings?: any): NavbarData => {
|
|||||||
const [hasArticles, setHasArticles] = useState<boolean>(false);
|
const [hasArticles, setHasArticles] = useState<boolean>(false);
|
||||||
const [hasVideos, setHasVideos] = useState<boolean>(false);
|
const [hasVideos, setHasVideos] = useState<boolean>(false);
|
||||||
const [hasGallery, setHasGallery] = useState<boolean>(false);
|
const [hasGallery, setHasGallery] = useState<boolean>(false);
|
||||||
|
const settingsCategories = Array.isArray(settings?.categories) ? (settings.categories as Category[]) : null;
|
||||||
|
const settingsHasVideos = Boolean(
|
||||||
|
settings?.youtube_url ||
|
||||||
|
settings?.videos_items?.length ||
|
||||||
|
settings?.videos?.length
|
||||||
|
);
|
||||||
|
const settingsHasGallery = Boolean(settings?.gallery_url || settings?.zonerama_url);
|
||||||
|
|
||||||
// Combined data loading effect
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let active = true;
|
let active = true;
|
||||||
|
|
||||||
const loadAllData = async () => {
|
const applyNavigationData = (data: CachedNavigationData) => {
|
||||||
try {
|
setDynamicNavItems(data.dynamicNavItems);
|
||||||
// Load navigation and categories in parallel
|
setCategories(
|
||||||
const [navItems, cats] = await Promise.all([
|
Array.isArray(data.categories) && data.categories.length > 0
|
||||||
getNavigationItems().catch(() => []),
|
? data.categories
|
||||||
getCategories().catch(() => [])
|
: settingsCategories
|
||||||
]);
|
);
|
||||||
|
setNavLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
if (active) {
|
const loadNavigationData = async () => {
|
||||||
// Process navigation
|
if (cachedNavigationData && cachedNavigationData.expiresAt > Date.now()) {
|
||||||
|
return cachedNavigationData.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!navigationRequest) {
|
||||||
|
navigationRequest = Promise.all([
|
||||||
|
getNavigationItems().catch(() => []),
|
||||||
|
getCategories().catch(() => []),
|
||||||
|
])
|
||||||
|
.then(([navItems, cats]) => {
|
||||||
const publicItems = Array.isArray(navItems)
|
const publicItems = Array.isArray(navItems)
|
||||||
? navItems.filter(item => !item.requires_admin)
|
? navItems.filter((item) => !item.requires_admin)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// Auto-seed if navigation is empty (only if user is authenticated as admin)
|
|
||||||
if (publicItems.length === 0 && isAdmin) {
|
if (publicItems.length === 0 && isAdmin) {
|
||||||
try {
|
try {
|
||||||
console.log('Navigation empty, auto-seeding...');
|
console.log('Navigation empty, auto-seeding...');
|
||||||
// Note: seedDefaultNavigation() would need to be imported
|
|
||||||
// For now, continue with empty navigation
|
|
||||||
} catch (seedError) {
|
} catch (seedError) {
|
||||||
console.error('Auto-seed failed:', seedError);
|
console.error('Auto-seed failed:', seedError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDynamicNavItems(publicItems);
|
const value: CachedNavigationData = {
|
||||||
|
dynamicNavItems: publicItems,
|
||||||
|
categories: Array.isArray(cats) && cats.length > 0 ? cats : null,
|
||||||
|
};
|
||||||
|
|
||||||
// Process categories
|
cachedNavigationData = {
|
||||||
if (Array.isArray(cats) && cats.length > 0) {
|
expiresAt: Date.now() + NAVBAR_CACHE_TTL_MS,
|
||||||
setCategories(cats);
|
value,
|
||||||
} else if (Array.isArray(settings?.categories)) {
|
};
|
||||||
setCategories(settings.categories as any);
|
|
||||||
} else {
|
return value;
|
||||||
setCategories(null);
|
})
|
||||||
|
.finally(() => {
|
||||||
|
navigationRequest = null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return navigationRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
try {
|
||||||
|
const data = await loadNavigationData();
|
||||||
|
if (active) {
|
||||||
|
applyNavigationData(data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load navigation/categories:', error);
|
console.error('Failed to load navigation/categories:', error);
|
||||||
if (active) {
|
if (active) {
|
||||||
setDynamicNavItems([]);
|
setDynamicNavItems([]);
|
||||||
setCategories(Array.isArray(settings?.categories) ? settings.categories as any : null);
|
setCategories(settingsCategories);
|
||||||
|
setNavLoading(false);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
if (active) setNavLoading(false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadAllData();
|
run();
|
||||||
return () => { active = false };
|
return () => { active = false };
|
||||||
}, [isAdmin, settings?.categories]);
|
}, [isAdmin, settingsCategories]);
|
||||||
|
|
||||||
// Load content availability data in parallel
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let disposed = false;
|
let disposed = false;
|
||||||
|
|
||||||
@@ -101,47 +145,93 @@ export const useNavbarData = (isAdmin: boolean, settings?: any): NavbarData => {
|
|||||||
} catch { return path; }
|
} catch { return path; }
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadContentData = async () => {
|
const applyAvailabilityData = (data: CachedAvailabilityData) => {
|
||||||
try {
|
setHasTables(data.hasTables);
|
||||||
// Load all content availability checks in parallel
|
setHasActivities(data.hasActivities);
|
||||||
const [
|
setHasPlayers(data.hasPlayers);
|
||||||
tablesResponse,
|
setHasArticles(data.hasArticles);
|
||||||
events,
|
setHasVideos(data.hasVideos || settingsHasVideos);
|
||||||
players,
|
setHasGallery(data.hasGallery || settingsHasGallery);
|
||||||
articlesResponse,
|
};
|
||||||
youtube,
|
|
||||||
manifest
|
const loadAvailabilityData = async () => {
|
||||||
] = await Promise.allSettled([
|
if (cachedAvailabilityData && cachedAvailabilityData.expiresAt > Date.now()) {
|
||||||
|
return cachedAvailabilityData.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!availabilityRequest) {
|
||||||
|
availabilityRequest = Promise.allSettled([
|
||||||
fetch(resolveBackendUrl('/cache/prefetch/facr_tables.json'), { cache: 'no-cache' }),
|
fetch(resolveBackendUrl('/cache/prefetch/facr_tables.json'), { cache: 'no-cache' }),
|
||||||
getEvents().catch(() => []),
|
getEvents().catch(() => []),
|
||||||
getPlayers().catch(() => []),
|
getPlayers().catch(() => []),
|
||||||
getArticles({ page: 1, page_size: 1, published: true }).catch(() => ({ total: 0 })),
|
getArticles({ page: 1, page_size: 1, published: true }).catch(() => ({ total: 0 })),
|
||||||
getCachedYouTube().catch(() => null),
|
getCachedYouTube().catch(() => null),
|
||||||
getZoneramaManifestWithFallbacks().catch(() => [])
|
getZoneramaManifestWithFallbacks().catch(() => []),
|
||||||
]);
|
])
|
||||||
|
.then(async ([tablesResponse, events, players, articlesResponse, youtube, manifest]) => {
|
||||||
|
let hasTables = false;
|
||||||
|
|
||||||
if (!disposed) {
|
|
||||||
// Process tables
|
|
||||||
if (tablesResponse.status === 'fulfilled') {
|
if (tablesResponse.status === 'fulfilled') {
|
||||||
const res = tablesResponse.value;
|
const res = tablesResponse.value;
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
const anyRows = Array.isArray(json?.competitions) &&
|
hasTables =
|
||||||
json.competitions.some((c: any) => Array.isArray(c?.table?.overall) && c.table.overall.length > 0);
|
Array.isArray(json?.competitions) &&
|
||||||
setHasTables(!!anyRows);
|
json.competitions.some(
|
||||||
} else {
|
(competition: any) =>
|
||||||
setHasTables(false);
|
Array.isArray(competition?.table?.overall) &&
|
||||||
|
competition.table.overall.length > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
setHasTables(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process other content with proper type guards
|
const value: CachedAvailabilityData = {
|
||||||
setHasActivities(events.status === 'fulfilled' && Array.isArray(events.value) && events.value.length > 0);
|
hasTables,
|
||||||
setHasPlayers(players.status === 'fulfilled' && Array.isArray(players.value) && players.value.length > 0);
|
hasActivities:
|
||||||
setHasArticles(articlesResponse.status === 'fulfilled' && typeof articlesResponse.value === 'object' && articlesResponse.value !== null && 'total' in articlesResponse.value && (articlesResponse.value as any).total > 0);
|
events.status === 'fulfilled' && Array.isArray(events.value) && events.value.length > 0,
|
||||||
setHasVideos(youtube.status === 'fulfilled' && youtube.value !== null && typeof youtube.value === 'object' && 'videos' in youtube.value && Array.isArray((youtube.value as any).videos) && (youtube.value as any).videos.length > 0);
|
hasPlayers:
|
||||||
setHasGallery(manifest.status === 'fulfilled' && Array.isArray(manifest.value) && manifest.value.length > 0);
|
players.status === 'fulfilled' &&
|
||||||
|
Array.isArray(players.value) &&
|
||||||
|
players.value.length > 0,
|
||||||
|
hasArticles:
|
||||||
|
articlesResponse.status === 'fulfilled' &&
|
||||||
|
typeof articlesResponse.value === 'object' &&
|
||||||
|
articlesResponse.value !== null &&
|
||||||
|
'total' in articlesResponse.value &&
|
||||||
|
(articlesResponse.value as any).total > 0,
|
||||||
|
hasVideos:
|
||||||
|
youtube.status === 'fulfilled' &&
|
||||||
|
youtube.value !== null &&
|
||||||
|
typeof youtube.value === 'object' &&
|
||||||
|
'videos' in youtube.value &&
|
||||||
|
Array.isArray((youtube.value as any).videos) &&
|
||||||
|
(youtube.value as any).videos.length > 0,
|
||||||
|
hasGallery:
|
||||||
|
manifest.status === 'fulfilled' &&
|
||||||
|
Array.isArray(manifest.value) &&
|
||||||
|
manifest.value.length > 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
cachedAvailabilityData = {
|
||||||
|
expiresAt: Date.now() + NAVBAR_CACHE_TTL_MS,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
|
||||||
|
return value;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
availabilityRequest = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return availabilityRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
const run = async () => {
|
||||||
|
try {
|
||||||
|
const data = await loadAvailabilityData();
|
||||||
|
if (!disposed) {
|
||||||
|
applyAvailabilityData(data);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load content data:', error);
|
console.error('Failed to load content data:', error);
|
||||||
@@ -150,15 +240,15 @@ export const useNavbarData = (isAdmin: boolean, settings?: any): NavbarData => {
|
|||||||
setHasActivities(false);
|
setHasActivities(false);
|
||||||
setHasPlayers(false);
|
setHasPlayers(false);
|
||||||
setHasArticles(false);
|
setHasArticles(false);
|
||||||
setHasVideos(false);
|
setHasVideos(settingsHasVideos);
|
||||||
setHasGallery(false);
|
setHasGallery(settingsHasGallery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
loadContentData();
|
run();
|
||||||
return () => { disposed = true; };
|
return () => { disposed = true; };
|
||||||
}, []);
|
}, [settingsHasGallery, settingsHasVideos]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
categories,
|
categories,
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { PageElementConfig, getPageElementConfigs } from '../services/pageElements';
|
import { getPageElementConfigs } from '../services/pageElementsPublic';
|
||||||
|
|
||||||
|
const detectEditMode = () => {
|
||||||
|
try {
|
||||||
|
if (typeof document !== 'undefined' && document.body?.classList?.contains('myuibrix-edit-mode')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
return params.get('myuibrix') === 'edit';
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
export const usePageElementConfig = (pageType: string, elementName: string, defaultVariant: string = 'unified') => {
|
export const usePageElementConfig = (pageType: string, elementName: string, defaultVariant: string = 'unified') => {
|
||||||
const [variant, setVariant] = useState<string>(defaultVariant);
|
const [variant, setVariant] = useState<string>(defaultVariant);
|
||||||
@@ -10,7 +26,7 @@ export const usePageElementConfig = (pageType: string, elementName: string, defa
|
|||||||
|
|
||||||
const loadConfig = async () => {
|
const loadConfig = async () => {
|
||||||
try {
|
try {
|
||||||
const configs = await getPageElementConfigs(pageType);
|
const configs = await getPageElementConfigs(pageType, { force: detectEditMode() });
|
||||||
if (active) {
|
if (active) {
|
||||||
const config = configs.find(c => c.element_name === elementName);
|
const config = configs.find(c => c.element_name === elementName);
|
||||||
if (config) {
|
if (config) {
|
||||||
@@ -46,6 +62,7 @@ export const useAllPageElementConfigs = (pageType: string) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let active = true;
|
let active = true;
|
||||||
|
const isEditingMode = detectEditMode();
|
||||||
|
|
||||||
// Helper function to apply DOM order
|
// Helper function to apply DOM order
|
||||||
const applyDOMOrder = (order: string[]) => {
|
const applyDOMOrder = (order: string[]) => {
|
||||||
@@ -257,10 +274,9 @@ body [data-element="${name}"],
|
|||||||
|
|
||||||
styleEl.textContent = `/* MyUIbrix Dynamic Styles - Auto-generated */\n${cssBlocks.join('\n\n')}`;
|
styleEl.textContent = `/* MyUIbrix Dynamic Styles - Auto-generated */\n${cssBlocks.join('\n\n')}`;
|
||||||
|
|
||||||
// Force browser to recalculate styles
|
// Immediate reflow is only useful in live preview mode and is expensive in production.
|
||||||
if (typeof document !== 'undefined') {
|
if (isEditingMode && typeof document !== 'undefined') {
|
||||||
// Trigger a reflow to ensure styles are applied immediately
|
document.body.offsetHeight;
|
||||||
document.body.offsetHeight; // Read operation forces reflow
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[MyUIbrix] Style injection failed:', e);
|
console.error('[MyUIbrix] Style injection failed:', e);
|
||||||
@@ -269,7 +285,7 @@ body [data-element="${name}"],
|
|||||||
|
|
||||||
const loadConfigs = async () => {
|
const loadConfigs = async () => {
|
||||||
try {
|
try {
|
||||||
const data = await getPageElementConfigs(pageType);
|
const data = await getPageElementConfigs(pageType, { force: isEditingMode });
|
||||||
if (active) {
|
if (active) {
|
||||||
const configMap: Record<string, string> = {};
|
const configMap: Record<string, string> = {};
|
||||||
const visMap: Record<string, boolean> = {};
|
const visMap: Record<string, boolean> = {};
|
||||||
@@ -336,17 +352,6 @@ body [data-element="${name}"],
|
|||||||
// Inject style properties so they apply even without inline spreading
|
// Inject style properties so they apply even without inline spreading
|
||||||
updateInjectedStyleProps(stylesMap);
|
updateInjectedStyleProps(stylesMap);
|
||||||
|
|
||||||
// Apply initial order to DOM only in editor/preview mode
|
|
||||||
const isEditingMode = (() => {
|
|
||||||
try {
|
|
||||||
if (typeof document !== 'undefined' && (document.body?.classList?.contains('myuibrix-edit-mode'))) return true;
|
|
||||||
const params = new URLSearchParams(window.location.search);
|
|
||||||
return params.get('myuibrix') === 'edit';
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (order.length > 0 && isEditingMode) {
|
if (order.length > 0 && isEditingMode) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
applyDOMOrder(order);
|
applyDOMOrder(order);
|
||||||
@@ -364,6 +369,16 @@ body [data-element="${name}"],
|
|||||||
|
|
||||||
loadConfigs();
|
loadConfigs();
|
||||||
|
|
||||||
|
if (!isEditingMode) {
|
||||||
|
return () => {
|
||||||
|
active = false;
|
||||||
|
try {
|
||||||
|
const s = document.getElementById('myuibrix-style-props');
|
||||||
|
if (s) s.remove();
|
||||||
|
} catch {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Listen for live updates from MyUIbrix editor (ONLY in preview mode)
|
// Listen for live updates from MyUIbrix editor (ONLY in preview mode)
|
||||||
const handleMyUIbrixChange = ((event: CustomEvent) => {
|
const handleMyUIbrixChange = ((event: CustomEvent) => {
|
||||||
const { elementName, variant, visible, previewMode, timestamp } = event.detail;
|
const { elementName, variant, visible, previewMode, timestamp } = event.detail;
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ interface UmamiConfig {
|
|||||||
script_url: string;
|
script_url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cachedUmamiConfig: UmamiConfig | null | undefined;
|
||||||
|
let umamiConfigPromise: Promise<UmamiConfig | null> | null = null;
|
||||||
|
|
||||||
// Extend window object to include umami
|
// Extend window object to include umami
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -31,31 +34,57 @@ export const useUmami = () => {
|
|||||||
pathname === '/setup';
|
pathname === '/setup';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchConfigOnce = async () => {
|
||||||
|
if (cachedUmamiConfig !== undefined) {
|
||||||
|
return cachedUmamiConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!umamiConfigPromise) {
|
||||||
|
umamiConfigPromise = axios
|
||||||
|
.get(`${API_URL}/insights/config`)
|
||||||
|
.then((response) => {
|
||||||
|
cachedUmamiConfig = response.data as UmamiConfig;
|
||||||
|
return cachedUmamiConfig;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Failed to load Umami config:', error);
|
||||||
|
cachedUmamiConfig = null;
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
umamiConfigPromise = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return umamiConfigPromise;
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Don't load Umami for admin pages
|
|
||||||
if (isAdminRoute(location.pathname)) {
|
if (isAdminRoute(location.pathname)) {
|
||||||
console.log('Umami tracking disabled for admin pages');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch Umami configuration from backend
|
let active = true;
|
||||||
const fetchConfig = async () => {
|
|
||||||
try {
|
const ensureConfig = async () => {
|
||||||
const response = await axios.get(`${API_URL}/insights/config`);
|
const umamiConfig = await fetchConfigOnce();
|
||||||
const umamiConfig = response.data as UmamiConfig;
|
if (!active || !umamiConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setConfig(umamiConfig);
|
setConfig(umamiConfig);
|
||||||
|
|
||||||
// If enabled and not already loaded, inject the script
|
|
||||||
if (umamiConfig.enabled && umamiConfig.website_id && !isLoaded) {
|
if (umamiConfig.enabled && umamiConfig.website_id && !isLoaded) {
|
||||||
loadUmamiScript(umamiConfig.script_url, umamiConfig.website_id);
|
loadUmamiScript(umamiConfig.script_url, umamiConfig.website_id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to load Umami config:', error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchConfig();
|
ensureConfig();
|
||||||
}, [location.pathname]);
|
|
||||||
|
return () => {
|
||||||
|
active = false;
|
||||||
|
};
|
||||||
|
}, [isLoaded, location.pathname]);
|
||||||
|
|
||||||
// Track page views when location changes (skip admin routes for Umami)
|
// Track page views when location changes (skip admin routes for Umami)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import './styles/custom-editor.css';
|
|||||||
import './styles/public-rich-content.css';
|
import './styles/public-rich-content.css';
|
||||||
// Import i18n configuration
|
// Import i18n configuration
|
||||||
import './i18n';
|
import './i18n';
|
||||||
import { theme } from './App';
|
import { theme } from './theme/siteTheme';
|
||||||
import AppLazy from './App.lazy';
|
import AppLazy from './App.lazy';
|
||||||
import { ColorModeScript } from '@chakra-ui/react';
|
import { ColorModeScript } from '@chakra-ui/react';
|
||||||
import { HelmetProvider } from 'react-helmet-async';
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { Box, Container, Heading, Text, Stack, Image, SimpleGrid, Divider } from
|
|||||||
import { usePublicSettings } from '../hooks/usePublicSettings';
|
import { usePublicSettings } from '../hooks/usePublicSettings';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { assetUrl } from '../utils/url';
|
import { assetUrl } from '../utils/url';
|
||||||
|
import { sanitizeRichHtml } from '../utils/sanitizeHtml';
|
||||||
import NewsletterCTA from '../components/common/NewsletterCTA';
|
import NewsletterCTA from '../components/common/NewsletterCTA';
|
||||||
|
|
||||||
const ClubPage: React.FC = () => {
|
const ClubPage: React.FC = () => {
|
||||||
const { data: settings } = usePublicSettings();
|
const { data: settings } = usePublicSettings();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const aboutHtml = React.useMemo(() => sanitizeRichHtml(settings?.about_html), [settings?.about_html]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainLayout>
|
<MainLayout>
|
||||||
@@ -24,9 +26,9 @@ const ClubPage: React.FC = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{settings?.about_html ? (
|
{aboutHtml ? (
|
||||||
<Box>
|
<Box>
|
||||||
<Box className="prose" color="gray.800" dangerouslySetInnerHTML={{ __html: settings.about_html as any }} />
|
<Box className="prose" color="gray.800" dangerouslySetInnerHTML={{ __html: aboutHtml }} />
|
||||||
</Box>
|
</Box>
|
||||||
) : (
|
) : (
|
||||||
<Box>
|
<Box>
|
||||||
|
|||||||
@@ -31,7 +31,14 @@ import MatchModal from '../components/home/MatchModal';
|
|||||||
import { useAllPageElementConfigs } from '../hooks/usePageElementConfig';
|
import { useAllPageElementConfigs } from '../hooks/usePageElementConfig';
|
||||||
import { API_URL } from '../services/api';
|
import { API_URL } from '../services/api';
|
||||||
import { TeamLogo } from '../components/common/TeamLogo';
|
import { TeamLogo } from '../components/common/TeamLogo';
|
||||||
|
import MatchCountdownText, { buildKickoffIso } from '../components/common/MatchCountdownText';
|
||||||
import ClubHeroTopbar from '../components/home/ClubHeroTopbar';
|
import ClubHeroTopbar from '../components/home/ClubHeroTopbar';
|
||||||
|
import {
|
||||||
|
HomeCardsSkeleton,
|
||||||
|
HomeHeroSkeleton,
|
||||||
|
HomeSponsorsSkeleton,
|
||||||
|
HomeStandingsSkeleton,
|
||||||
|
} from '../components/home/HomeLoadingSkeletons';
|
||||||
import NewsList from '../components/pack/NewsList';
|
import NewsList from '../components/pack/NewsList';
|
||||||
const StandingsCard = React.lazy(() => import('../components/pack/StandingsCard'));
|
const StandingsCard = React.lazy(() => import('../components/pack/StandingsCard'));
|
||||||
import NextMatch from '../components/pack/NextMatch';
|
import NextMatch from '../components/pack/NextMatch';
|
||||||
@@ -75,7 +82,6 @@ const HomePage: React.FC = () => {
|
|||||||
// Local state now starts empty; filled by FACR/cache/live APIs
|
// Local state now starts empty; filled by FACR/cache/live APIs
|
||||||
const [news, setNews] = useState<NewsItem[]>([]);
|
const [news, setNews] = useState<NewsItem[]>([]);
|
||||||
const [matches, setMatches] = useState<MatchItem[]>([]);
|
const [matches, setMatches] = useState<MatchItem[]>([]);
|
||||||
const [countdown, setCountdown] = useState<string>('');
|
|
||||||
const [clubName, setClubName] = useState<string>('');
|
const [clubName, setClubName] = useState<string>('');
|
||||||
const [clubLogo, setClubLogo] = useState<string>('');
|
const [clubLogo, setClubLogo] = useState<string>('');
|
||||||
const [standings, setStandings] = useState<any[]>([]);
|
const [standings, setStandings] = useState<any[]>([]);
|
||||||
@@ -771,49 +777,6 @@ const HomePage: React.FC = () => {
|
|||||||
// MyUIbrix events are handled by useAllPageElementConfigs hook
|
// MyUIbrix events are handled by useAllPageElementConfigs hook
|
||||||
// It automatically updates getVariant() and isVisible() when changes occur in edit mode
|
// It automatically updates getVariant() and isVisible() when changes occur in edit mode
|
||||||
|
|
||||||
// Countdown to next match (uses selected competition upcoming if available)
|
|
||||||
useEffect(() => {
|
|
||||||
const getUpcomingForComp = (c: any) => {
|
|
||||||
const items = Array.isArray(c?.matches) ? c.matches : [];
|
|
||||||
const future = items
|
|
||||||
.map((m: any) => ({ m, t: new Date(`${m.date}T${(m.time || '00:00')}:00`).getTime() }))
|
|
||||||
.filter((x: any) => !isNaN(x.t) && x.t > Date.now())
|
|
||||||
.sort((a: any, b: any) => a.t - b.t);
|
|
||||||
return future[0]?.m || null;
|
|
||||||
};
|
|
||||||
const getNextKickoff = () => {
|
|
||||||
if (facrCompetitions.length) {
|
|
||||||
const sel = facrCompetitions[Math.max(0, Math.min(matchesTab, facrCompetitions.length - 1))];
|
|
||||||
const up = getUpcomingForComp(sel);
|
|
||||||
if (up) {
|
|
||||||
const iso = `${up.date}T${(up.time || '00:00')}:00`;
|
|
||||||
const d = new Date(iso);
|
|
||||||
return isNaN(d.getTime()) ? null : d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!matches.length) return null;
|
|
||||||
const m = matches[0];
|
|
||||||
const iso = `${m.date}T${(m.time || '00:00')}:00`;
|
|
||||||
const d = new Date(iso);
|
|
||||||
return isNaN(d.getTime()) ? null : d;
|
|
||||||
};
|
|
||||||
const update = () => {
|
|
||||||
const next = getNextKickoff();
|
|
||||||
if (!next) { setCountdown(''); return; }
|
|
||||||
const diff = next.getTime() - Date.now();
|
|
||||||
if (diff <= 0) { setCountdown('Začátek'); return; }
|
|
||||||
const s = Math.floor(diff / 1000);
|
|
||||||
const days = Math.floor(s / 86400);
|
|
||||||
const hrs = Math.floor((s % 86400) / 3600);
|
|
||||||
const mins = Math.floor((s % 3600) / 60);
|
|
||||||
const secs = s % 60;
|
|
||||||
setCountdown(`${days} d ${hrs} h ${mins} m ${secs} s`);
|
|
||||||
};
|
|
||||||
update();
|
|
||||||
const id = setInterval(update, 1000);
|
|
||||||
return () => clearInterval(id);
|
|
||||||
}, [matches, facrCompetitions, matchesTab]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let active = true;
|
let active = true;
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -1181,7 +1144,14 @@ const HomePage: React.FC = () => {
|
|||||||
<div>{show?.home || clubName}</div>
|
<div>{show?.home || clubName}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="meta">
|
<div className="meta">
|
||||||
{isFuture ? <><div style={{ fontWeight: 800 }}>{countdown || '—'}</div><div>Začátek</div></> : <div style={{ fontWeight: 800 }}>{show?.score || '—'}</div>}
|
{isFuture ? (
|
||||||
|
<>
|
||||||
|
<div style={{ fontWeight: 800 }}>
|
||||||
|
<MatchCountdownText targetDate={buildKickoffIso(show?.date, show?.time)} />
|
||||||
|
</div>
|
||||||
|
<div>Začátek</div>
|
||||||
|
</>
|
||||||
|
) : <div style={{ fontWeight: 800 }}>{show?.score || '—'}</div>}
|
||||||
</div>
|
</div>
|
||||||
<div className="team">
|
<div className="team">
|
||||||
<img src={assetUrl(show?.away_logo_url) || '/images/club-opponent.svg'} alt="Hosté" />
|
<img src={assetUrl(show?.away_logo_url) || '/images/club-opponent.svg'} alt="Hosté" />
|
||||||
@@ -1682,7 +1652,7 @@ const HomePage: React.FC = () => {
|
|||||||
|
|
||||||
{getVariant('hero', heroStyle) === 'scroller' && isVisible('hero', true) && (
|
{getVariant('hero', heroStyle) === 'scroller' && isVisible('hero', true) && (
|
||||||
<section key={`hero-scroller-${refreshKey}`} data-element="hero" data-variant={getVariant('hero', heroStyle)} style={{ position: 'relative', ...getStyles('hero') }}>
|
<section key={`hero-scroller-${refreshKey}`} data-element="hero" data-variant={getVariant('hero', heroStyle)} style={{ position: 'relative', ...getStyles('hero') }}>
|
||||||
<Suspense fallback={<div style={{ minHeight: 240 }} />}>
|
<Suspense fallback={<HomeHeroSkeleton />}>
|
||||||
<BlogCardsScroller />
|
<BlogCardsScroller />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
@@ -1694,7 +1664,7 @@ const HomePage: React.FC = () => {
|
|||||||
data-variant={getVariant('hero', heroStyle)}
|
data-variant={getVariant('hero', heroStyle)}
|
||||||
style={{ position: 'relative', ...getStyles('hero') }}
|
style={{ position: 'relative', ...getStyles('hero') }}
|
||||||
>
|
>
|
||||||
<Suspense fallback={<div style={{ minHeight: 280 }} />}>
|
<Suspense fallback={<HomeHeroSkeleton />}>
|
||||||
<BlogSwiper fallbackArticles={heroFallbackArticles} />
|
<BlogSwiper fallbackArticles={heroFallbackArticles} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</section>
|
</section>
|
||||||
@@ -1736,7 +1706,7 @@ const HomePage: React.FC = () => {
|
|||||||
<NextMatch
|
<NextMatch
|
||||||
data={show}
|
data={show}
|
||||||
competitionName={comp?.name}
|
competitionName={comp?.name}
|
||||||
countdown={countdown}
|
kickoffIso={buildKickoffIso(show?.date, show?.time)}
|
||||||
onPrev={() => { setNextCompIdx(prevIdx); setMatchesTab(prevIdx); }}
|
onPrev={() => { setNextCompIdx(prevIdx); setMatchesTab(prevIdx); }}
|
||||||
onNext={() => { setNextCompIdx(nextIdx); setMatchesTab(nextIdx); }}
|
onNext={() => { setNextCompIdx(nextIdx); setMatchesTab(nextIdx); }}
|
||||||
onOpen={handleNextMatchClick}
|
onOpen={handleNextMatchClick}
|
||||||
@@ -1769,7 +1739,7 @@ const HomePage: React.FC = () => {
|
|||||||
away: next?.awayTeam || 'Soupeř',
|
away: next?.awayTeam || 'Soupeř',
|
||||||
away_logo_url: next?.awayLogoURL,
|
away_logo_url: next?.awayLogoURL,
|
||||||
}}
|
}}
|
||||||
countdown={countdown}
|
kickoffIso={buildKickoffIso(next?.date, next?.time)}
|
||||||
elementProps={{ 'data-element': 'matches', 'data-variant': getVariant('matches', 'compact'), 'aria-live': 'polite', style: { position: 'relative', ...getStyles('matches') } }}
|
elementProps={{ 'data-element': 'matches', 'data-variant': getVariant('matches', 'compact'), 'aria-live': 'polite', style: { position: 'relative', ...getStyles('matches') } }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1786,7 +1756,7 @@ const HomePage: React.FC = () => {
|
|||||||
{/* Matches slider with scores by competition (moved after news+tables) */}
|
{/* Matches slider with scores by competition (moved after news+tables) */}
|
||||||
{facrCompetitions.length > 0 && (
|
{facrCompetitions.length > 0 && (
|
||||||
defer ? (
|
defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton layout="carousel" cardCount={3} cardHeight={160} minCardWidth={340} titleWidth={140} actionWidth={96} />}>
|
||||||
<MatchesSlider
|
<MatchesSlider
|
||||||
key={`matches-slider-${refreshKey}-${getVariant('matches-slider', 'carousel')}`}
|
key={`matches-slider-${refreshKey}-${getVariant('matches-slider', 'carousel')}`}
|
||||||
comps={facrCompetitions as any}
|
comps={facrCompetitions as any}
|
||||||
@@ -1800,7 +1770,7 @@ const HomePage: React.FC = () => {
|
|||||||
elementProps={{ 'data-element': 'matches-slider', 'data-variant': getVariant('matches-slider', 'carousel'), style: { position: 'relative', ...getStyles('matches-slider') } }}
|
elementProps={{ 'data-element': 'matches-slider', 'data-variant': getVariant('matches-slider', 'carousel'), style: { position: 'relative', ...getStyles('matches-slider') } }}
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : null
|
) : <HomeCardsSkeleton layout="carousel" cardCount={3} cardHeight={160} minCardWidth={340} titleWidth={140} actionWidth={96} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{facrCompetitions.length === 0 && isLoading && (
|
{facrCompetitions.length === 0 && isLoading && (
|
||||||
@@ -1871,7 +1841,7 @@ const HomePage: React.FC = () => {
|
|||||||
<a href="/tabulky" className="see-all" style={{ fontSize: '0.85rem' }}>{t('nav.view_all')} <FiArrowRight size={14} /></a>
|
<a href="/tabulky" className="see-all" style={{ fontSize: '0.85rem' }}>{t('nav.view_all')} <FiArrowRight size={14} /></a>
|
||||||
</div>
|
</div>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeStandingsSkeleton />}>
|
||||||
<StandingsCard
|
<StandingsCard
|
||||||
variant={((): 'logos'|'plain' => { const v = getVariant('table_rows', 'logos'); return v === 'plain' ? 'plain' : 'logos'; })()}
|
variant={((): 'logos'|'plain' => { const v = getVariant('table_rows', 'logos'); return v === 'plain' ? 'plain' : 'logos'; })()}
|
||||||
rows={(matchingStanding?.table || matchingStanding?.rows || []) as any}
|
rows={(matchingStanding?.table || matchingStanding?.rows || []) as any}
|
||||||
@@ -2040,10 +2010,10 @@ const HomePage: React.FC = () => {
|
|||||||
<section key={`gallery-${refreshKey}-${getVariant('gallery', 'grid')}`} data-element="gallery" data-variant={getVariant('gallery', 'grid')} aria-labelledby="home-gallery-heading" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '700px', ...getStyles('gallery') }}>
|
<section key={`gallery-${refreshKey}-${getVariant('gallery', 'grid')}`} data-element="gallery" data-variant={getVariant('gallery', 'grid')} aria-labelledby="home-gallery-heading" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '700px', ...getStyles('gallery') }}>
|
||||||
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton cardCount={3} cardHeight={300} titleWidth={140} actionWidth={96} />}>
|
||||||
<GallerySection zoneramaUrl={galleryUrl} />
|
<GallerySection zoneramaUrl={galleryUrl} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : null}
|
) : <HomeCardsSkeleton cardCount={3} cardHeight={300} titleWidth={140} actionWidth={96} />}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
@@ -2053,7 +2023,7 @@ const HomePage: React.FC = () => {
|
|||||||
<section key={`videos-${refreshKey}-${getVariant('videos', 'carousel')}`} data-element="videos" data-variant={getVariant('videos', 'carousel')} aria-labelledby="home-videos-heading" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '700px', ...getStyles('videos') }}>
|
<section key={`videos-${refreshKey}-${getVariant('videos', 'carousel')}`} data-element="videos" data-variant={getVariant('videos', 'carousel')} aria-labelledby="home-videos-heading" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '700px', ...getStyles('videos') }}>
|
||||||
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton layout="list" cardCount={3} cardHeight={240} titleWidth={110} actionWidth={110} />}>
|
||||||
<VideosSection
|
<VideosSection
|
||||||
key={`videos-comp-${refreshKey}-${getVariant('videos', 'carousel')}`}
|
key={`videos-comp-${refreshKey}-${getVariant('videos', 'carousel')}`}
|
||||||
variant={(getVariant('videos', 'carousel') as any) as 'grid' | 'carousel'}
|
variant={(getVariant('videos', 'carousel') as any) as 'grid' | 'carousel'}
|
||||||
@@ -2080,7 +2050,7 @@ const HomePage: React.FC = () => {
|
|||||||
<section key={`merch-${refreshKey}-${getVariant('merch', 'grid')}`} data-element="merch" data-variant={getVariant('merch', 'grid')} aria-labelledby="home-merch-heading" style={{ marginTop: 24, marginBottom: 24, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '600px', ...getStyles('merch') }}>
|
<section key={`merch-${refreshKey}-${getVariant('merch', 'grid')}`} data-element="merch" data-variant={getVariant('merch', 'grid')} aria-labelledby="home-merch-heading" style={{ marginTop: 24, marginBottom: 24, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '600px', ...getStyles('merch') }}>
|
||||||
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton cardCount={5} cardHeight={180} titleWidth={170} actionWidth={96} />}>
|
||||||
<MerchSection variant={(getVariant('merch', 'grid') as any) as 'grid' | 'carousel' | 'featured' | 'list'} />
|
<MerchSection variant={(getVariant('merch', 'grid') as any) as 'grid' | 'carousel' | 'featured' | 'list'} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : (
|
) : (
|
||||||
@@ -2105,7 +2075,7 @@ const HomePage: React.FC = () => {
|
|||||||
<section key={`poll-${refreshKey}-${getVariant('poll', 'vertical')}`} data-element="poll" data-variant={getVariant('poll', 'vertical')} aria-label="Anketa" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '500px', ...getStyles('poll') }}>
|
<section key={`poll-${refreshKey}-${getVariant('poll', 'vertical')}`} data-element="poll" data-variant={getVariant('poll', 'vertical')} aria-label="Anketa" style={{ marginTop: 32, marginBottom: 32, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '500px', ...getStyles('poll') }}>
|
||||||
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
<div style={{ maxWidth: 1200, margin: '0 auto', padding: '0 12px' }}>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton layout="grid" columns="1fr" cardCount={1} cardHeight={320} titleWidth={140} actionWidth={88} />}>
|
||||||
<PollsWidget featuredOnly={false} maxPolls={1} title="Anketa" />
|
<PollsWidget featuredOnly={false} maxPolls={1} title="Anketa" />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : (
|
) : (
|
||||||
@@ -2132,7 +2102,7 @@ const HomePage: React.FC = () => {
|
|||||||
<section key={`newsletter-${refreshKey}-${getVariant('newsletter', 'default')}`} data-element="newsletter" data-variant={getVariant('newsletter', 'default')} className="newsletter-cta" aria-label="Přihlášení k newsletteru" style={{ marginTop: 24, marginBottom: 24, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '420px', ...getStyles('newsletter') }}>
|
<section key={`newsletter-${refreshKey}-${getVariant('newsletter', 'default')}`} data-element="newsletter" data-variant={getVariant('newsletter', 'default')} className="newsletter-cta" aria-label="Přihlášení k newsletteru" style={{ marginTop: 24, marginBottom: 24, position: 'relative', contentVisibility: 'auto' as any, containIntrinsicSize: '420px', ...getStyles('newsletter') }}>
|
||||||
<div className="card" style={{ maxWidth: 960, margin: '0 auto' }}>
|
<div className="card" style={{ maxWidth: 960, margin: '0 auto' }}>
|
||||||
{defer ? (
|
{defer ? (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={<HomeCardsSkeleton layout="grid" columns="1fr" cardCount={1} cardHeight={280} titleWidth={180} actionWidth={120} />}>
|
||||||
<NewsletterSubscribe />
|
<NewsletterSubscribe />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
) : (
|
) : (
|
||||||
@@ -2220,13 +2190,7 @@ const HomePage: React.FC = () => {
|
|||||||
<div className="section-head">
|
<div className="section-head">
|
||||||
<h3 id="home-sponsors-heading">{t('nav.sponsors')}</h3>
|
<h3 id="home-sponsors-heading">{t('nav.sponsors')}</h3>
|
||||||
</div>
|
</div>
|
||||||
{isLoading && ordered.length === 0 && (
|
{isLoading && ordered.length === 0 && <HomeSponsorsSkeleton />}
|
||||||
<div className="sponsors-grid">
|
|
||||||
{[1,2,3,4,5,6,7,8].map(i => (
|
|
||||||
<div key={i} className="sponsor-tile skeleton" style={{ minHeight: 90, borderRadius: 12 }} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{variant === 'grid' && (
|
{variant === 'grid' && (
|
||||||
<>
|
<>
|
||||||
{general.length > 0 && (
|
{general.length > 0 && (
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/// <reference types="react-scripts" />
|
/// <reference types="vite/client" />
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import api from './api';
|
import api from './api';
|
||||||
import { IconType } from 'react-icons';
|
import { IconType } from 'react-icons';
|
||||||
|
import { invalidatePageElementConfigs } from './pageElementsPublic';
|
||||||
|
import type { PageElementConfig } from './pageElementsPublic';
|
||||||
|
export type { PageElementConfig } from './pageElementsPublic';
|
||||||
|
export { getPageElementConfigs } from './pageElementsPublic';
|
||||||
import {
|
import {
|
||||||
FaRegClipboard,
|
FaRegClipboard,
|
||||||
FaBullseye,
|
FaBullseye,
|
||||||
@@ -37,26 +41,6 @@ import {
|
|||||||
|
|
||||||
// Use shared API base URL
|
// Use shared API base URL
|
||||||
|
|
||||||
export interface PageElementConfig {
|
|
||||||
id?: number;
|
|
||||||
page_type: string;
|
|
||||||
element_name: string;
|
|
||||||
variant: string;
|
|
||||||
visible?: boolean;
|
|
||||||
display_order?: number;
|
|
||||||
settings?: Record<string, any>;
|
|
||||||
created_at?: string;
|
|
||||||
updated_at?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public endpoints
|
|
||||||
export const getPageElementConfigs = async (pageType: string): Promise<PageElementConfig[]> => {
|
|
||||||
const response = await api.get('/page-elements', {
|
|
||||||
params: { page_type: pageType }
|
|
||||||
});
|
|
||||||
return response.data || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
// Admin endpoints
|
// Admin endpoints
|
||||||
export const getAllPageElementConfigs = async (): Promise<PageElementConfig[]> => {
|
export const getAllPageElementConfigs = async (): Promise<PageElementConfig[]> => {
|
||||||
const response = await api.get('/admin/page-elements');
|
const response = await api.get('/admin/page-elements');
|
||||||
@@ -65,20 +49,29 @@ export const getAllPageElementConfigs = async (): Promise<PageElementConfig[]> =
|
|||||||
|
|
||||||
export const createOrUpdatePageElementConfig = async (config: Partial<PageElementConfig>): Promise<PageElementConfig> => {
|
export const createOrUpdatePageElementConfig = async (config: Partial<PageElementConfig>): Promise<PageElementConfig> => {
|
||||||
const response = await api.post('/admin/page-elements', config);
|
const response = await api.post('/admin/page-elements', config);
|
||||||
|
invalidatePageElementConfigs(config.page_type);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updatePageElementConfig = async (id: number, config: Partial<PageElementConfig>): Promise<PageElementConfig> => {
|
export const updatePageElementConfig = async (id: number, config: Partial<PageElementConfig>): Promise<PageElementConfig> => {
|
||||||
const response = await api.put(`/admin/page-elements/${id}`, config);
|
const response = await api.put(`/admin/page-elements/${id}`, config);
|
||||||
|
invalidatePageElementConfigs(config.page_type);
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deletePageElementConfig = async (id: number): Promise<void> => {
|
export const deletePageElementConfig = async (id: number): Promise<void> => {
|
||||||
await api.delete(`/admin/page-elements/${id}`);
|
await api.delete(`/admin/page-elements/${id}`);
|
||||||
|
invalidatePageElementConfigs();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const batchUpdatePageElementConfigs = async (configs: PageElementConfig[]): Promise<{ message: string; updated: number; created: number }> => {
|
export const batchUpdatePageElementConfigs = async (configs: PageElementConfig[]): Promise<{ message: string; updated: number; created: number }> => {
|
||||||
const response = await api.post('/admin/page-elements/batch', configs);
|
const response = await api.post('/admin/page-elements/batch', configs);
|
||||||
|
const pageTypes = new Set(configs.map((config) => config.page_type).filter(Boolean));
|
||||||
|
if (pageTypes.size === 0) {
|
||||||
|
invalidatePageElementConfigs();
|
||||||
|
} else {
|
||||||
|
pageTypes.forEach((pageType) => invalidatePageElementConfigs(pageType));
|
||||||
|
}
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import api from './api';
|
||||||
|
|
||||||
|
export interface PageElementConfig {
|
||||||
|
id?: number;
|
||||||
|
page_type: string;
|
||||||
|
element_name: string;
|
||||||
|
variant: string;
|
||||||
|
visible?: boolean;
|
||||||
|
display_order?: number;
|
||||||
|
settings?: Record<string, any>;
|
||||||
|
created_at?: string;
|
||||||
|
updated_at?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type CacheEntry = {
|
||||||
|
expiresAt: number;
|
||||||
|
value: PageElementConfig[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const PAGE_ELEMENT_CACHE_TTL_MS = 5 * 60 * 1000;
|
||||||
|
const pageElementCache = new Map<string, CacheEntry>();
|
||||||
|
const inFlightPageElementRequests = new Map<string, Promise<PageElementConfig[]>>();
|
||||||
|
|
||||||
|
export const invalidatePageElementConfigs = (pageType?: string) => {
|
||||||
|
if (pageType) {
|
||||||
|
pageElementCache.delete(pageType);
|
||||||
|
inFlightPageElementRequests.delete(pageType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pageElementCache.clear();
|
||||||
|
inFlightPageElementRequests.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPageElementConfigs = async (
|
||||||
|
pageType: string,
|
||||||
|
options?: { force?: boolean }
|
||||||
|
): Promise<PageElementConfig[]> => {
|
||||||
|
const force = options?.force === true;
|
||||||
|
const cacheKey = String(pageType || '').trim();
|
||||||
|
|
||||||
|
if (!force) {
|
||||||
|
const cached = pageElementCache.get(cacheKey);
|
||||||
|
if (cached && cached.expiresAt > Date.now()) {
|
||||||
|
return cached.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pending = inFlightPageElementRequests.get(cacheKey);
|
||||||
|
if (pending) {
|
||||||
|
return pending;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const request = api
|
||||||
|
.get('/page-elements', {
|
||||||
|
params: { page_type: pageType },
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const data = Array.isArray(response.data) ? response.data : [];
|
||||||
|
pageElementCache.set(cacheKey, {
|
||||||
|
expiresAt: Date.now() + PAGE_ELEMENT_CACHE_TTL_MS,
|
||||||
|
value: data,
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
inFlightPageElementRequests.delete(cacheKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!force) {
|
||||||
|
inFlightPageElementRequests.set(cacheKey, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return request;
|
||||||
|
};
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
||||||
|
|
||||||
function resolveBackendOrigin() {
|
|
||||||
const raw = process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || '';
|
|
||||||
const fallback = 'http://127.0.0.1:8080';
|
|
||||||
try {
|
|
||||||
if (!raw || raw.startsWith('/')) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
const u = new URL(raw);
|
|
||||||
u.pathname = '/';
|
|
||||||
return u.toString();
|
|
||||||
} catch (e) {
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(app) {
|
|
||||||
// Proxy /uploads requests to backend
|
|
||||||
app.use(
|
|
||||||
'/uploads',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /uploads:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
app.use(
|
|
||||||
'/api',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /api:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Proxy short links and tracked redirect so CRA dev server doesn't 404 or capture the route
|
|
||||||
app.use(
|
|
||||||
'/s',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /s:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
app.use(
|
|
||||||
'/r',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /r:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Proxy /static requests to backend (for any static assets served by Go)
|
|
||||||
app.use(
|
|
||||||
'/static',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /static:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Proxy /dist requests to backend (assets served by Go under /dist)
|
|
||||||
app.use(
|
|
||||||
'/dist',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /dist:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Proxy /cache requests to backend (for FACR cache files, etc.)
|
|
||||||
app.use(
|
|
||||||
'/cache',
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for /cache:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Additional common static/image paths that may be referenced directly
|
|
||||||
app.use(
|
|
||||||
[
|
|
||||||
'/images',
|
|
||||||
'/img',
|
|
||||||
'/media',
|
|
||||||
'/files',
|
|
||||||
'/logos',
|
|
||||||
'/avatars',
|
|
||||||
'/downloads',
|
|
||||||
'/public',
|
|
||||||
'/favicon.ico',
|
|
||||||
],
|
|
||||||
createProxyMiddleware({
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for image/static path:', err);
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fallback: proxy any direct image file requests to the backend
|
|
||||||
// This will not affect Webpack Dev Server assets since they are handled earlier in the middleware chain
|
|
||||||
app.use(
|
|
||||||
createProxyMiddleware(
|
|
||||||
(pathname, req) => {
|
|
||||||
try {
|
|
||||||
if (pathname.startsWith('/sockjs-node') || pathname.startsWith('/ws')) return false;
|
|
||||||
return /\.(?:png|jpe?g|gif|svg|webp|ico|avif)$/i.test(pathname);
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
target: resolveBackendOrigin(),
|
|
||||||
changeOrigin: true,
|
|
||||||
logLevel: 'debug',
|
|
||||||
onError: (err, req, res) => {
|
|
||||||
console.error('Proxy error for image extension fallback:', err);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
import { extendTheme } from '@chakra-ui/react';
|
||||||
|
|
||||||
|
export const theme = extendTheme({
|
||||||
|
config: {
|
||||||
|
initialColorMode: 'light',
|
||||||
|
useSystemColorMode: false,
|
||||||
|
},
|
||||||
|
colors: {
|
||||||
|
brand: {
|
||||||
|
50: '#e6f7ff',
|
||||||
|
100: '#b3e0ff',
|
||||||
|
200: '#80caff',
|
||||||
|
300: '#4db3ff',
|
||||||
|
400: '#1a9cff',
|
||||||
|
500: 'var(--club-primary, #0b5cff)',
|
||||||
|
600: '#0066cc',
|
||||||
|
700: '#004d99',
|
||||||
|
800: '#003366',
|
||||||
|
900: '#001a33',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
semanticTokens: {
|
||||||
|
colors: {
|
||||||
|
'brand.primary': {
|
||||||
|
default: 'var(--club-primary, #0b5cff)',
|
||||||
|
},
|
||||||
|
'brand.secondary': {
|
||||||
|
default: 'var(--club-secondary, #ffd200)',
|
||||||
|
},
|
||||||
|
'brand.accent': {
|
||||||
|
default: 'var(--club-accent, #141414)',
|
||||||
|
},
|
||||||
|
'text.onPrimary': {
|
||||||
|
default: 'var(--club-text-on-primary, #ffffff)',
|
||||||
|
},
|
||||||
|
'bg.app': {
|
||||||
|
default: '#f8f9fb',
|
||||||
|
_dark: '#0f1115',
|
||||||
|
},
|
||||||
|
'text.app': {
|
||||||
|
default: '#1a1a1a',
|
||||||
|
_dark: '#e8eaf0',
|
||||||
|
},
|
||||||
|
'border.subtle': {
|
||||||
|
default: 'rgba(0,0,0,0.06)',
|
||||||
|
_dark: 'rgba(255,255,255,0.12)',
|
||||||
|
},
|
||||||
|
'bg.card': {
|
||||||
|
default: '#ffffff',
|
||||||
|
_dark: '#1a1d29',
|
||||||
|
},
|
||||||
|
'bg.elevated': {
|
||||||
|
default: '#ffffff',
|
||||||
|
_dark: '#242831',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
styles: {
|
||||||
|
global: {
|
||||||
|
'html, body, #root': {
|
||||||
|
height: '100%',
|
||||||
|
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
bg: 'bg.app',
|
||||||
|
color: 'text.app',
|
||||||
|
lineHeight: 1.5,
|
||||||
|
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
'h1, h2, h3, h4, h5, h6': {
|
||||||
|
fontFamily: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
a: {
|
||||||
|
transition: 'color 0.2s ease',
|
||||||
|
},
|
||||||
|
'::selection': {
|
||||||
|
background: 'brand.accent',
|
||||||
|
color: 'black',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Container: {
|
||||||
|
baseStyle: {
|
||||||
|
px: { base: 4, md: 6 },
|
||||||
|
},
|
||||||
|
sizes: {
|
||||||
|
'7xl': '88rem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Button: {
|
||||||
|
baseStyle: {
|
||||||
|
fontWeight: '700',
|
||||||
|
borderRadius: 'md',
|
||||||
|
letterSpacing: '0.4px',
|
||||||
|
_hover: { transform: 'translateY(-1px)', boxShadow: 'md' },
|
||||||
|
_active: { transform: 'translateY(0)' },
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
solid: {
|
||||||
|
bg: 'brand.primary',
|
||||||
|
color: 'text.onPrimary',
|
||||||
|
_hover: { filter: 'brightness(0.95)' },
|
||||||
|
},
|
||||||
|
outline: {
|
||||||
|
border: '2px solid',
|
||||||
|
borderColor: 'brand.primary',
|
||||||
|
color: 'brand.primary',
|
||||||
|
_hover: { bg: 'rgba(0,0,0,0.02)' },
|
||||||
|
},
|
||||||
|
ghost: {
|
||||||
|
color: 'brand.secondary',
|
||||||
|
_hover: { bg: 'rgba(0,0,0,0.04)' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Card: {
|
||||||
|
baseStyle: {
|
||||||
|
container: {
|
||||||
|
borderRadius: 'lg',
|
||||||
|
boxShadow: 'sm',
|
||||||
|
overflow: 'hidden',
|
||||||
|
transition: 'all 0.2s',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderColor: 'border.subtle',
|
||||||
|
_hover: { transform: 'translateY(-4px)', boxShadow: 'lg' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Divider: {
|
||||||
|
baseStyle: {
|
||||||
|
borderColor: 'border.subtle',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Heading: {
|
||||||
|
baseStyle: {
|
||||||
|
fontFamily: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Text: {
|
||||||
|
baseStyle: {
|
||||||
|
fontFamily: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fonts: {
|
||||||
|
heading: 'var(--font-heading, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
body: 'var(--font-body, Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial)',
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
|
const ADDITIONAL_TAGS = ['iframe'];
|
||||||
|
const ADDITIONAL_ATTRS = [
|
||||||
|
'allow',
|
||||||
|
'allowfullscreen',
|
||||||
|
'class',
|
||||||
|
'data-bullets',
|
||||||
|
'data-filters',
|
||||||
|
'data-img-id',
|
||||||
|
'data-list',
|
||||||
|
'rel',
|
||||||
|
'style',
|
||||||
|
'target',
|
||||||
|
];
|
||||||
|
|
||||||
|
export function sanitizeRichHtml(html: string | null | undefined): string {
|
||||||
|
const sanitized = DOMPurify.sanitize(html ?? '', {
|
||||||
|
USE_PROFILES: { html: true },
|
||||||
|
ADD_TAGS: ADDITIONAL_TAGS,
|
||||||
|
ADD_ATTR: ADDITIONAL_ATTRS,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof window === 'undefined' || !sanitized) {
|
||||||
|
return sanitized;
|
||||||
|
}
|
||||||
|
|
||||||
|
const template = window.document.createElement('template');
|
||||||
|
template.innerHTML = sanitized;
|
||||||
|
|
||||||
|
template.content.querySelectorAll<HTMLAnchorElement>('a[target="_blank"]').forEach((anchor) => {
|
||||||
|
const rel = new Set((anchor.getAttribute('rel') ?? '').split(/\s+/).filter(Boolean));
|
||||||
|
rel.add('noopener');
|
||||||
|
rel.add('noreferrer');
|
||||||
|
anchor.setAttribute('rel', Array.from(rel).join(' '));
|
||||||
|
});
|
||||||
|
|
||||||
|
return template.innerHTML;
|
||||||
|
}
|
||||||
@@ -22,7 +22,11 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"jsx": "react-jsx"
|
"jsx": "react-jsx",
|
||||||
|
"types": [
|
||||||
|
"vite/client",
|
||||||
|
"vitest/globals"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"src"
|
"src"
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import path from 'node:path';
|
||||||
|
import { URL } from 'node:url';
|
||||||
|
import { defineConfig, loadEnv } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
|
||||||
|
function resolveBackendOrigin(env: Record<string, string>) {
|
||||||
|
const raw = env.REACT_APP_API_BASE_URL || env.REACT_APP_API_URL || '';
|
||||||
|
const fallback = 'http://127.0.0.1:8080';
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!raw || raw.startsWith('/')) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsed = new URL(raw);
|
||||||
|
parsed.pathname = '/';
|
||||||
|
parsed.search = '';
|
||||||
|
parsed.hash = '';
|
||||||
|
return parsed.toString();
|
||||||
|
} catch {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildProcessEnv(mode: string, env: Record<string, string>, base: string) {
|
||||||
|
const processEnv: Record<string, string> = {
|
||||||
|
NODE_ENV: mode === 'production' ? 'production' : mode,
|
||||||
|
PUBLIC_URL: base === '/' ? '' : base.replace(/\/$/, ''),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(env)) {
|
||||||
|
if (key.startsWith('REACT_APP_')) {
|
||||||
|
processEnv[key] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return processEnv;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineConfig(({ mode }) => {
|
||||||
|
const env = loadEnv(mode, process.cwd(), '');
|
||||||
|
const base = env.PUBLIC_URL ? (env.PUBLIC_URL.endsWith('/') ? env.PUBLIC_URL : `${env.PUBLIC_URL}/`) : '/';
|
||||||
|
const backendOrigin = resolveBackendOrigin(env);
|
||||||
|
const processEnv = buildProcessEnv(mode, env, base);
|
||||||
|
const commonProxy = {
|
||||||
|
target: backendOrigin,
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
base,
|
||||||
|
publicDir: 'public',
|
||||||
|
plugins: [react()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': path.resolve(__dirname, 'src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
'process.env': JSON.stringify(processEnv),
|
||||||
|
global: 'globalThis',
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: 'build',
|
||||||
|
assetsDir: 'static',
|
||||||
|
emptyOutDir: true,
|
||||||
|
sourcemap: false,
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 3000,
|
||||||
|
proxy: {
|
||||||
|
'/api': commonProxy,
|
||||||
|
'/uploads': commonProxy,
|
||||||
|
'/s': commonProxy,
|
||||||
|
'/r': commonProxy,
|
||||||
|
'/static': commonProxy,
|
||||||
|
'/dist': commonProxy,
|
||||||
|
'/cache': commonProxy,
|
||||||
|
'/images': commonProxy,
|
||||||
|
'/img': commonProxy,
|
||||||
|
'/media': commonProxy,
|
||||||
|
'/files': commonProxy,
|
||||||
|
'/logos': commonProxy,
|
||||||
|
'/avatars': commonProxy,
|
||||||
|
'/downloads': commonProxy,
|
||||||
|
'/public': commonProxy,
|
||||||
|
'/favicon.ico': commonProxy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
preview: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 4173,
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
environment: 'jsdom',
|
||||||
|
globals: true,
|
||||||
|
setupFiles: 'src/setupTests.ts',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
module fotbal-club
|
module fotbal-club
|
||||||
|
|
||||||
go 1.23.0
|
go 1.25.0
|
||||||
|
|
||||||
toolchain go1.24.4
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/PuerkitoBio/goquery v1.10.3
|
github.com/PuerkitoBio/goquery v1.10.3
|
||||||
@@ -16,14 +14,17 @@ require (
|
|||||||
github.com/jung-kurt/gofpdf v1.16.2
|
github.com/jung-kurt/gofpdf v1.16.2
|
||||||
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762
|
github.com/muesli/clusters v0.0.0-20200529215643-2700303c1762
|
||||||
github.com/muesli/kmeans v0.3.1
|
github.com/muesli/kmeans v0.3.1
|
||||||
|
github.com/pressly/goose/v3 v3.27.0
|
||||||
github.com/prometheus/client_golang v1.20.5
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/sqlc-dev/sqlc v1.30.0
|
||||||
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/vanng822/go-premailer v1.25.0
|
github.com/vanng822/go-premailer v1.25.0
|
||||||
github.com/xuri/excelize/v2 v2.9.0
|
github.com/xuri/excelize/v2 v2.9.0
|
||||||
golang.org/x/crypto v0.39.0
|
go.uber.org/zap v1.27.1
|
||||||
|
golang.org/x/crypto v0.48.0
|
||||||
golang.org/x/image v0.18.0
|
golang.org/x/image v0.18.0
|
||||||
golang.org/x/text v0.26.0
|
golang.org/x/text v0.34.0
|
||||||
gopkg.in/mail.v2 v2.3.1
|
gopkg.in/mail.v2 v2.3.1
|
||||||
gorm.io/datatypes v1.2.6
|
gorm.io/datatypes v1.2.6
|
||||||
gorm.io/driver/postgres v1.5.7
|
gorm.io/driver/postgres v1.5.7
|
||||||
@@ -32,58 +33,91 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.1.0 // indirect
|
cel.dev/expr v0.25.1 // indirect
|
||||||
|
filippo.io/edwards25519 v1.2.0 // indirect
|
||||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bytedance/sonic v1.11.6 // indirect
|
github.com/bytedance/sonic v1.11.6 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.4 // indirect
|
github.com/cloudwego/base64x v0.1.4 // indirect
|
||||||
github.com/cloudwego/iasm v0.2.0 // indirect
|
github.com/cloudwego/iasm v0.2.0 // indirect
|
||||||
|
github.com/cubicdaiya/gonp v1.0.4 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
|
github.com/fatih/structtag v1.2.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
github.com/go-sql-driver/mysql v1.9.3 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/google/cel-go v0.26.1 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||||
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
github.com/jackc/pgx/v5 v5.8.0 // indirect
|
||||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // indirect
|
github.com/klauspost/compress v1.18.4 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||||
github.com/kr/text v0.2.0 // indirect
|
|
||||||
github.com/leodido/go-urn v1.4.0 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.15 // indirect
|
github.com/mattn/go-sqlite3 v1.14.15 // indirect
|
||||||
|
github.com/mfridman/interpolate v0.0.2 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/pganalyze/pg_query_go/v6 v6.1.0 // indirect
|
||||||
|
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb // indirect
|
||||||
|
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 // indirect
|
||||||
|
github.com/pingcap/log v1.1.0 // indirect
|
||||||
|
github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.55.0 // indirect
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.19.2 // indirect
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||||
github.com/richardlehane/msoleps v1.0.4 // indirect
|
github.com/richardlehane/msoleps v1.0.4 // indirect
|
||||||
|
github.com/riza-io/grpc-go v0.2.0 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
|
github.com/sethvargo/go-retry v0.3.0 // indirect
|
||||||
|
github.com/spf13/cobra v1.9.1 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.7 // indirect
|
||||||
|
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
github.com/vanng822/css v1.0.1 // indirect
|
github.com/vanng822/css v1.0.1 // indirect
|
||||||
|
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 // indirect
|
||||||
|
github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 // indirect
|
||||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
||||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
||||||
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/arch v0.8.0 // indirect
|
golang.org/x/arch v0.8.0 // indirect
|
||||||
golang.org/x/net v0.41.0 // indirect
|
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
|
||||||
golang.org/x/sync v0.15.0 // indirect
|
golang.org/x/net v0.50.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
google.golang.org/protobuf v1.34.2 // indirect
|
golang.org/x/sys v0.41.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
|
||||||
|
google.golang.org/grpc v1.79.1 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.11 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
gorm.io/driver/mysql v1.5.6 // indirect
|
gorm.io/driver/mysql v1.5.6 // indirect
|
||||||
|
modernc.org/libc v1.68.0 // indirect
|
||||||
|
modernc.org/mathutil v1.7.1 // indirect
|
||||||
|
modernc.org/memory v1.11.0 // indirect
|
||||||
|
modernc.org/sqlite v1.46.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=
|
||||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
|
||||||
|
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
||||||
|
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
|
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
|
||||||
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
||||||
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
|
||||||
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||||
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
@@ -17,12 +23,18 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
|
|||||||
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
|
github.com/cubicdaiya/gonp v1.0.4 h1:ky2uIAJh81WiLcGKBVD5R7KsM/36W6IqqTy6Bo6rGws=
|
||||||
|
github.com/cubicdaiya/gonp v1.0.4/go.mod h1:iWGuP/7+JVTn02OWhRemVbMmG1DOUnmrGTYYACpOI0I=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||||
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||||
|
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||||
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
github.com/gin-contrib/gzip v1.0.1 h1:HQ8ENHODeLY7a4g1Au/46Z92bdGFl74OhxcZble9WJE=
|
||||||
@@ -31,6 +43,10 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
|||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
|
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
@@ -40,8 +56,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
|
|||||||
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
|
||||||
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||||
@@ -51,21 +67,34 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2V
|
|||||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
|
github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ=
|
||||||
|
github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||||
|
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||||
|
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo=
|
||||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw=
|
||||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
@@ -78,14 +107,17 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
|||||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||||
github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc=
|
github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc=
|
||||||
github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0=
|
github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0=
|
||||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||||
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
@@ -96,8 +128,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
|||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
|
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
|
||||||
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
|
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
|
||||||
|
github.com/microsoft/go-mssqldb v1.9.6 h1:1MNQg5UiSsokiPz3++K2KPx4moKrwIqly1wv+RyCKTw=
|
||||||
|
github.com/microsoft/go-mssqldb v1.9.6/go.mod h1:yYMPDufyoF2vVuVCUGtZARr06DKFIhMrluTcgWlXpr4=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@@ -112,44 +146,81 @@ github.com/muesli/kmeans v0.3.1 h1:KshLQ8wAETfLWOJKMuDCVYHnafddSa1kwGh/IypGIzY=
|
|||||||
github.com/muesli/kmeans v0.3.1/go.mod h1:8/OvJW7cHc1BpRf8URb43m+vR105DDe+Kj1WcFXYDqc=
|
github.com/muesli/kmeans v0.3.1/go.mod h1:8/OvJW7cHc1BpRf8URb43m+vR105DDe+Kj1WcFXYDqc=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
|
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||||
|
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/pganalyze/pg_query_go/v6 v6.1.0 h1:jG5ZLhcVgL1FAw4C/0VNQaVmX1SUJx71wBGdtTtBvls=
|
||||||
|
github.com/pganalyze/pg_query_go/v6 v6.1.0/go.mod h1:nvTHIuoud6e1SfrUaFwHqT0i4b5Nr+1rPWVds3B5+50=
|
||||||
github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
|
github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
|
||||||
|
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||||
|
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb h1:3pSi4EDG6hg0orE1ndHkXvX6Qdq2cZn8gAPir8ymKZk=
|
||||||
|
github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
|
||||||
|
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86 h1:tdMsjOqUR7YXHoBitzdebTvOjs/swniBTOLy5XiMtuE=
|
||||||
|
github.com/pingcap/failpoint v0.0.0-20240528011301-b51a646c7c86/go.mod h1:exzhVYca3WRtd6gclGNErRWb1qEgff3LYta0LvRmON4=
|
||||||
|
github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8=
|
||||||
|
github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4=
|
||||||
|
github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0 h1:W3rpAI3bubR6VWOcwxDIG0Gz9G5rl5b3SL116T0vBt0=
|
||||||
|
github.com/pingcap/tidb/pkg/parser v0.0.0-20250324122243-d51e00e5bbf0/go.mod h1:+8feuexTKcXHZF/dkDfvCwEyBAmgb4paFc3/WeYV2eE=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/pressly/goose/v3 v3.27.0 h1:/D30gVTuQhu0WsNZYbJi4DMOsx1lNq+6SkLe+Wp59BM=
|
||||||
|
github.com/pressly/goose/v3 v3.27.0/go.mod h1:3ZBeCXqzkgIRvrEMDkYh1guvtoJTU5oMMuDdkutoM78=
|
||||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
|
github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00=
|
||||||
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||||
|
github.com/riza-io/grpc-go v0.2.0 h1:2HxQKFVE7VuYstcJ8zqpN84VnAoJ4dCL6YFhJewNcHQ=
|
||||||
|
github.com/riza-io/grpc-go v0.2.0/go.mod h1:2bDvR9KkKC3KhtlSHfR3dAXjUMT86kg4UfWFyVGWqi8=
|
||||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||||
|
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
|
||||||
|
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
|
||||||
|
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||||
|
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||||
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||||
|
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/sqlc-dev/sqlc v1.30.0 h1:H4HrNwPc0hntxGWzAbhlfplPRN4bQpXFx+CaEMcKz6c=
|
||||||
|
github.com/sqlc-dev/sqlc v1.30.0/go.mod h1:QnEN+npugyhUg1A+1kkYM3jc2OMOFsNlZ1eh8mdhad0=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||||
@@ -158,6 +229,10 @@ github.com/vanng822/css v1.0.1 h1:10yiXc4e8NI8ldU6mSrWmSWMuyWgPr9DZ63RSlsgDw8=
|
|||||||
github.com/vanng822/css v1.0.1/go.mod h1:tcnB1voG49QhCrwq1W0w5hhGasvOg+VQp9i9H1rCM1w=
|
github.com/vanng822/css v1.0.1/go.mod h1:tcnB1voG49QhCrwq1W0w5hhGasvOg+VQp9i9H1rCM1w=
|
||||||
github.com/vanng822/go-premailer v1.25.0 h1:hGHKfroCXrCDTyGVR8o4HCON5/HWvc7C1uocS+VnaZs=
|
github.com/vanng822/go-premailer v1.25.0 h1:hGHKfroCXrCDTyGVR8o4HCON5/HWvc7C1uocS+VnaZs=
|
||||||
github.com/vanng822/go-premailer v1.25.0/go.mod h1:8WJKIPZtegxqSOA8+eDFx7QNesKmMYfGEIodLTJqrtM=
|
github.com/vanng822/go-premailer v1.25.0/go.mod h1:8WJKIPZtegxqSOA8+eDFx7QNesKmMYfGEIodLTJqrtM=
|
||||||
|
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 h1:mJdDDPblDfPe7z7go8Dvv1AJQDI3eQ/5xith3q2mFlo=
|
||||||
|
github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07/go.mod h1:Ak17IJ037caFp4jpCw/iQQ7/W74Sqpb1YuKJU6HTKfM=
|
||||||
|
github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 h1:OvLBa8SqJnZ6P+mjlzc2K7PM22rRUPE1x32G9DTPrC4=
|
||||||
|
github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52/go.mod h1:jMeV4Vpbi8osrE/pKUxRZkVaA0EX7NZN0A9/oRzgpgY=
|
||||||
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
|
||||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
|
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY=
|
||||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||||
@@ -166,6 +241,33 @@ github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmji
|
|||||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
|
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
|
||||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
|
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||||
|
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||||
|
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||||
|
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
|
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||||
|
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||||
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||||
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
|
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||||
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
|
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||||
|
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||||
|
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||||
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
|
||||||
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||||
@@ -175,18 +277,24 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||||
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
|
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||||
|
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
|
||||||
|
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
|
||||||
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
|
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||||
|
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
@@ -196,8 +304,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
|||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||||
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
|
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@@ -205,8 +313,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
|||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@@ -219,8 +327,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@@ -239,25 +347,48 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
|||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||||
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
|
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||||
|
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||||
|
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||||
|
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
|
||||||
|
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||||
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
|
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
|
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
|
||||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/datatypes v1.2.6 h1:KafLdXvFUhzNeL2ncm03Gl3eTLONQfNKZ+wJ+9Y4Nck=
|
gorm.io/datatypes v1.2.6 h1:KafLdXvFUhzNeL2ncm03Gl3eTLONQfNKZ+wJ+9Y4Nck=
|
||||||
@@ -274,5 +405,33 @@ gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
|||||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
|
||||||
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
|
||||||
|
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
|
||||||
|
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
|
modernc.org/ccgo/v4 v4.30.2 h1:4yPaaq9dXYXZ2V8s1UgrC3KIj580l2N4ClrLwnbv2so=
|
||||||
|
modernc.org/ccgo/v4 v4.30.2/go.mod h1:yZMnhWEdW0qw3EtCndG1+ldRrVGS+bIwyWmAWzS0XEw=
|
||||||
|
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
|
||||||
|
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||||
|
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||||
|
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||||
|
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
|
||||||
|
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||||
|
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||||
|
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||||
|
modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ=
|
||||||
|
modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0=
|
||||||
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||||
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||||
|
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||||
|
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||||
|
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||||
|
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||||
|
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||||
|
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||||
|
modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=
|
||||||
|
modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
|
||||||
|
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||||
|
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||||
|
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||||
|
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ type SEOController struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSEOController(db *gorm.DB) *SEOController {
|
func NewSEOController(db *gorm.DB) *SEOController {
|
||||||
// Ensure settings table has the SEO fields
|
|
||||||
_ = db.AutoMigrate(&models.Settings{})
|
|
||||||
return &SEOController{DB: db}
|
return &SEOController{DB: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,14 +311,30 @@ func (s *SEOController) UpdateSEOSettings(c *gin.Context) {
|
|||||||
|
|
||||||
// Update only provided fields
|
// Update only provided fields
|
||||||
updates := map[string]interface{}{}
|
updates := map[string]interface{}{}
|
||||||
if body.SiteTitle != nil { updates["site_title"] = strings.TrimSpace(*body.SiteTitle) }
|
if body.SiteTitle != nil {
|
||||||
if body.SiteDescription != nil { updates["site_description"] = strings.TrimSpace(*body.SiteDescription) }
|
updates["site_title"] = strings.TrimSpace(*body.SiteTitle)
|
||||||
if body.MetaKeywords != nil { updates["meta_keywords"] = strings.TrimSpace(*body.MetaKeywords) }
|
}
|
||||||
if body.DefaultOGImageURL != nil { updates["default_og_image_url"] = strings.TrimSpace(*body.DefaultOGImageURL) }
|
if body.SiteDescription != nil {
|
||||||
if body.TwitterHandle != nil { updates["twitter_handle"] = strings.TrimSpace(*body.TwitterHandle) }
|
updates["site_description"] = strings.TrimSpace(*body.SiteDescription)
|
||||||
if body.CanonicalBaseURL != nil { updates["canonical_base_url"] = strings.TrimSpace(*body.CanonicalBaseURL) }
|
}
|
||||||
if body.AdditionalMeta != nil { updates["additional_meta"] = *body.AdditionalMeta }
|
if body.MetaKeywords != nil {
|
||||||
if body.EnableIndexing != nil { updates["enable_indexing"] = *body.EnableIndexing }
|
updates["meta_keywords"] = strings.TrimSpace(*body.MetaKeywords)
|
||||||
|
}
|
||||||
|
if body.DefaultOGImageURL != nil {
|
||||||
|
updates["default_og_image_url"] = strings.TrimSpace(*body.DefaultOGImageURL)
|
||||||
|
}
|
||||||
|
if body.TwitterHandle != nil {
|
||||||
|
updates["twitter_handle"] = strings.TrimSpace(*body.TwitterHandle)
|
||||||
|
}
|
||||||
|
if body.CanonicalBaseURL != nil {
|
||||||
|
updates["canonical_base_url"] = strings.TrimSpace(*body.CanonicalBaseURL)
|
||||||
|
}
|
||||||
|
if body.AdditionalMeta != nil {
|
||||||
|
updates["additional_meta"] = *body.AdditionalMeta
|
||||||
|
}
|
||||||
|
if body.EnableIndexing != nil {
|
||||||
|
updates["enable_indexing"] = *body.EnableIndexing
|
||||||
|
}
|
||||||
|
|
||||||
if len(updates) > 0 {
|
if len(updates) > 0 {
|
||||||
if err := s.DB.Model(&settings).Updates(updates).Error; err != nil {
|
if err := s.DB.Model(&settings).Updates(updates).Error; err != nil {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
|
||||||
|
package eshopreporting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DBTX interface {
|
||||||
|
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
|
||||||
|
PrepareContext(context.Context, string) (*sql.Stmt, error)
|
||||||
|
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
|
||||||
|
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db DBTX) *Queries {
|
||||||
|
return &Queries{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Queries struct {
|
||||||
|
db DBTX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
|
||||||
|
return &Queries{
|
||||||
|
db: tx,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
// source: eshop_reporting.sql
|
||||||
|
|
||||||
|
package eshopreporting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
const listOrderStatusBreakdown = `-- name: ListOrderStatusBreakdown :many
|
||||||
|
SELECT
|
||||||
|
status,
|
||||||
|
COUNT(*)::bigint AS order_count
|
||||||
|
FROM eshop_orders
|
||||||
|
WHERE deleted_at IS NULL
|
||||||
|
GROUP BY status
|
||||||
|
ORDER BY order_count DESC, status ASC
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListOrderStatusBreakdownRow struct {
|
||||||
|
Status sql.NullString `json:"status"`
|
||||||
|
OrderCount int64 `json:"order_count"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) ListOrderStatusBreakdown(ctx context.Context) ([]ListOrderStatusBreakdownRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, listOrderStatusBreakdown)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ListOrderStatusBreakdownRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListOrderStatusBreakdownRow
|
||||||
|
if err := rows.Scan(&i.Status, &i.OrderCount); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const listRecentOrderSummaries = `-- name: ListRecentOrderSummaries :many
|
||||||
|
SELECT
|
||||||
|
o.id,
|
||||||
|
o.order_number,
|
||||||
|
o.status,
|
||||||
|
o.total_amount_cents,
|
||||||
|
o.currency,
|
||||||
|
o.shipping_method,
|
||||||
|
o.shipping_price_cents,
|
||||||
|
o.created_at,
|
||||||
|
COALESCE(p.status, '') AS payment_status,
|
||||||
|
COALESCE(s.status, '') AS shipping_status
|
||||||
|
FROM eshop_orders AS o
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT ep.status
|
||||||
|
FROM eshop_payments AS ep
|
||||||
|
WHERE ep.order_id = o.id
|
||||||
|
AND ep.deleted_at IS NULL
|
||||||
|
ORDER BY ep.created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
) AS p ON TRUE
|
||||||
|
LEFT JOIN LATERAL (
|
||||||
|
SELECT sl.status
|
||||||
|
FROM eshop_shipping_labels AS sl
|
||||||
|
WHERE sl.order_id = o.id
|
||||||
|
AND sl.deleted_at IS NULL
|
||||||
|
ORDER BY sl.created_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
) AS s ON TRUE
|
||||||
|
WHERE o.deleted_at IS NULL
|
||||||
|
ORDER BY o.created_at DESC
|
||||||
|
LIMIT $1
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListRecentOrderSummariesRow struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
OrderNumber string `json:"order_number"`
|
||||||
|
Status sql.NullString `json:"status"`
|
||||||
|
TotalAmountCents int64 `json:"total_amount_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
ShippingMethod sql.NullString `json:"shipping_method"`
|
||||||
|
ShippingPriceCents sql.NullInt64 `json:"shipping_price_cents"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
PaymentStatus string `json:"payment_status"`
|
||||||
|
ShippingStatus string `json:"shipping_status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) ListRecentOrderSummaries(ctx context.Context, limit int32) ([]ListRecentOrderSummariesRow, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, listRecentOrderSummaries, limit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
var items []ListRecentOrderSummariesRow
|
||||||
|
for rows.Next() {
|
||||||
|
var i ListRecentOrderSummariesRow
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.OrderNumber,
|
||||||
|
&i.Status,
|
||||||
|
&i.TotalAmountCents,
|
||||||
|
&i.Currency,
|
||||||
|
&i.ShippingMethod,
|
||||||
|
&i.ShippingPriceCents,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.PaymentStatus,
|
||||||
|
&i.ShippingStatus,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
items = append(items, i)
|
||||||
|
}
|
||||||
|
if err := rows.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return items, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const summarizeOrderRevenue = `-- name: SummarizeOrderRevenue :one
|
||||||
|
SELECT
|
||||||
|
COUNT(*)::bigint AS order_count,
|
||||||
|
COALESCE(SUM(total_amount_cents), 0)::bigint AS gross_revenue_cents,
|
||||||
|
COALESCE(SUM(shipping_price_cents), 0)::bigint AS shipping_revenue_cents
|
||||||
|
FROM eshop_orders
|
||||||
|
WHERE deleted_at IS NULL
|
||||||
|
AND created_at >= $1
|
||||||
|
AND created_at < $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type SummarizeOrderRevenueParams struct {
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
CreatedAt_2 sql.NullTime `json:"created_at_2"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SummarizeOrderRevenueRow struct {
|
||||||
|
OrderCount int64 `json:"order_count"`
|
||||||
|
GrossRevenueCents int64 `json:"gross_revenue_cents"`
|
||||||
|
ShippingRevenueCents int64 `json:"shipping_revenue_cents"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) SummarizeOrderRevenue(ctx context.Context, arg SummarizeOrderRevenueParams) (SummarizeOrderRevenueRow, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, summarizeOrderRevenue, arg.CreatedAt, arg.CreatedAt_2)
|
||||||
|
var i SummarizeOrderRevenueRow
|
||||||
|
err := row.Scan(&i.OrderCount, &i.GrossRevenueCents, &i.ShippingRevenueCents)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
|
||||||
|
package eshopreporting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EshopCart struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
UserID sql.NullInt32 `json:"user_id"`
|
||||||
|
SessionToken sql.NullString `json:"session_token"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
Completed sql.NullBool `json:"completed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopCartItem struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
CartID int32 `json:"cart_id"`
|
||||||
|
ProductID int32 `json:"product_id"`
|
||||||
|
VariantID sql.NullInt32 `json:"variant_id"`
|
||||||
|
Quantity int32 `json:"quantity"`
|
||||||
|
UnitPriceCents int64 `json:"unit_price_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopOrder struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
OrderNumber string `json:"order_number"`
|
||||||
|
UserID sql.NullInt32 `json:"user_id"`
|
||||||
|
SessionToken sql.NullString `json:"session_token"`
|
||||||
|
Email sql.NullString `json:"email"`
|
||||||
|
FirstName sql.NullString `json:"first_name"`
|
||||||
|
LastName sql.NullString `json:"last_name"`
|
||||||
|
BillingAddressJson sql.NullString `json:"billing_address_json"`
|
||||||
|
ShippingAddressJson sql.NullString `json:"shipping_address_json"`
|
||||||
|
Status sql.NullString `json:"status"`
|
||||||
|
TotalAmountCents int64 `json:"total_amount_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
ShippingMethod sql.NullString `json:"shipping_method"`
|
||||||
|
ShippingPriceCents sql.NullInt64 `json:"shipping_price_cents"`
|
||||||
|
ShippingDataJson sql.NullString `json:"shipping_data_json"`
|
||||||
|
MetadataJson sql.NullString `json:"metadata_json"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopOrderItem struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
OrderID int32 `json:"order_id"`
|
||||||
|
ProductID int32 `json:"product_id"`
|
||||||
|
VariantID sql.NullInt32 `json:"variant_id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Sku sql.NullString `json:"sku"`
|
||||||
|
Quantity int32 `json:"quantity"`
|
||||||
|
UnitPriceCents int64 `json:"unit_price_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
VatRate sql.NullString `json:"vat_rate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopPayment struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
OrderID int32 `json:"order_id"`
|
||||||
|
Provider sql.NullString `json:"provider"`
|
||||||
|
ProviderPaymentID sql.NullString `json:"provider_payment_id"`
|
||||||
|
Status sql.NullString `json:"status"`
|
||||||
|
AmountCents int64 `json:"amount_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
RawPayloadJson sql.NullString `json:"raw_payload_json"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopProduct struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ShortDescription sql.NullString `json:"short_description"`
|
||||||
|
DescriptionHtml sql.NullString `json:"description_html"`
|
||||||
|
PriceCents int64 `json:"price_cents"`
|
||||||
|
Currency sql.NullString `json:"currency"`
|
||||||
|
VatRate sql.NullString `json:"vat_rate"`
|
||||||
|
Active sql.NullBool `json:"active"`
|
||||||
|
StockMode sql.NullString `json:"stock_mode"`
|
||||||
|
DefaultImageUrl sql.NullString `json:"default_image_url"`
|
||||||
|
GalleryJson sql.NullString `json:"gallery_json"`
|
||||||
|
Tags sql.NullString `json:"tags"`
|
||||||
|
MetadataJson sql.NullString `json:"metadata_json"`
|
||||||
|
CategoryID sql.NullInt32 `json:"category_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopProductCategory struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ParentID sql.NullInt32 `json:"parent_id"`
|
||||||
|
DisplayOrder sql.NullInt32 `json:"display_order"`
|
||||||
|
Active sql.NullBool `json:"active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopProductVariant struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
ProductID int32 `json:"product_id"`
|
||||||
|
Sku sql.NullString `json:"sku"`
|
||||||
|
Name sql.NullString `json:"name"`
|
||||||
|
AttributesJson sql.NullString `json:"attributes_json"`
|
||||||
|
StockQty sql.NullInt32 `json:"stock_qty"`
|
||||||
|
Barcode sql.NullString `json:"barcode"`
|
||||||
|
ImageUrl sql.NullString `json:"image_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopSetting struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
DefaultCurrency sql.NullString `json:"default_currency"`
|
||||||
|
SupportedCurrencies sql.NullString `json:"supported_currencies"`
|
||||||
|
DefaultCountry sql.NullString `json:"default_country"`
|
||||||
|
ShippingOptionsJson sql.NullString `json:"shipping_options_json"`
|
||||||
|
TermsUrl sql.NullString `json:"terms_url"`
|
||||||
|
ReturnsPolicyUrl sql.NullString `json:"returns_policy_url"`
|
||||||
|
SupportEmail sql.NullString `json:"support_email"`
|
||||||
|
SupportPhone sql.NullString `json:"support_phone"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EshopShippingLabel struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
CreatedAt sql.NullTime `json:"created_at"`
|
||||||
|
UpdatedAt sql.NullTime `json:"updated_at"`
|
||||||
|
DeletedAt sql.NullTime `json:"deleted_at"`
|
||||||
|
OrderID int32 `json:"order_id"`
|
||||||
|
Carrier sql.NullString `json:"carrier"`
|
||||||
|
PacketaPacketID sql.NullString `json:"packeta_packet_id"`
|
||||||
|
TrackingNumber sql.NullString `json:"tracking_number"`
|
||||||
|
LabelUrl sql.NullString `json:"label_url"`
|
||||||
|
Status sql.NullString `json:"status"`
|
||||||
|
HistoryJson sql.NullString `json:"history_json"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID int32 `json:"id"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.30.0
|
||||||
|
|
||||||
|
package eshopreporting
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Querier interface {
|
||||||
|
ListOrderStatusBreakdown(ctx context.Context) ([]ListOrderStatusBreakdownRow, error)
|
||||||
|
ListRecentOrderSummaries(ctx context.Context, limit int32) ([]ListRecentOrderSummariesRow, error)
|
||||||
|
SummarizeOrderRevenue(ctx context.Context, arg SummarizeOrderRevenueParams) (SummarizeOrderRevenueRow, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Querier = (*Queries)(nil)
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package dbschema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fotbal-club/internal/models"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AllModels returns the complete set of persisted models used to bootstrap the schema.
|
||||||
|
func AllModels() []interface{} {
|
||||||
|
return []interface{}{
|
||||||
|
&models.SetupInfo{},
|
||||||
|
&models.ClubInfo{},
|
||||||
|
&models.Settings{},
|
||||||
|
&models.User{},
|
||||||
|
&models.UserProfile{},
|
||||||
|
&models.Article{},
|
||||||
|
&models.Category{},
|
||||||
|
&models.ArticleTeamLink{},
|
||||||
|
&models.ArticleMatchLink{},
|
||||||
|
&models.Team{},
|
||||||
|
&models.Player{},
|
||||||
|
&models.Club{},
|
||||||
|
&models.Sponsor{},
|
||||||
|
&models.Banner{},
|
||||||
|
&models.ScoreboardState{},
|
||||||
|
&models.ContactCategory{},
|
||||||
|
&models.Contact{},
|
||||||
|
&models.ContactMessage{},
|
||||||
|
&models.NewsletterSubscription{},
|
||||||
|
&models.PasswordReset{},
|
||||||
|
&models.VisitorEvent{},
|
||||||
|
&models.AboutPage{},
|
||||||
|
&models.EmailLog{},
|
||||||
|
&models.EmailEvent{},
|
||||||
|
&models.NewsletterSentLog{},
|
||||||
|
&models.MatchNotification{},
|
||||||
|
&models.BlogNotification{},
|
||||||
|
&models.MatchOverride{},
|
||||||
|
&models.TeamLogoOverride{},
|
||||||
|
&models.NavigationItem{},
|
||||||
|
&models.SocialLink{},
|
||||||
|
&models.PageElementConfig{},
|
||||||
|
&models.ShortLink{},
|
||||||
|
&models.LinkClick{},
|
||||||
|
&models.Poll{},
|
||||||
|
&models.PollOption{},
|
||||||
|
&models.PollVote{},
|
||||||
|
&models.Comment{},
|
||||||
|
&models.CommentReaction{},
|
||||||
|
&models.CommentBan{},
|
||||||
|
&models.UnbanRequest{},
|
||||||
|
&models.CommentReport{},
|
||||||
|
&models.PointsTransaction{},
|
||||||
|
&models.Achievement{},
|
||||||
|
&models.UserAchievement{},
|
||||||
|
&models.RewardItem{},
|
||||||
|
&models.RewardRedemption{},
|
||||||
|
&models.Sweepstake{},
|
||||||
|
&models.SweepstakePrize{},
|
||||||
|
&models.SweepstakeEntry{},
|
||||||
|
&models.SweepstakeWinner{},
|
||||||
|
&models.UploadedFile{},
|
||||||
|
&models.FileUsage{},
|
||||||
|
&models.ErrorEvent{},
|
||||||
|
&models.CompetitionAlias{},
|
||||||
|
&models.Clothing{},
|
||||||
|
&models.Language{},
|
||||||
|
&models.Translation{},
|
||||||
|
&models.ContentTranslation{},
|
||||||
|
&models.UserLanguagePreference{},
|
||||||
|
&models.ManualCompetition{},
|
||||||
|
&models.ManualMatch{},
|
||||||
|
&models.ManualTableRow{},
|
||||||
|
&models.Event{},
|
||||||
|
&models.EventAttachment{},
|
||||||
|
&models.QRCode{},
|
||||||
|
&models.EshopProductCategory{},
|
||||||
|
&models.EshopProduct{},
|
||||||
|
&models.EshopProductVariant{},
|
||||||
|
&models.EshopCart{},
|
||||||
|
&models.EshopCartItem{},
|
||||||
|
&models.EshopOrder{},
|
||||||
|
&models.EshopOrderItem{},
|
||||||
|
&models.EshopPayment{},
|
||||||
|
&models.EshopShippingLabel{},
|
||||||
|
&models.EshopSettings{},
|
||||||
|
&models.Facility{},
|
||||||
|
&models.FacilityAvailabilityRule{},
|
||||||
|
&models.FacilityBooking{},
|
||||||
|
&models.FacilityEquipment{},
|
||||||
|
&models.FacilityMaintenance{},
|
||||||
|
&models.WeatherCondition{},
|
||||||
|
&models.FacilityBookingTemplate{},
|
||||||
|
&models.Budget{},
|
||||||
|
&models.Sponsorship{},
|
||||||
|
&models.SponsorshipPayment{},
|
||||||
|
&models.SponsorshipDocument{},
|
||||||
|
&models.Expense{},
|
||||||
|
&models.ExpenseDocument{},
|
||||||
|
&models.FinancialReport{},
|
||||||
|
&models.FinancialSettings{},
|
||||||
|
&models.Invoice{},
|
||||||
|
&models.InvoiceItem{},
|
||||||
|
&models.InvoicePayment{},
|
||||||
|
&models.InvoiceCustomer{},
|
||||||
|
&models.InvoiceTemplate{},
|
||||||
|
&models.InvoiceSettings{},
|
||||||
|
&models.InvoiceSequence{},
|
||||||
|
&models.AuditLog{},
|
||||||
|
&models.TicketType{},
|
||||||
|
&models.TicketCampaign{},
|
||||||
|
&models.CampaignTicketType{},
|
||||||
|
&models.Ticket{},
|
||||||
|
&models.TicketAvailability{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AutoMigrate(db *gorm.DB) error {
|
||||||
|
return db.AutoMigrate(AllModels()...)
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
VITE_API_BASE_URL=
|
||||||
|
VITE_SITE_URL=https://example.com
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# MyClub Landing
|
||||||
|
|
||||||
|
Samostatná publikovatelná landing page pro `MyClub` v root složce `/landing`.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
- React + TypeScript + Vite
|
||||||
|
- Tailwind CSS v4
|
||||||
|
- shadcn/ui primitives
|
||||||
|
- Montserrat variable font
|
||||||
|
- Form submission přes existující `POST /api/v1/contact`
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd landing
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Dev server běží na `http://localhost:4174`.
|
||||||
|
|
||||||
|
Výchozí proxy posílá `/api/*` na `http://localhost:8080`, takže při lokálním běhu backendu není potřeba nastavovat extra URL.
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
|
||||||
|
Zkopírujte `.env.example` podle potřeby:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Podporované proměnné:
|
||||||
|
|
||||||
|
- `VITE_API_BASE_URL`: volitelné. Pokud je prázdné, používá se same-origin `/api/...`
|
||||||
|
- `VITE_SITE_URL`: volitelné. Pokud je nastavené, doplní canonical a absolutní OG/Twitter URL
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd landing
|
||||||
|
npm run build
|
||||||
|
npm run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
Výstup je v `landing/dist`.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://ui.shadcn.com/schema.json",
|
||||||
|
"style": "radix-nova",
|
||||||
|
"rsc": false,
|
||||||
|
"tsx": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "",
|
||||||
|
"css": "src/index.css",
|
||||||
|
"baseColor": "neutral",
|
||||||
|
"cssVariables": true,
|
||||||
|
"prefix": ""
|
||||||
|
},
|
||||||
|
"iconLibrary": "lucide",
|
||||||
|
"rtl": false,
|
||||||
|
"aliases": {
|
||||||
|
"components": "@/components",
|
||||||
|
"utils": "@/lib/utils",
|
||||||
|
"ui": "@/components/ui",
|
||||||
|
"lib": "@/lib",
|
||||||
|
"hooks": "@/hooks"
|
||||||
|
},
|
||||||
|
"menuColor": "default",
|
||||||
|
"menuAccent": "subtle",
|
||||||
|
"registries": {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
js.configs.recommended,
|
||||||
|
tseslint.configs.recommended,
|
||||||
|
reactHooks.configs.flat.recommended,
|
||||||
|
reactRefresh.configs.vite,
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': ['error', { allowConstantExport: true }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['src/components/ui/button.tsx', 'src/components/ui/badge.tsx'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': 'off',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="cs">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="theme-color" content="rgb(108 56 217)" />
|
||||||
|
<meta name="color-scheme" content="light" />
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
content="MyClub spojuje klubový web, MyUIbrix builder, zápasy, obsah, partnery, newslettery i provozní workflow do jednoho přehledného systému pro sportovní kluby."
|
||||||
|
/>
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:site_name" content="MyClub" />
|
||||||
|
<meta property="og:title" content="MyClub | Web, obsah a provoz klubu v jednom systému" />
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="MyClub spojuje klubový web, MyUIbrix builder, zápasy, obsah, partnery, newslettery i provozní workflow do jednoho přehledného systému pro sportovní kluby."
|
||||||
|
/>
|
||||||
|
<meta property="og:image" content="/og-cover.svg" />
|
||||||
|
<meta name="twitter:card" content="summary" />
|
||||||
|
<meta name="twitter:title" content="MyClub | Web, obsah a provoz klubu v jednom systému" />
|
||||||
|
<meta
|
||||||
|
name="twitter:description"
|
||||||
|
content="MyClub spojuje klubový web, MyUIbrix builder, zápasy, obsah, partnery, newslettery i provozní workflow do jednoho přehledného systému pro sportovní kluby."
|
||||||
|
/>
|
||||||
|
<meta name="twitter:image" content="/og-cover.svg" />
|
||||||
|
<title>MyClub | Web, obsah a provoz klubu v jednom systému</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"name": "landing",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fontsource-variable/montserrat": "^5.2.8",
|
||||||
|
"@hookform/resolvers": "^5.2.2",
|
||||||
|
"axios": "^1.13.6",
|
||||||
|
"class-variance-authority": "^0.7.1",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"lucide-react": "^0.577.0",
|
||||||
|
"radix-ui": "^1.4.3",
|
||||||
|
"react": "^19.2.4",
|
||||||
|
"react-dom": "^19.2.4",
|
||||||
|
"react-hook-form": "^7.71.2",
|
||||||
|
"shadcn": "^4.0.6",
|
||||||
|
"tailwind-merge": "^3.5.0",
|
||||||
|
"tw-animate-css": "^1.4.0",
|
||||||
|
"zod": "^4.3.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.39.4",
|
||||||
|
"@tailwindcss/vite": "^4.2.1",
|
||||||
|
"@types/node": "^24.12.0",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"@vitejs/plugin-react": "^5.2.0",
|
||||||
|
"eslint": "^9.39.4",
|
||||||
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
|
"eslint-plugin-react-refresh": "^0.5.2",
|
||||||
|
"globals": "^17.4.0",
|
||||||
|
"tailwindcss": "^4.2.1",
|
||||||
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"typescript": "~5.9.3",
|
||||||
|
"typescript-eslint": "^8.56.1",
|
||||||
|
"vite": "^7.3.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="MyClub">
|
||||||
|
<rect width="128" height="128" rx="32" fill="rgb(255 255 255)" />
|
||||||
|
<rect x="10" y="10" width="108" height="108" rx="28" fill="rgb(255 255 255)" stroke="rgba(17,24,39,0.14)" stroke-width="2" />
|
||||||
|
<path d="M32 94V34h12l20 30 20-30h12v60H84V58L64 87 44 58v36H32Z" fill="rgb(108 56 217)" />
|
||||||
|
<circle cx="98" cy="34" r="12" fill="rgba(255,153,51,0.24)" />
|
||||||
|
<circle cx="98" cy="34" r="6" fill="rgb(255 153 51)" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 514 B |
@@ -0,0 +1,18 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 630" role="img" aria-label="MyClub Open Graph Cover">
|
||||||
|
<rect width="1200" height="630" fill="rgb(255 255 255)" />
|
||||||
|
<rect x="42" y="42" width="1116" height="546" rx="36" fill="rgb(255 255 255)" stroke="rgba(17,24,39,0.1)" stroke-width="2" />
|
||||||
|
<circle cx="180" cy="126" r="88" fill="rgba(108,56,217,0.14)" />
|
||||||
|
<circle cx="1032" cy="128" r="72" fill="rgba(255,153,51,0.18)" />
|
||||||
|
<path d="M110 454V182h68l112 168 112-168h68v272h-68V291L290 429 178 291v163h-68Z" fill="rgb(108 56 217)" />
|
||||||
|
<rect x="552" y="170" width="520" height="290" rx="30" fill="rgba(108,56,217,0.05)" stroke="rgba(17,24,39,0.08)" />
|
||||||
|
<rect x="590" y="210" width="230" height="132" rx="24" fill="rgb(255 255 255)" stroke="rgba(17,24,39,0.08)" />
|
||||||
|
<rect x="848" y="210" width="186" height="60" rx="20" fill="rgba(255,153,51,0.18)" />
|
||||||
|
<rect x="848" y="286" width="186" height="56" rx="20" fill="rgb(255 255 255)" stroke="rgba(17,24,39,0.08)" />
|
||||||
|
<rect x="590" y="362" width="444" height="58" rx="20" fill="rgb(255 255 255)" stroke="rgba(17,24,39,0.08)" />
|
||||||
|
<text x="552" y="520" fill="rgb(17 24 39)" font-family="Montserrat, sans-serif" font-size="58" font-weight="700" letter-spacing="-2">
|
||||||
|
MyClub
|
||||||
|
</text>
|
||||||
|
<text x="552" y="574" fill="rgb(75 85 99)" font-family="Montserrat, sans-serif" font-size="28">
|
||||||
|
Web, obsah a provoz klubu v jednom systému
|
||||||
|
</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,429 @@
|
|||||||
|
import {
|
||||||
|
ArrowRight,
|
||||||
|
Check,
|
||||||
|
ChevronRight,
|
||||||
|
LayoutDashboard,
|
||||||
|
MailPlus,
|
||||||
|
Sparkles,
|
||||||
|
Image as ImageIcon,
|
||||||
|
} from 'lucide-react'
|
||||||
|
|
||||||
|
import {
|
||||||
|
contactChecklist,
|
||||||
|
faqItems,
|
||||||
|
featureCards,
|
||||||
|
navItems,
|
||||||
|
operationalPillars,
|
||||||
|
proofPoints,
|
||||||
|
workflowSteps,
|
||||||
|
} from '@/content'
|
||||||
|
import { useLandingSeo } from '@/hooks/useLandingSeo'
|
||||||
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
|
||||||
|
import { Badge } from '@/components/ui/badge'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
|
import { ContactForm } from '@/components/landing/ContactForm'
|
||||||
|
import { HeroVisual } from '@/components/landing/HeroVisual'
|
||||||
|
import { SectionHeading } from '@/components/landing/SectionHeading'
|
||||||
|
import { SiteHeader } from '@/components/landing/SiteHeader'
|
||||||
|
import { VideoText } from '@/components/ui/video-text'
|
||||||
|
|
||||||
|
useLandingSeo()
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<div id="top" className="landing-shell">
|
||||||
|
<SiteHeader items={navItems} />
|
||||||
|
|
||||||
|
<main className="pb-16 pt-24 sm:pt-28">
|
||||||
|
<section className="relative overflow-hidden pb-14 pt-8 sm:pb-18">
|
||||||
|
<div className="section-shell grid gap-12 lg:grid-cols-[1.02fr_0.98fr] lg:items-center">
|
||||||
|
<div className="relative z-10 flex flex-col gap-7">
|
||||||
|
<Badge className="eyebrow-pill max-w-max">
|
||||||
|
MyClub SaaS pro sportovní kluby
|
||||||
|
</Badge>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-5">
|
||||||
|
<div className="relative h-[120px] w-full overflow-hidden rounded-2xl">
|
||||||
|
<VideoText
|
||||||
|
src="https://cdn.magicui.design/ocean-small.webm"
|
||||||
|
className="absolute inset-0"
|
||||||
|
fontSize={18}
|
||||||
|
fontWeight="800"
|
||||||
|
>
|
||||||
|
Jeden systém pro web, obsah a provoz vašeho klubu.
|
||||||
|
</VideoText>
|
||||||
|
</div>
|
||||||
|
<p className="max-w-2xl text-lg leading-7 text-[rgb(75_85_99)] sm:text-xl sm:leading-8 break-words">
|
||||||
|
MyClub spojuje MyUIbrix builder, zápasy, týmy, partnery, newslettery a
|
||||||
|
klubovou administraci do jedné čisté vrstvy připravené na každodenní provoz.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-3 sm:flex-row">
|
||||||
|
<Button
|
||||||
|
asChild
|
||||||
|
className="h-12 rounded-full px-6 text-sm shadow-[0_18px_34px_rgba(17,24,39,0.12)]"
|
||||||
|
>
|
||||||
|
<a href="#kontakt">
|
||||||
|
Domluvit ukázku
|
||||||
|
<ArrowRight className="size-4" />
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
asChild
|
||||||
|
variant="outline"
|
||||||
|
className="h-12 rounded-full border-[rgba(17,24,39,0.12)] bg-white px-6 text-sm hover:bg-[rgba(108,56,217,0.06)]"
|
||||||
|
>
|
||||||
|
<a href="#ukazka">
|
||||||
|
Projít produktovou vrstvu
|
||||||
|
<ChevronRight className="size-4" />
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4 sm:grid-cols-3">
|
||||||
|
{[
|
||||||
|
'MyUIbrix jako vestavěný editor homepage.',
|
||||||
|
'Klubová data, obsah a komunikace bez pluginové skládačky.',
|
||||||
|
'Připravené fungovat vedle stávajícího backendu a publikace.',
|
||||||
|
].map((item) => (
|
||||||
|
<div key={item} className="rounded-[1.55rem] border border-[rgba(17,24,39,0.08)] bg-white/88 p-5 backdrop-blur-sm transition-all duration-300 hover:shadow-lg hover:bg-white">
|
||||||
|
<div className="mb-3 flex items-center gap-2 text-sm font-semibold text-[rgb(17_24_39)]">
|
||||||
|
<Check className="size-4 text-[rgb(108_56_217)]" />
|
||||||
|
Přímý benefit
|
||||||
|
</div>
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)]">{item}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HeroVisual />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="pb-16 pt-8">
|
||||||
|
<div className="section-shell">
|
||||||
|
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||||
|
{proofPoints.map((item) => (
|
||||||
|
<Card key={item.title} className="surface-panel-soft border-0 p-6 transition-all duration-300 hover:shadow-xl hover:scale-[1.02]">
|
||||||
|
<CardHeader className="p-0 pb-4">
|
||||||
|
<div className="mb-4 flex size-14 items-center justify-center rounded-2xl border border-[rgba(17,24,39,0.08)] bg-white shadow-sm">
|
||||||
|
<item.icon className="size-6 text-[rgb(108_56_217)]" />
|
||||||
|
</div>
|
||||||
|
<CardDescription className="section-label mb-2">{item.eyebrow}</CardDescription>
|
||||||
|
<CardTitle className="text-xl tracking-[-0.04em] leading-7 text-[rgb(17_24_39)]">{item.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)]">{item.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="platforma" className="scroll-mt-28 py-20">
|
||||||
|
<div className="section-shell flex flex-col gap-12">
|
||||||
|
<SectionHeading
|
||||||
|
kicker="Platforma"
|
||||||
|
title="Navržené pro klub, který nechce skládat pět různých systémů."
|
||||||
|
description="Každá vrstva landingu vychází z reálných schopností projektu. Žádná obecná SaaS omáčka, ale konkrétní modulární klubový stack."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="grid gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||||
|
{featureCards.map((item, index) => (
|
||||||
|
<Card
|
||||||
|
key={item.title}
|
||||||
|
className={`
|
||||||
|
${index % 3 === 1 ? 'surface-panel-secondary border-0' : 'surface-panel border-0'}
|
||||||
|
p-6 transition-all duration-300 hover:shadow-xl hover:scale-[1.02]
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<CardHeader className="p-0 pb-4">
|
||||||
|
<div className="mb-4 flex size-14 items-center justify-center rounded-2xl border border-[rgba(17,24,39,0.08)] bg-white shadow-sm">
|
||||||
|
<item.icon
|
||||||
|
className={`
|
||||||
|
${index % 3 === 1 ? 'size-6 text-[rgb(255_153_51)]' : 'size-6 text-[rgb(108_56_217)]'}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CardDescription className="section-label mb-2">{item.eyebrow}</CardDescription>
|
||||||
|
<CardTitle className="text-xl tracking-[-0.04em] leading-7 text-[rgb(17_24_39)]">{item.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="p-0">
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)]">{item.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="ukazka" className="scroll-mt-28 py-20">
|
||||||
|
<div className="section-shell grid gap-12 xl:grid-cols-[1.08fr_0.92fr]">
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
<SectionHeading
|
||||||
|
kicker="Ukázka produktu"
|
||||||
|
title="Editorial sports-tech bez generické šablony."
|
||||||
|
description="Landing používá bílý mód, výraznou typografii a kontrolovanou barevnost. Stejný přístup může nést i veřejný klubový web vystavěný v MyClubu."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card className="surface-panel border-0 py-0 transition-all duration-300 hover:shadow-xl">
|
||||||
|
<CardHeader className="border-b border-[rgba(17,24,39,0.08)] pb-6">
|
||||||
|
<CardDescription className="section-label">ukázková kompozice</CardDescription>
|
||||||
|
<CardTitle className="text-2xl tracking-[-0.05em] leading-8">
|
||||||
|
Homepage builder, který řídí rytmus celého klubu
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="grid gap-6 px-6 py-8 sm:grid-cols-[0.95fr_1.05fr]">
|
||||||
|
<div className="rounded-[1.5rem] border border-[rgba(17,24,39,0.08)] bg-white p-6">
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<span className="section-label">bloky stránky</span>
|
||||||
|
<Sparkles className="size-5 text-[rgb(108_56_217)]" />
|
||||||
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
|
{[
|
||||||
|
'Hero s hlavní kampaní',
|
||||||
|
'Novinky a články',
|
||||||
|
'Příští zápas + tabulka',
|
||||||
|
'Sponzoři a bannery',
|
||||||
|
'Kontakty a mapa',
|
||||||
|
].map((label, index) => (
|
||||||
|
<div
|
||||||
|
key={label}
|
||||||
|
className="flex items-center gap-4 rounded-[1.1rem] border border-[rgba(17,24,39,0.06)] bg-[rgba(17,24,39,0.02)] px-5 py-4 transition-all duration-200 hover:bg-[rgba(17,24,39,0.04)] hover:shadow-sm"
|
||||||
|
>
|
||||||
|
<span className="flex size-8 items-center justify-center rounded-full bg-[rgba(108,56,217,0.08)] text-xs font-semibold text-[rgb(108_56_217)]">
|
||||||
|
0{index + 1}
|
||||||
|
</span>
|
||||||
|
<span className="font-medium text-[rgb(17_24_39)] leading-6">{label}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-[1.5rem] border border-[rgba(17,24,39,0.08)] bg-[linear-gradient(180deg,rgba(108,56,217,0.08),rgba(255,255,255,0.96))] p-6">
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<span className="section-label">preview</span>
|
||||||
|
<LayoutDashboard className="size-5 text-[rgb(17_24_39)]" />
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-4">
|
||||||
|
<div className="rounded-[1.4rem] bg-white p-5">
|
||||||
|
<div className="h-3 w-2/3 rounded-full bg-[rgba(17,24,39,0.12)] mb-4" />
|
||||||
|
<div className="grid grid-cols-3 gap-3">
|
||||||
|
<div className="h-20 rounded-2xl bg-[rgba(108,56,217,0.09)] flex items-center justify-center">
|
||||||
|
<ImageIcon className="size-6 text-[rgb(108_56_217)/20]" />
|
||||||
|
</div>
|
||||||
|
<div className="h-20 rounded-2xl bg-[rgba(255,153,51,0.16)] flex items-center justify-center">
|
||||||
|
<ImageIcon className="size-6 text-[rgb(255_153_51)/20]" />
|
||||||
|
</div>
|
||||||
|
<div className="h-20 rounded-2xl bg-[rgba(17,24,39,0.06)] flex items-center justify-center">
|
||||||
|
<ImageIcon className="size-6 text-[rgb(17_24_39)/15]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="rounded-[1.25rem] bg-white p-4">
|
||||||
|
<div className="h-2.5 w-16 rounded-full bg-[rgba(17,24,39,0.12)] mb-4" />
|
||||||
|
<div className="h-20 rounded-[1rem] bg-[rgba(108,56,217,0.08)] flex items-center justify-center">
|
||||||
|
<ImageIcon className="size-5 text-[rgb(108_56_217)/15]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-[1.25rem] bg-white p-4">
|
||||||
|
<div className="h-2.5 w-16 rounded-full bg-[rgba(17,24,39,0.12)] mb-4" />
|
||||||
|
<div className="h-20 rounded-[1rem] bg-[rgba(255,153,51,0.16)] flex items-center justify-center">
|
||||||
|
<ImageIcon className="size-5 text-[rgb(255_153_51)/15]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
{operationalPillars.map((item, index) => (
|
||||||
|
<Card
|
||||||
|
key={item.title}
|
||||||
|
className={`
|
||||||
|
${index === 1 ? 'surface-panel-secondary border-0' : 'surface-panel-soft border-0'}
|
||||||
|
transition-all duration-300 hover:shadow-xl hover:scale-[1.02]
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<CardHeader>
|
||||||
|
<div className="mb-4 flex size-14 items-center justify-center rounded-2xl border border-[rgba(17,24,39,0.08)] bg-white shadow-sm">
|
||||||
|
<item.icon
|
||||||
|
className={`
|
||||||
|
${index === 1 ? 'size-6 text-[rgb(255_153_51)]' : 'size-6 text-[rgb(108_56_217)]'}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<CardDescription className="section-label mb-2">{item.eyebrow}</CardDescription>
|
||||||
|
<CardTitle className="text-xl tracking-[-0.04em] leading-7 text-[rgb(17_24_39)]">{item.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)]">{item.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="workflow" className="scroll-mt-28 py-20">
|
||||||
|
<div className="section-shell flex flex-col gap-12">
|
||||||
|
<SectionHeading
|
||||||
|
kicker="Jak to funguje"
|
||||||
|
title="Od první identity klubu po každodenní publikaci."
|
||||||
|
description="Workflow je navržené tak, aby produkt dával smysl vedení klubu, redakci i operativě okolo zápasového provozu."
|
||||||
|
align="center"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="grid gap-6 lg:grid-cols-4">
|
||||||
|
{workflowSteps.map((step, index) => (
|
||||||
|
<Card
|
||||||
|
key={step.step}
|
||||||
|
className={`
|
||||||
|
${index === 1 || index === 3 ? 'surface-panel-secondary border-0' : 'surface-panel border-0'}
|
||||||
|
transition-all duration-300 hover:shadow-xl hover:scale-[1.02] relative overflow-hidden
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-br from-transparent via-white/5 to-transparent opacity-0 transition-opacity duration-300 group-hover:opacity-100" />
|
||||||
|
<CardHeader className="relative z-10">
|
||||||
|
<div className="flex items-center justify-between gap-4">
|
||||||
|
<span className="rounded-full bg-white px-4 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] shadow-sm border border-[rgba(17,24,39,0.08)]">
|
||||||
|
krok {step.step}
|
||||||
|
</span>
|
||||||
|
<span className="text-3xl font-semibold tracking-[-0.05em] text-[rgba(17,24,39,0.2)]">
|
||||||
|
{step.step}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<CardTitle className="text-xl tracking-[-0.04em] leading-7 text-[rgb(17_24_39)] mt-4">{step.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="relative z-10">
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)]">{step.description}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="faq" className="scroll-mt-28 py-20">
|
||||||
|
<div className="section-shell grid gap-12 xl:grid-cols-[0.95fr_1.05fr]">
|
||||||
|
<SectionHeading
|
||||||
|
kicker="FAQ"
|
||||||
|
title="Krátké odpovědi na věci, které padnou nejdřív."
|
||||||
|
description="Landing je postavený jako publikovatelná poptávková vrstva. Níže jsou odpovědi, které drží směr produktu i technického nasazení."
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Card className="surface-panel border-0 transition-all duration-300 hover:shadow-xl">
|
||||||
|
<CardContent className="px-8 py-6">
|
||||||
|
<Accordion type="single" collapsible className="space-y-4">
|
||||||
|
{faqItems.map((item) => (
|
||||||
|
<AccordionItem
|
||||||
|
key={item.question}
|
||||||
|
value={item.question}
|
||||||
|
className="border border-[rgba(17,24,39,0.08)] rounded-xl px-6 transition-all duration-200 hover:bg-[rgba(17,24,39,0.02]"
|
||||||
|
>
|
||||||
|
<AccordionTrigger className="text-base font-semibold text-[rgb(17_24_39)] hover:text-[rgb(108_56_217)] transition-colors duration-200">
|
||||||
|
{item.question}
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent className="text-sm leading-6 text-[rgb(75_85_99)] pt-4">
|
||||||
|
{item.answer}
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="kontakt" className="scroll-mt-28 py-20">
|
||||||
|
<div className="section-shell">
|
||||||
|
<div className="grid gap-12 rounded-[2rem] border border-[rgba(17,24,39,0.08)] bg-[linear-gradient(135deg,rgba(108,56,217,0.08),rgba(255,255,255,0.98),rgba(255,153,51,0.14))] p-8 shadow-[0_28px_80px_rgba(17,24,39,0.08)] lg:grid-cols-[0.9fr_1.1fr] lg:p-10">
|
||||||
|
<div className="flex flex-col gap-8">
|
||||||
|
<Badge className="eyebrow-pill max-w-max">CTA a poptávka</Badge>
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
<h2 className="section-title text-[clamp(2.2rem,4vw,4rem)] max-w-lg">
|
||||||
|
Chcete si projít, jak bude MyClub fungovat pro váš klub?
|
||||||
|
</h2>
|
||||||
|
<p className="section-copy max-w-xl">
|
||||||
|
Pošlete stručný kontext a landing použije existující veřejný endpoint projektu. Tím je hotová
|
||||||
|
první publikovatelná vrstva bez dalších backend zásahů.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4">
|
||||||
|
{contactChecklist.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item}
|
||||||
|
className="flex items-start gap-4 rounded-[1.35rem] border border-[rgba(17,24,39,0.08)] bg-white/86 px-5 py-5 transition-all duration-300 hover:bg-white hover:shadow-md"
|
||||||
|
>
|
||||||
|
<span className="mt-0.5 flex size-9 shrink-0 items-center justify-center rounded-full bg-[rgba(108,56,217,0.08)] text-[rgb(108_56_217)]">
|
||||||
|
<Check className="size-5" />
|
||||||
|
</span>
|
||||||
|
<p className="text-sm leading-7 text-[rgb(17_24_39)]">{item}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-[1.45rem] border border-[rgba(17,24,39,0.08)] bg-white/88 p-6 transition-all duration-300 hover:bg-white hover:shadow-md">
|
||||||
|
<div className="mb-3 flex items-center gap-3 text-sm font-semibold text-[rgb(17_24_39)]">
|
||||||
|
<MailPlus className="size-5 text-[rgb(255_153_51)]" />
|
||||||
|
Technická poznámka
|
||||||
|
</div>
|
||||||
|
<p className="text-sm leading-7 text-[rgb(75_85_99)]">
|
||||||
|
V developmentu funguje formulář přes Vite proxy na <code className="px-2 py-1 bg-[rgba(108,56,217,0.08)] rounded-md">localhost:8080</code>. V produkci
|
||||||
|
může zůstat same-origin nebo využít <code className="px-2 py-1 bg-[rgba(108,56,217,0.08)] rounded-md">VITE_API_BASE_URL</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card className="surface-panel border-0 bg-white/92 transition-all duration-300 hover:shadow-xl">
|
||||||
|
<CardHeader>
|
||||||
|
<CardDescription className="section-label">pracující formulář</CardDescription>
|
||||||
|
<CardTitle className="text-2xl tracking-[-0.05em] leading-8">
|
||||||
|
Pošlete poptávku přes stávající backend
|
||||||
|
</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<ContactForm />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer className="border-t border-[rgba(17,24,39,0.08)] py-12 bg-gradient-to-b from-white to-[rgba(108,56,217,0.02)]">
|
||||||
|
<div className="section-shell flex flex-col gap-8 md:flex-row md:items-center md:justify-between">
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<p className="text-xl font-bold tracking-[-0.03em] text-[rgb(17_24_39)]">
|
||||||
|
MyClub
|
||||||
|
</p>
|
||||||
|
<p className="text-sm leading-6 text-[rgb(75_85_99)] max-w-md">
|
||||||
|
Web, obsah, partneři a klubový provoz bez generické CMS skládačky.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-wrap items-center gap-6 text-sm font-medium text-[rgb(75_85_99)]">
|
||||||
|
{navItems.map((item) => (
|
||||||
|
<a
|
||||||
|
key={item.href}
|
||||||
|
href={item.href}
|
||||||
|
className="transition-all duration-200 hover:text-[rgb(108_56_217)] hover:translate-y-[-1px]"
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { ArrowRight, LoaderCircle } from 'lucide-react'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
|
import { submitContactForm } from '@/lib/api'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
|
|
||||||
|
const contactSchema = z.object({
|
||||||
|
name: z.string().min(2, 'Zadejte prosím jméno nebo název klubu.'),
|
||||||
|
email: z.email('Zadejte prosím platný e-mail.'),
|
||||||
|
subject: z.string().min(3, 'Napište stručné téma poptávky.'),
|
||||||
|
message: z.string().min(24, 'Doplňte prosím alespoň krátký kontext, co chcete řešit.'),
|
||||||
|
})
|
||||||
|
|
||||||
|
type ContactValues = z.infer<typeof contactSchema>
|
||||||
|
|
||||||
|
const defaultValues: ContactValues = {
|
||||||
|
name: '',
|
||||||
|
email: '',
|
||||||
|
subject: 'Mám zájem o ukázku MyClubu',
|
||||||
|
message: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
type FormStatus =
|
||||||
|
| { type: 'success'; message: string }
|
||||||
|
| { type: 'error'; message: string }
|
||||||
|
| null
|
||||||
|
|
||||||
|
export function ContactForm() {
|
||||||
|
const [status, setStatus] = useState<FormStatus>(null)
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
handleSubmit,
|
||||||
|
reset,
|
||||||
|
formState: { errors, isSubmitting },
|
||||||
|
} = useForm<ContactValues>({
|
||||||
|
resolver: zodResolver(contactSchema),
|
||||||
|
defaultValues,
|
||||||
|
})
|
||||||
|
|
||||||
|
async function onSubmit(values: ContactValues) {
|
||||||
|
setStatus(null)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await submitContactForm(values)
|
||||||
|
reset(defaultValues)
|
||||||
|
setStatus({
|
||||||
|
type: 'success',
|
||||||
|
message:
|
||||||
|
'Poptávka byla odeslána. Pokud je backend správně nakonfigurovaný, zpráva právě dorazila do klubové kontaktní vrstvy.',
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
let message =
|
||||||
|
'Odeslání se nepodařilo. Zkontrolujte, že běží backend a že endpoint /api/v1/contact přijímá veřejné formuláře.'
|
||||||
|
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
const serverMessage =
|
||||||
|
typeof error.response?.data?.error === 'string'
|
||||||
|
? error.response.data.error
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (serverMessage) {
|
||||||
|
if (/failed to save message/i.test(serverMessage)) {
|
||||||
|
message =
|
||||||
|
'Server zprávu přijal, ale nepodařilo se ji uložit. Zkontrolujte databázi a nastavení kontaktního formuláře na backendu.'
|
||||||
|
} else if (/invalid payload/i.test(serverMessage)) {
|
||||||
|
message = 'Server odmítl odeslaná data. Zkontrolujte prosím vyplněná pole.'
|
||||||
|
} else if (/valid email is required/i.test(serverMessage)) {
|
||||||
|
message = 'Zadejte prosím platný e-mail.'
|
||||||
|
} else {
|
||||||
|
message = serverMessage
|
||||||
|
}
|
||||||
|
} else if (error.code === 'ECONNABORTED') {
|
||||||
|
message = 'Server neodpověděl včas. Zkuste odeslání znovu nebo zkontrolujte backend.'
|
||||||
|
} else if (!error.response) {
|
||||||
|
message = 'Nepodařilo se spojit s API. V developmentu ověřte proxy nebo VITE_API_BASE_URL.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setStatus({ type: 'error', message })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="flex flex-col gap-5" onSubmit={handleSubmit(onSubmit)} noValidate>
|
||||||
|
<div className="grid gap-5 sm:grid-cols-2">
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-sm font-semibold text-[rgb(17_24_39)]" htmlFor="name">
|
||||||
|
Jméno / klub
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
id="name"
|
||||||
|
placeholder="Například FK Example / Jan Novák"
|
||||||
|
aria-invalid={errors.name ? true : undefined}
|
||||||
|
className="h-12 rounded-2xl border-[rgba(17,24,39,0.1)] bg-white px-4 text-[rgb(17_24_39)] placeholder:text-[rgba(75,85,99,0.7)]"
|
||||||
|
{...register('name')}
|
||||||
|
/>
|
||||||
|
{errors.name ? <p className="form-feedback">{errors.name.message}</p> : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-sm font-semibold text-[rgb(17_24_39)]" htmlFor="email">
|
||||||
|
E-mail
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
id="email"
|
||||||
|
type="email"
|
||||||
|
placeholder="vas@email.cz"
|
||||||
|
aria-invalid={errors.email ? true : undefined}
|
||||||
|
className="h-12 rounded-2xl border-[rgba(17,24,39,0.1)] bg-white px-4 text-[rgb(17_24_39)] placeholder:text-[rgba(75,85,99,0.7)]"
|
||||||
|
{...register('email')}
|
||||||
|
/>
|
||||||
|
{errors.email ? <p className="form-feedback">{errors.email.message}</p> : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-sm font-semibold text-[rgb(17_24_39)]" htmlFor="subject">
|
||||||
|
Co chcete řešit
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
id="subject"
|
||||||
|
aria-invalid={errors.subject ? true : undefined}
|
||||||
|
className="h-12 rounded-2xl border-[rgba(17,24,39,0.1)] bg-white px-4 text-[rgb(17_24_39)] placeholder:text-[rgba(75,85,99,0.7)]"
|
||||||
|
{...register('subject')}
|
||||||
|
/>
|
||||||
|
{errors.subject ? <p className="form-feedback">{errors.subject.message}</p> : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<label className="text-sm font-semibold text-[rgb(17_24_39)]" htmlFor="message">
|
||||||
|
Krátký kontext
|
||||||
|
</label>
|
||||||
|
<Textarea
|
||||||
|
id="message"
|
||||||
|
rows={6}
|
||||||
|
placeholder="Popište klub, stávající web, jak dnes funguje obsah a co má nová platforma zjednodušit."
|
||||||
|
aria-invalid={errors.message ? true : undefined}
|
||||||
|
className="min-h-36 rounded-[1.35rem] border-[rgba(17,24,39,0.1)] bg-white px-4 py-3 text-[rgb(17_24_39)] placeholder:text-[rgba(75,85,99,0.7)]"
|
||||||
|
{...register('message')}
|
||||||
|
/>
|
||||||
|
{errors.message ? <p className="form-feedback">{errors.message.message}</p> : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
className="h-12 rounded-full px-6 text-sm shadow-[0_16px_32px_rgba(17,24,39,0.12)]"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
>
|
||||||
|
{isSubmitting ? (
|
||||||
|
<>
|
||||||
|
<LoaderCircle className="size-4 animate-spin" />
|
||||||
|
Odesílám
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
Domluvit ukázku
|
||||||
|
<ArrowRight className="size-4" />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<p className="max-w-xs text-sm leading-6 text-[rgb(75_85_99)]">
|
||||||
|
Formulář používá stávající veřejný endpoint projektu. V produkci stačí stejné origin API nebo
|
||||||
|
nastavit <code>VITE_API_BASE_URL</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div aria-live="polite" className="min-h-6">
|
||||||
|
{status ? (
|
||||||
|
<p
|
||||||
|
className={
|
||||||
|
status.type === 'success'
|
||||||
|
? 'rounded-3xl border border-[rgba(108,56,217,0.15)] bg-[rgba(108,56,217,0.07)] px-4 py-3 text-sm leading-6 text-[rgb(17_24_39)]'
|
||||||
|
: 'rounded-3xl border border-[rgba(255,153,51,0.24)] bg-[rgba(255,153,51,0.12)] px-4 py-3 text-sm leading-6 text-[rgb(17_24_39)]'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{status.message}
|
||||||
|
</p>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
import {
|
||||||
|
ArrowUpRight,
|
||||||
|
CalendarRange,
|
||||||
|
ChartColumnIncreasing,
|
||||||
|
Layers3,
|
||||||
|
MailPlus,
|
||||||
|
Trophy,
|
||||||
|
Image as ImageIcon,
|
||||||
|
} from 'lucide-react'
|
||||||
|
|
||||||
|
import { Badge } from '@/components/ui/badge'
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||||
|
import { VideoText } from '@/components/ui/video-text'
|
||||||
|
|
||||||
|
export function HeroVisual() {
|
||||||
|
return (
|
||||||
|
<div className="relative mx-auto w-full max-w-[680px]">
|
||||||
|
<div className="hero-halo hero-halo-primary absolute -left-16 top-16 size-56" />
|
||||||
|
<div className="hero-halo hero-halo-secondary absolute -right-12 top-4 size-52" />
|
||||||
|
|
||||||
|
<Card className="surface-panel relative overflow-hidden rounded-[2rem] border-0 py-0 transition-all duration-500 hover:shadow-2xl">
|
||||||
|
<CardHeader className="border-b border-[rgba(17,24,39,0.08)] px-8 py-6">
|
||||||
|
<div className="flex items-center justify-between gap-4">
|
||||||
|
<div className="flex-1">
|
||||||
|
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-[rgb(108_56_217)] mb-3">
|
||||||
|
produktová ukázka
|
||||||
|
</p>
|
||||||
|
<CardTitle className="text-2xl tracking-[-0.04em] leading-8">
|
||||||
|
Řídicí vrstva pro klubový web
|
||||||
|
</CardTitle>
|
||||||
|
</div>
|
||||||
|
<Badge
|
||||||
|
variant="outline"
|
||||||
|
className="hidden border-[rgba(17,24,39,0.08)] bg-white px-4 py-2 text-[rgb(75_85_99)] sm:inline-flex shadow-sm"
|
||||||
|
>
|
||||||
|
white mode only
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
<CardDescription className="max-w-xl text-[rgb(75_85_99)] mt-3 leading-6">
|
||||||
|
MyUIbrix, klubový obsah, partneři i matchday přehled v jedné kompozici.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
|
<CardContent className="grid gap-6 px-8 py-8 lg:grid-cols-[1.08fr_0.92fr]">
|
||||||
|
<div className="space-y-5">
|
||||||
|
<div className="mock-window dashboard-grid rounded-[1.75rem] p-5">
|
||||||
|
<div className="mb-5 flex items-center justify-between gap-4">
|
||||||
|
<div className="flex gap-3">
|
||||||
|
<span className="size-3 rounded-full bg-[rgba(108,56,217,0.45)] shadow-sm" />
|
||||||
|
<span className="size-3 rounded-full bg-[rgba(255,153,51,0.45)] shadow-sm" />
|
||||||
|
<span className="size-3 rounded-full bg-[rgba(17,24,39,0.18)] shadow-sm" />
|
||||||
|
</div>
|
||||||
|
<div className="rounded-full bg-white px-4 py-2 text-[11px] font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] shadow-sm border border-[rgba(17,24,39,0.08)]">
|
||||||
|
homepage builder
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4">
|
||||||
|
<div className="rounded-[1.3rem] border border-[rgba(108,56,217,0.16)] bg-[rgba(108,56,217,0.07)] p-5">
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3 text-sm font-semibold text-[rgb(17_24_39)]">
|
||||||
|
<Layers3 className="size-5 text-[rgb(108_56_217)]" />
|
||||||
|
Hero + novinky + zápasy
|
||||||
|
</div>
|
||||||
|
<span className="rounded-full bg-white px-3 py-1.5 text-[11px] font-semibold text-[rgb(108_56_217)] shadow-sm border border-[rgba(108,56,217,0.16)]">
|
||||||
|
live preview
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-3">
|
||||||
|
<div className="h-3 w-11/12 rounded-full bg-white/90 shadow-sm" />
|
||||||
|
<div className="h-3 w-8/12 rounded-full bg-white/75 shadow-sm" />
|
||||||
|
<div className="grid grid-cols-3 gap-3 pt-2">
|
||||||
|
<div className="h-20 rounded-2xl bg-white/85 shadow-sm flex items-center justify-center relative overflow-hidden group">
|
||||||
|
<VideoText
|
||||||
|
src="https://cdn.magicui.design/ocean-small.webm"
|
||||||
|
className="absolute inset-0"
|
||||||
|
fontSize={8}
|
||||||
|
>
|
||||||
|
<ImageIcon className="size-8 text-white/80" />
|
||||||
|
</VideoText>
|
||||||
|
</div>
|
||||||
|
<div className="h-20 rounded-2xl bg-white/70 shadow-sm flex items-center justify-center relative overflow-hidden group">
|
||||||
|
<VideoText
|
||||||
|
src="https://cdn.magicui.design/ocean-small.webm"
|
||||||
|
className="absolute inset-0"
|
||||||
|
fontSize={8}
|
||||||
|
>
|
||||||
|
<ImageIcon className="size-8 text-white/80" />
|
||||||
|
</VideoText>
|
||||||
|
</div>
|
||||||
|
<div className="h-20 rounded-2xl bg-white/85 shadow-sm flex items-center justify-center relative overflow-hidden group">
|
||||||
|
<VideoText
|
||||||
|
src="https://cdn.magicui.design/ocean-small.webm"
|
||||||
|
className="absolute inset-0"
|
||||||
|
fontSize={8}
|
||||||
|
>
|
||||||
|
<ImageIcon className="size-8 text-white/80" />
|
||||||
|
</VideoText>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-3 sm:grid-cols-3">
|
||||||
|
<div className="rounded-[1.2rem] border border-[rgba(17,24,39,0.08)] bg-white p-4 transition-all duration-300 hover:shadow-md hover:scale-[1.02]">
|
||||||
|
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] mb-3">
|
||||||
|
články
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 text-xl font-semibold tracking-[-0.04em] text-[rgb(17_24_39)]">
|
||||||
|
redakce
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-[1.2rem] border border-[rgba(17,24,39,0.08)] bg-white p-4 transition-all duration-300 hover:shadow-md hover:scale-[1.02]">
|
||||||
|
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] mb-3">
|
||||||
|
partneři
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 text-xl font-semibold tracking-[-0.04em] text-[rgb(17_24_39)]">
|
||||||
|
bannery
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-[1.2rem] border border-[rgba(17,24,39,0.08)] bg-white p-4 transition-all duration-300 hover:shadow-md hover:scale-[1.02]">
|
||||||
|
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] mb-3">
|
||||||
|
komunikace
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 text-xl font-semibold tracking-[-0.04em] text-[rgb(17_24_39)]">
|
||||||
|
newsletter
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
|
<div className="metric-chip transition-all duration-300 hover:shadow-md hover:scale-[1.02]">
|
||||||
|
<CalendarRange className="size-5 text-[rgb(108_56_217)]" />
|
||||||
|
<span className="text-sm leading-5">Zápasy a tabulky v klubovém layoutu</span>
|
||||||
|
</div>
|
||||||
|
<div className="metric-chip transition-all duration-300 hover:shadow-md hover:scale-[1.02]">
|
||||||
|
<MailPlus className="size-5 text-[rgb(255_153_51)]" />
|
||||||
|
<span className="text-sm leading-5">Kontakty a newsletter bez externí skládačky</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-5">
|
||||||
|
<div className="rounded-[1.75rem] border border-[rgba(17,24,39,0.08)] bg-white p-6 shadow-[0_20px_40px_rgba(17,24,39,0.06)] transition-all duration-300 hover:shadow-xl">
|
||||||
|
<div className="mb-5 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3 text-sm font-semibold text-[rgb(17_24_39)]">
|
||||||
|
<Trophy className="size-5 text-[rgb(255_153_51)]" />
|
||||||
|
Match center
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-semibold uppercase tracking-[0.18em] text-[rgb(75_85_99)]">
|
||||||
|
připraveno na víkend
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{[
|
||||||
|
['1. tým', 'sobota 16:30'],
|
||||||
|
['Dorost U19', 'neděle 10:15'],
|
||||||
|
['Ženy', 'neděle 14:00'],
|
||||||
|
].map(([label, time]) => (
|
||||||
|
<div
|
||||||
|
key={label}
|
||||||
|
className="flex items-center justify-between rounded-[1.1rem] border border-[rgba(17,24,39,0.07)] bg-[rgba(17,24,39,0.02)] px-4 py-3 transition-all duration-200 hover:bg-[rgba(17,24,39,0.04)] hover:shadow-sm"
|
||||||
|
>
|
||||||
|
<span className="font-medium text-[rgb(17_24_39)]">{label}</span>
|
||||||
|
<span className="text-sm text-[rgb(75_85_99)]">{time}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="rounded-[1.75rem] border border-[rgba(17,24,39,0.08)] bg-[linear-gradient(180deg,rgba(255,153,51,0.12),rgba(255,255,255,0.98))] p-6 shadow-[0_20px_40px_rgba(17,24,39,0.06)] transition-all duration-300 hover:shadow-xl">
|
||||||
|
<div className="mb-5 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3 text-sm font-semibold text-[rgb(17_24_39)]">
|
||||||
|
<ChartColumnIncreasing className="size-5 text-[rgb(108_56_217)]" />
|
||||||
|
Přehled vedení
|
||||||
|
</div>
|
||||||
|
<ArrowUpRight className="size-4 text-[rgb(17_24_39)]" />
|
||||||
|
</div>
|
||||||
|
<div className="grid gap-4 sm:grid-cols-2">
|
||||||
|
<div className="rounded-[1.2rem] bg-white/80 p-4 transition-all duration-300 hover:bg-white hover:shadow-sm min-h-[100px] flex flex-col justify-between">
|
||||||
|
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] mb-2">
|
||||||
|
obsah
|
||||||
|
</div>
|
||||||
|
<div className="text-lg font-bold tracking-[-0.02em] text-[rgb(17_24_39)] leading-tight">
|
||||||
|
pod kontrolou
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="rounded-[1.2rem] bg-white/80 p-4 transition-all duration-300 hover:bg-white hover:shadow-sm min-h-[100px] flex flex-col justify-between">
|
||||||
|
<div className="text-xs font-semibold uppercase tracking-[0.2em] text-[rgb(75_85_99)] mb-2">
|
||||||
|
partneři
|
||||||
|
</div>
|
||||||
|
<div className="text-lg font-bold tracking-[-0.02em] text-[rgb(17_24_39)] leading-tight">
|
||||||
|
v publikaci
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
type SectionHeadingProps = {
|
||||||
|
kicker: string
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
align?: 'left' | 'center'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SectionHeading({
|
||||||
|
kicker,
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
align = 'left',
|
||||||
|
}: SectionHeadingProps) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'flex flex-col gap-4',
|
||||||
|
align === 'center' && 'mx-auto max-w-3xl text-center'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<span className="section-kicker">{kicker}</span>
|
||||||
|
<h2 className="section-title text-[clamp(2rem,4vw,3.55rem)]">{title}</h2>
|
||||||
|
<p className="section-copy max-w-3xl">{description}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||