2026-07-31 14:56:58 +02:00
|
|
|
import React, { useEffect } from 'react';
|
2026-05-12 19:10:59 +02:00
|
|
|
import Header from './components/Header';
|
|
|
|
|
import Hero from './components/Hero';
|
|
|
|
|
import About from './components/About';
|
|
|
|
|
import Offerings from './components/Offerings';
|
|
|
|
|
import WhyHumanAI from './components/WhyHumanAI';
|
|
|
|
|
import Process from './components/Process';
|
|
|
|
|
import Audience from './components/Audience';
|
|
|
|
|
import CTASection from './components/CTASection';
|
|
|
|
|
import Footer from './components/Footer';
|
2026-06-25 12:53:49 +02:00
|
|
|
import PrivacyPolicyPage from './components/PrivacyPolicyPage';
|
2026-07-31 14:49:06 +02:00
|
|
|
import PlatformPage from './components/PlatformPage';
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
import { useLang, stripLangPrefix } from './i18n';
|
|
|
|
|
import { usePathname } from './router';
|
2026-05-12 19:10:59 +02:00
|
|
|
|
|
|
|
|
function App() {
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
// Reactive, so the language switcher's pushState re-renders the tree instead
|
|
|
|
|
// of leaving a stale page under a changed URL.
|
|
|
|
|
const pathname = usePathname();
|
|
|
|
|
const lang = useLang();
|
|
|
|
|
// One route table for both languages: /en/privacy and /privacy both match
|
|
|
|
|
// '/privacy' here.
|
|
|
|
|
const route = stripLangPrefix(pathname);
|
|
|
|
|
|
|
|
|
|
// index.html ships lang="pl"; keep the document honest on the English routes
|
|
|
|
|
// (screen readers, translation prompts, search engines all read this).
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
document.documentElement.lang = lang;
|
|
|
|
|
}, [lang]);
|
2026-06-25 12:53:49 +02:00
|
|
|
|
2026-07-31 14:56:58 +02:00
|
|
|
// The landing sections are client-rendered, so when a /#section URL arrives
|
|
|
|
|
// with the initial request — following "Oferta"/"Kontakt" from /privacy or
|
|
|
|
|
// /platforma — the browser resolves the fragment before the target exists and
|
|
|
|
|
// leaves the page at the top. Re-apply the scroll once the sections are
|
|
|
|
|
// mounted. In-page clicks never reach this: they are same-document fragment
|
|
|
|
|
// navigations that the browser handles natively (smoothly, via .scroll-smooth)
|
|
|
|
|
// without remounting App.
|
|
|
|
|
useEffect(() => {
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
if (route !== '/') return;
|
2026-07-31 14:56:58 +02:00
|
|
|
const id = window.location.hash.slice(1);
|
|
|
|
|
if (!id) return;
|
|
|
|
|
// Jump rather than smooth-scroll: this only runs on a fresh load, where
|
|
|
|
|
// animating the full page height would just be a slow detour.
|
|
|
|
|
document.getElementById(id)?.scrollIntoView({ behavior: 'auto' });
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
}, [route]);
|
2026-07-31 14:56:58 +02:00
|
|
|
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
if (route === '/privacy') {
|
2026-06-25 12:53:49 +02:00
|
|
|
return <PrivacyPolicyPage />;
|
|
|
|
|
}
|
|
|
|
|
|
feat: wybór języka przez URL (/en) — reaktywny hook, przełącznik, hreflang
Język wynikał z navigator.language liczonego przy każdym renderze, więc nie
dało się go wybrać ani zalinkować. Teraz nośnikiem języka jest ścieżka.
- src/router.ts: usePathname() na useSyncExternalStore + navigate(). pushState
nie emituje zdarzenia, więc bez tego React nie widzi zmiany URL-a.
- i18n: useLang(), localizePath(), stripLangPrefix(), setLang(). useT() czyta
język ze ścieżki i jest reaktywne na nawigację.
- Detekcja przeglądarki tylko przy pierwszym wejściu na "/" i tylko gdy w
localStorage nic nie ma; wynik zapisujemy od razu, więc przekierowanie na
/en zadziała najwyżej raz i nie nadpisze późniejszego wyboru użytkownika.
Deep linki honorujemy bez ruszania.
- App.tsx: jedna tablica tras dla obu języków (/en/privacy -> '/privacy').
Ustawia też document.documentElement.lang, bo index.html ma na sztywno "pl".
- Header: przełącznik PL/EN (desktop + mobile), <button>, nie <a> — link
przeładowałby dokument.
- Hrefy w Header/Footer/PrivacyPolicyPage/PlatformPage przez localizePath,
inaczej /en jest pułapką jednokierunkową: każdy klik wraca na PL.
- index.html: hreflang pl/en/x-default; og:url z gethumanai.com na .pl
(wskazywał na cudzą domenę).
Bez nowych tłumaczeń treści — to osobny krok.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 15:54:49 +02:00
|
|
|
if (route === '/platforma') {
|
2026-07-31 14:49:06 +02:00
|
|
|
return <PlatformPage />;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-12 19:10:59 +02:00
|
|
|
return (
|
|
|
|
|
<div className="min-h-screen bg-background selection:bg-primary selection:text-background">
|
|
|
|
|
<Header />
|
|
|
|
|
<main>
|
|
|
|
|
<Hero />
|
|
|
|
|
<About />
|
|
|
|
|
<Offerings />
|
|
|
|
|
<WhyHumanAI />
|
|
|
|
|
<Process />
|
|
|
|
|
<Audience />
|
|
|
|
|
<CTASection />
|
|
|
|
|
</main>
|
|
|
|
|
<Footer />
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default App;
|