chore: initialize project
Some checks failed
Deploy monie-landing (kaniko) / build-and-deploy (push) Failing after 13s

This commit is contained in:
2026-04-05 17:16:55 +03:00
commit ec3f72113a
38 changed files with 11366 additions and 0 deletions

44
src/components/Footer.tsx Normal file
View File

@@ -0,0 +1,44 @@
export default function Footer() {
const year = new Date().getFullYear()
return (
<footer className="mt-20 border-t border-[var(--line)] px-4 pb-14 pt-10 text-[var(--sea-ink-soft)]">
<div className="page-wrap flex flex-col items-center justify-between gap-4 text-center sm:flex-row sm:text-left">
<p className="m-0 text-sm">
&copy; {year} Your name here. All rights reserved.
</p>
<p className="island-kicker m-0">Built with TanStack Start</p>
</div>
<div className="mt-4 flex justify-center gap-4">
<a
href="https://x.com/tan_stack"
target="_blank"
rel="noreferrer"
className="rounded-xl p-2 text-[var(--sea-ink-soft)] transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)]"
>
<span className="sr-only">Follow TanStack on X</span>
<svg viewBox="0 0 16 16" aria-hidden="true" width="32" height="32">
<path
fill="currentColor"
d="M12.6 1h2.2L10 6.48 15.64 15h-4.41L7.78 9.82 3.23 15H1l5.14-5.84L.72 1h4.52l3.12 4.73L12.6 1zm-.77 12.67h1.22L4.57 2.26H3.26l8.57 11.41z"
/>
</svg>
</a>
<a
href="https://github.com/TanStack"
target="_blank"
rel="noreferrer"
className="rounded-xl p-2 text-[var(--sea-ink-soft)] transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)]"
>
<span className="sr-only">Go to TanStack GitHub</span>
<svg viewBox="0 0 16 16" aria-hidden="true" width="32" height="32">
<path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
/>
</svg>
</a>
</div>
</footer>
)
}

80
src/components/Header.tsx Normal file
View File

@@ -0,0 +1,80 @@
import { Link } from '@tanstack/react-router'
import ParaglideLocaleSwitcher from './LocaleSwitcher.tsx'
import ThemeToggle from './ThemeToggle'
export default function Header() {
return (
<header className="sticky top-0 z-50 border-b border-[var(--line)] bg-[var(--header-bg)] px-4 backdrop-blur-lg">
<nav className="page-wrap flex flex-wrap items-center gap-x-3 gap-y-2 py-3 sm:py-4">
<h2 className="m-0 flex-shrink-0 text-base font-semibold tracking-tight">
<Link
to="/"
className="inline-flex items-center gap-2 rounded-full border border-[var(--chip-line)] bg-[var(--chip-bg)] px-3 py-1.5 text-sm text-[var(--sea-ink)] no-underline shadow-[0_8px_24px_rgba(30,90,72,0.08)] sm:px-4 sm:py-2"
>
<span className="h-2 w-2 rounded-full bg-[linear-gradient(90deg,#56c6be,#7ed3bf)]" />
TanStack Start
</Link>
</h2>
<div className="ml-auto flex items-center gap-1.5 sm:ml-0 sm:gap-2">
<a
href="https://x.com/tan_stack"
target="_blank"
rel="noreferrer"
className="hidden rounded-xl p-2 text-[var(--sea-ink-soft)] transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)] sm:block"
>
<span className="sr-only">Follow TanStack on X</span>
<svg viewBox="0 0 16 16" aria-hidden="true" width="24" height="24">
<path
fill="currentColor"
d="M12.6 1h2.2L10 6.48 15.64 15h-4.41L7.78 9.82 3.23 15H1l5.14-5.84L.72 1h4.52l3.12 4.73L12.6 1zm-.77 12.67h1.22L4.57 2.26H3.26l8.57 11.41z"
/>
</svg>
</a>
<a
href="https://github.com/TanStack"
target="_blank"
rel="noreferrer"
className="hidden rounded-xl p-2 text-[var(--sea-ink-soft)] transition hover:bg-[var(--link-bg-hover)] hover:text-[var(--sea-ink)] sm:block"
>
<span className="sr-only">Go to TanStack GitHub</span>
<svg viewBox="0 0 16 16" aria-hidden="true" width="24" height="24">
<path
fill="currentColor"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"
/>
</svg>
</a>
<ParaglideLocaleSwitcher />
<ThemeToggle />
</div>
<div className="order-3 flex w-full flex-wrap items-center gap-x-4 gap-y-1 pb-1 text-sm font-semibold sm:order-2 sm:w-auto sm:flex-nowrap sm:pb-0">
<Link
to="/"
className="nav-link"
activeProps={{ className: 'nav-link is-active' }}
>
Home
</Link>
<Link
to="/about"
className="nav-link"
activeProps={{ className: 'nav-link is-active' }}
>
About
</Link>
<a
href="https://tanstack.com/start/latest/docs/framework/react/overview"
className="nav-link"
target="_blank"
rel="noreferrer"
>
Docs
</a>
</div>
</nav>
</header>
)
}

