feat(auth): welcome/landing page + email-password login UI (5b)

Replace the old Google-only login card with a public landing page (Welcome.tsx):
hero + auth card (email+password Sign in / Create account / Forgot password,
Continue with Google, explicit Try-the-demo) over a feature pitch (6 pain->solution
cards) and demo-account screenshot slots (graceful placeholder until the images are
dropped into frontend/public/welcome/). Auth forms wire to the 5a endpoints; errors
show inline via a new req() quiet flag (no global modal for a wrong password).
Handles ?verify, ?reset (set-new-password form), ?access banners. EN/HU/DE.
Verified end-to-end on a fresh load: render, register->approve->password-login.
This commit is contained in:
npeter83 2026-06-19 15:15:58 +02:00
parent 732acfce52
commit a81734b4d6
7 changed files with 602 additions and 124 deletions

View file

@ -0,0 +1,73 @@
{
"hero": {
"title": "Deine YouTube-Abos, so wie ein Feed funktionieren sollte.",
"subtitle": "Siftlode sammelt jeden Upload der Kanäle, denen du folgst, in einem aufgeräumten, filterbaren Feed — kein Algorithmus entscheidet, was du siehst, und kein Shorts- oder Live-Lärm, außer du willst es.",
"trust": "Selbst gehostet und privat. Melde dich per E-Mail an oder fahre mit Google fort."
},
"preview": {
"feed": "Der Feed — filtern nach Kanal, Sprache, Thema, Länge und Datum.",
"channels": "Kanal-Verwaltung",
"playlists": "Wiedergabelisten"
},
"features": {
"heading": "Warum Siftlode",
"readable": {
"title": "Deine Abos, endlich lesbar",
"body": "Sortiere und filtere nach Kanal, Sprache, Thema, Länge oder Datum — und blende Kanäle aus, ohne sie zu deabonnieren. Du entscheidest, was erscheint, nicht ein Algorithmus."
},
"neverMiss": {
"title": "Verpasse keinen Upload",
"body": "Jedes Video jedes Kanals, dem du folgst, landet in einem Feed. Shorts und Livestreams sind standardmäßig ausgeblendet — so sind es nur die Videos, für die du gekommen bist."
},
"playlists": {
"title": "Playlists, die in beide Richtungen synchronisieren",
"body": "Erstelle Playlists lokal und halte sie mit YouTube synchron — Änderungen fließen in beide Richtungen."
},
"player": {
"title": "Schau in der App, mach da weiter, wo du aufgehört hast",
"body": "Ein In-App-Player setzt jedes Video dort fort, wo du gestoppt hast — kein Empfehlungs-Strudel, der dich ablenkt."
},
"channels": {
"title": "Eine echte Kanal-Verwaltung",
"body": "Priorisiere die Kanäle, die dir wichtig sind, tagge sie nach deiner Art und filtere den Feed nach deinen eigenen Tags."
},
"private": {
"title": "Selbst gehostet, privat, mehrsprachig",
"body": "Betreibe es selbst — deine Daten bleiben deine. Mehrbenutzerfähig, mit der Oberfläche auf Englisch, Ungarisch und Deutsch."
}
},
"auth": {
"signinTitle": "Anmelden",
"createTitle": "Konto erstellen",
"forgotTitle": "Passwort zurücksetzen",
"resetTitle": "Neues Passwort festlegen",
"email": "E-Mail",
"password": "Passwort",
"newPassword": "Neues Passwort (min. {{min}} Zeichen)",
"invalidEmail": "Gib eine gültige E-Mail-Adresse ein.",
"weakPassword": "Das Passwort muss mindestens {{min}} Zeichen lang sein.",
"genericError": "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
"working": "Einen Moment…",
"signinButton": "Anmelden",
"createButton": "Konto erstellen",
"forgotButton": "Reset-Link senden",
"resetButton": "Passwort festlegen",
"createLink": "Konto erstellen",
"forgotLink": "Passwort vergessen?",
"backToSignin": "Zurück zur Anmeldung",
"or": "oder",
"google": "Mit Google fortfahren",
"tryDemo": "Demo ausprobieren",
"demoHint": "Gib eine E-Mail ein, die für das Demo-Konto freigeschaltet ist.",
"demoEmail": "Demo-E-Mail",
"demoEnter": "Eintreten",
"demoDenied": "Diese E-Mail ist nicht für die Demo freigeschaltet. Bitte den Admin, sie hinzuzufügen.",
"registerDone": "Fast geschafft — prüfe deine E-Mails auf den Bestätigungslink. Nach der Bestätigung gibt ein Admin dein Konto frei, bevor du dich anmelden kannst.",
"forgotDone": "Falls zu dieser E-Mail ein Konto gehört, haben wir einen Reset-Link gesendet. Prüfe dein Postfach.",
"resetDone": "Dein Passwort wurde festgelegt — du kannst dich jetzt anmelden.",
"verifyOk": "E-Mail bestätigt. Sobald ein Admin dein Konto freigibt, kannst du dich anmelden.",
"verifyInvalid": "Dieser Bestätigungslink ist ungültig oder abgelaufen.",
"accessRequested": "Danke — wir haben deine Anfrage erfasst. Ein Admin wird sie prüfen.",
"accessDenied": "Dieses Konto ist für diese Instanz noch nicht freigegeben — registriere dich unten oder bitte den Admin um Zugang."
}
}

