Initial commit
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import type { ReactNode } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { BrandMark } from '../../components/BrandMark'
|
||||
import { Icon } from '../../components/Icon'
|
||||
import type { IconName } from '../../components/Icon'
|
||||
import { useInstanceFavicon } from '../../lib/usePublicConfig'
|
||||
import { useLegal } from '../../lib/useLegal'
|
||||
|
||||
/**
|
||||
* Rama strony publicznej.
|
||||
*
|
||||
* Domyslnie WASKA (`max-w-2xl`): wiekszosc stron publicznych to jeden formularz
|
||||
* albo krotki komunikat, wygodniejszy na telefonie w waskiej kolumnie.
|
||||
*
|
||||
* `wide` przelacza na szerokosc panelu (`max-w-container`, 1200px) - dla stron,
|
||||
* ktore maja miescic wiecej tresci obok siebie i wygladac jak reszta serwisu:
|
||||
* strona zapisu na webinar oraz dokumenty prawne (regulamin, polityka).
|
||||
* Szerokosc ustawia layout, a nie poszczegolna strona - zgodnie z regula, ze
|
||||
* strona nie ustawia wlasnej szerokosci.
|
||||
*/
|
||||
export function PublicLayout({ children, wide = false }: { children: ReactNode; wide?: boolean }) {
|
||||
useInstanceFavicon()
|
||||
const legal = useLegal()
|
||||
const company = legal.data?.company
|
||||
// regulamin i polityka to gotowe dokumenty - sa zawsze dostepne,
|
||||
// wiec odnosniki pokazujemy bezwarunkowo (o ile dane w ogole sie zaladowaly)
|
||||
const ready = Boolean(legal.data)
|
||||
|
||||
const widthClass = wide ? 'max-w-container' : 'max-w-2xl'
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col bg-slate-50">
|
||||
<header className="border-b border-slate-100 bg-white">
|
||||
<div className={`mx-auto flex w-full ${widthClass} items-center px-4 py-4`}>
|
||||
<BrandMark />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className={`mx-auto w-full ${widthClass} flex-1 px-4 py-6 sm:py-10`}>{children}</main>
|
||||
|
||||
{/*
|
||||
Stopka prawna: uczestnik webinaru MUSI mieć dostęp do regulaminu,
|
||||
polityki prywatności i tożsamości administratora danych (RODO).
|
||||
Puste dokumenty nie pokazują odnośnika - odnośnik donikąd jest gorszy
|
||||
niż jego brak.
|
||||
*/}
|
||||
<footer className={`mx-auto w-full ${widthClass} space-y-2 px-4 pb-8 pt-4 pb-safe`}>
|
||||
{ready && (
|
||||
<p className="flex flex-wrap justify-center gap-x-4 gap-y-1 text-xs text-slate-500">
|
||||
<Link to="/regulamin" className="hover:text-slate-700 hover:underline">
|
||||
Regulamin
|
||||
</Link>
|
||||
<Link to="/polityka-prywatnosci" className="hover:text-slate-700 hover:underline">
|
||||
Polityka prywatności
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
{company?.name && (
|
||||
<p className="text-center text-xs text-slate-400">
|
||||
{company.name}
|
||||
{company.address ? `, ${company.address}` : ''}
|
||||
</p>
|
||||
)}
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/** Komunikat zajmujacy cala strone, na przyklad brak miejsc albo webinar odwolany. */
|
||||
export function PublicNotice({
|
||||
icon,
|
||||
title,
|
||||
text,
|
||||
tone = 'neutral',
|
||||
children,
|
||||
}: {
|
||||
icon: IconName
|
||||
title: string
|
||||
text: string
|
||||
tone?: 'neutral' | 'success' | 'warning'
|
||||
children?: ReactNode
|
||||
}) {
|
||||
const tones = {
|
||||
neutral: 'border-slate-100 bg-white',
|
||||
success: 'border-ok-500/20 bg-ok-50',
|
||||
warning: 'border-warn-500/25 bg-warn-50',
|
||||
}
|
||||
const iconTones = {
|
||||
neutral: 'text-slate-300',
|
||||
success: 'text-ok-500',
|
||||
warning: 'text-warn-500',
|
||||
}
|
||||
const textTones = {
|
||||
neutral: 'text-slate-600',
|
||||
success: 'text-ok-600',
|
||||
warning: 'text-warn-600',
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={`rounded-lg border p-6 text-center shadow-sm ${tones[tone]}`}>
|
||||
<span className="mx-auto flex justify-center">
|
||||
<Icon name={icon} size={36} className={iconTones[tone]} />
|
||||
</span>
|
||||
<h2 className="mt-3 text-lg font-semibold text-slate-900">{title}</h2>
|
||||
<p className={`mx-auto mt-1.5 max-w-md text-sm leading-relaxed ${textTones[tone]}`}>{text}</p>
|
||||
{children && <div className="mt-5">{children}</div>}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user