View File

@@ -0,0 +1,46 @@
// Locale switcher refs:
// - Paraglide docs: https://inlang.com/m/gerre34r/library-inlang-paraglideJs
// - Router example: https://github.com/TanStack/router/tree/main/examples/react/i18n-paraglide#switching-locale
import { getLocale, locales, setLocale } from '#/paraglide/runtime'
import { m } from '#/paraglide/messages'
export default function ParaglideLocaleSwitcher() {
const currentLocale = getLocale()
return (
<div
style={{
display: 'flex',
gap: '0.5rem',
alignItems: 'center',
color: 'inherit',
}}
aria-label={m.language_label()}
>
<span style={{ opacity: 0.85 }}>
{m.current_locale({ locale: currentLocale })}
</span>
<div style={{ display: 'flex', gap: '0.25rem' }}>
{locales.map((locale) => (
<button
key={locale}
onClick={() => setLocale(locale)}
aria-pressed={locale === currentLocale}
style={{
cursor: 'pointer',
padding: '0.35rem 0.75rem',
borderRadius: '999px',
border: '1px solid #d1d5db',
background: locale === currentLocale ? '#0f172a' : 'transparent',
color: locale === currentLocale ? '#f8fafc' : 'inherit',
fontWeight: locale === currentLocale ? 700 : 500,
letterSpacing: '0.01em',
}}
>
{locale.toUpperCase()}
</button>
))}
</div>
</div>
)
}

View File

@@ -0,0 +1,81 @@
import { useEffect, useState } from 'react'
type ThemeMode = 'light' | 'dark' | 'auto'
function getInitialMode(): ThemeMode {
if (typeof window === 'undefined') {
return 'auto'
}
const stored = window.localStorage.getItem('theme')
if (stored === 'light' || stored === 'dark' || stored === 'auto') {
return stored
}
return 'auto'
}
function applyThemeMode(mode: ThemeMode) {
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
const resolved = mode === 'auto' ? (prefersDark ? 'dark' : 'light') : mode
document.documentElement.classList.remove('light', 'dark')
document.documentElement.classList.add(resolved)
if (mode === 'auto') {
document.documentElement.removeAttribute('data-theme')
} else {
document.documentElement.setAttribute('data-theme', mode)
}
document.documentElement.style.colorScheme = resolved
}
export default function ThemeToggle() {
const [mode, setMode] = useState<ThemeMode>('auto')
useEffect(() => {
const initialMode = getInitialMode()
setMode(initialMode)
applyThemeMode(initialMode)
}, [])
useEffect(() => {
if (mode !== 'auto') {
return
}
const media = window.matchMedia('(prefers-color-scheme: dark)')
const onChange = () => applyThemeMode('auto')
media.addEventListener('change', onChange)
return () => {
media.removeEventListener('change', onChange)
}
}, [mode])
function toggleMode() {
const nextMode: ThemeMode =
mode === 'light' ? 'dark' : mode === 'dark' ? 'auto' : 'light'
setMode(nextMode)
applyThemeMode(nextMode)
window.localStorage.setItem('theme', nextMode)
}
const label =
mode === 'auto'
? 'Theme mode: auto (system). Click to switch to light mode.'
: `Theme mode: ${mode}. Click to switch mode.`
return (
<button
type="button"
onClick={toggleMode}
aria-label={label}
title={label}
className="rounded-full border border-[var(--chip-line)] bg-[var(--chip-bg)] px-3 py-1.5 text-sm font-semibold text-[var(--sea-ink)] shadow-[0_8px_22px_rgba(30,90,72,0.08)] transition hover:-translate-y-0.5"
>
{mode === 'auto' ? 'Auto' : mode === 'dark' ? 'Dark' : 'Light'}
</button>
)
}