View file

@ -0,0 +1,73 @@
{
"hero": {
"title": "Your YouTube subscriptions, the way a feed should work.",
"subtitle": "Siftlode pulls every upload from the channels you follow into one clean, filterable feed — no algorithm deciding what you see, and no Shorts or live noise unless you want it.",
"trust": "Self-hosted and private. Sign in with email, or continue with Google."
},
"preview": {
"feed": "The feed — filter by channel, language, topic, length and date.",
"channels": "Channel manager",
"playlists": "Playlists"
},
"features": {
"heading": "Why Siftlode",
"readable": {
"title": "Your subscriptions, actually readable",
"body": "Sort and filter by channel, language, topic, length or date — and hide channels without unsubscribing. You decide what surfaces, not an algorithm."
},
"neverMiss": {
"title": "Never miss an upload",
"body": "Every video from every channel you follow lands in one feed. Shorts and live streams are tucked away by default, so it's just the videos you came for."
},
"playlists": {
"title": "Playlists that sync both ways",
"body": "Build playlists locally and keep them in sync with YouTube — changes flow in both directions."
},
"player": {
"title": "Watch in-app, pick up where you left off",
"body": "An in-app player resumes each video where you stopped — no recommendation rabbit-hole pulling you off course."
},
"channels": {
"title": "A real channel manager",
"body": "Prioritise the channels you care about, tag them your way, and filter the feed by your own tags."
},
"private": {
"title": "Self-hosted, private, multilingual",
"body": "Run it yourself — your data stays yours. Multi-user, with the interface in English, Hungarian and German."
}
},
"auth": {
"signinTitle": "Sign in",
"createTitle": "Create your account",
"forgotTitle": "Reset your password",
"resetTitle": "Set a new password",
"email": "Email",
"password": "Password",
"newPassword": "New password (min {{min}} characters)",
"invalidEmail": "Enter a valid email address.",
"weakPassword": "Password must be at least {{min}} characters.",
"genericError": "Something went wrong. Please try again.",
"working": "Please wait…",
"signinButton": "Sign in",
"createButton": "Create account",
"forgotButton": "Send reset link",
"resetButton": "Set password",
"createLink": "Create an account",
"forgotLink": "Forgot password?",
"backToSignin": "Back to sign in",
"or": "or",
"google": "Continue with Google",
"tryDemo": "Try the demo",
"demoHint": "Enter an email that's been enabled for the demo account.",
"demoEmail": "Demo email",
"demoEnter": "Enter",
"demoDenied": "That email isn't enabled for the demo. Ask the admin to add it.",
"registerDone": "Almost there — check your email for a verification link. After you confirm it, an admin approves your account before you can sign in.",
"forgotDone": "If that email has an account, we've sent a reset link. Check your inbox.",
"resetDone": "Your password has been set — you can sign in now.",
"verifyOk": "Email confirmed. Once an admin approves your account, you can sign in.",
"verifyInvalid": "That verification link is invalid or has expired.",
"accessRequested": "Thanks — we recorded your request. An admin will review it.",
"accessDenied": "That account isn't approved for this instance yet — register below or ask the admin for access."
}
}

View file

@ -0,0 +1,73 @@
{
"hero": {
"title": "A YouTube-feliratkozásaid úgy, ahogy egy hírfolyamnak működnie kéne.",
"subtitle": "A Siftlode minden feltöltést egyetlen tiszta, szűrhető hírfolyamba gyűjt a követett csatornáidról — nincs algoritmus, ami eldönti, mit látsz, és nincs Shorts- vagy élő-zaj, hacsak nem kéred.",
"trust": "Self-hosted és privát. Lépj be e-maillel, vagy folytasd Google-fiókkal."
},
"preview": {
"feed": "A hírfolyam — szűrés csatorna, nyelv, téma, hossz és dátum szerint.",
"channels": "Csatorna-kezelő",
"playlists": "Lejátszási listák"
},
"features": {
"heading": "Miért a Siftlode",
"readable": {
"title": "A feliratkozásaid végre olvashatóan",
"body": "Rendezz és szűrj csatorna, nyelv, téma, hossz vagy dátum szerint — és rejts el csatornákat leiratkozás nélkül. Te döntöd el, mi kerül elő, nem egy algoritmus."
},
"neverMiss": {
"title": "Egy feltöltés se vesszen el",
"body": "Minden videó minden követett csatornádról egyetlen hírfolyamba kerül. A Shorts és az élő adások alapból félrerakva — így tényleg csak azt látod, amiért jöttél."
},
"playlists": {
"title": "Kétirányban szinkronizált lejátszási listák",
"body": "Építs helyi lejátszási listákat, és tartsd őket szinkronban a YouTube-bal — a változások mindkét irányba áramlanak."
},
"player": {
"title": "Nézd appon belül, onnan folytatva, ahol abbahagytad",
"body": "Az appon belüli lejátszó ott folytatja a videót, ahol megálltál — nincs ajánló-örvény, ami eltérítene."
},
"channels": {
"title": "Igazi csatorna-kezelő",
"body": "Priorizáld a számodra fontos csatornákat, címkézd a saját módodon, és szűrd a hírfolyamot a saját címkéid szerint."
},
"private": {
"title": "Self-hosted, privát, többnyelvű",
"body": "Futtasd magad — az adataid a tieid maradnak. Többfelhasználós, a felület angolul, magyarul és németül."
}
},
"auth": {
"signinTitle": "Belépés",
"createTitle": "Fiók létrehozása",
"forgotTitle": "Jelszó visszaállítása",
"resetTitle": "Új jelszó beállítása",
"email": "E-mail",
"password": "Jelszó",
"newPassword": "Új jelszó (min. {{min}} karakter)",
"invalidEmail": "Adj meg egy érvényes e-mail-címet.",
"weakPassword": "A jelszónak legalább {{min}} karakteresnek kell lennie.",
"genericError": "Valami hiba történt. Próbáld újra.",
"working": "Egy pillanat…",
"signinButton": "Belépés",
"createButton": "Fiók létrehozása",
"forgotButton": "Visszaállító link küldése",
"resetButton": "Jelszó beállítása",
"createLink": "Hozz létre egy fiókot",
"forgotLink": "Elfelejtetted a jelszót?",
"backToSignin": "Vissza a belépéshez",
"or": "vagy",
"google": "Folytatás Google-lel",
"tryDemo": "Demó kipróbálása",
"demoHint": "Adj meg egy e-mailt, amely engedélyezve van a demó fiókhoz.",
"demoEmail": "Demó e-mail",
"demoEnter": "Belépés",
"demoDenied": "Ez az e-mail nincs engedélyezve a demóhoz. Kérd az admint, hogy adja hozzá.",
"registerDone": "Majdnem kész — nézd meg a postafiókod a megerősítő linkért. Miután megerősítetted, egy admin jóváhagyja a fiókodat, mielőtt beléphetnél.",
"forgotDone": "Ha ehhez az e-mailhez tartozik fiók, elküldtük a visszaállító linket. Nézd meg a postafiókod.",
"resetDone": "A jelszavad be van állítva — most már beléphetsz.",
"verifyOk": "E-mail megerősítve. Amint egy admin jóváhagyja a fiókodat, beléphetsz.",
"verifyInvalid": "Ez a megerősítő link érvénytelen vagy lejárt.",
"accessRequested": "Köszönjük — rögzítettük a kérésed. Egy admin felülvizsgálja.",
"accessDenied": "Ez a fiók még nincs jóváhagyva ehhez a példányhoz — regisztrálj lent, vagy kérj hozzáférést az admintól."
}
}