Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Vylosuj si, koho obdaruješ. Dárek musí začínat na stejné písmeno.
Translation pending
LifestyleTypeScript · CSSGitHub @lparoulekOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Vánoční losování dárků. Každý si na jedné adrese klikne na své jméno, jednou zalosuje a dozví se jednoho člověka, kterého obdaruje — a nic víc. Dárek musí začínat na stejné písmeno jako jméno obdarovaného.
Stack: Next.js 16 (App Router) · React 19 · TypeScript · Tailwind v4 · Drizzle ORM + Postgres (Supabase) · Vercel
/admin seznam lidí — jméno i příjmení, protože
v losu se zobrazí přesně to, co zadá.
Pár nebo domácnost napíše na jeden řádek a jména oddělí „+“
(Jan Novák + Jana Nováková) — navzájem se nevylosují.Název události, datum a cena dárku jsou pohromadě v konstantách v
lib/game/countdown.ts — na další rok se mění
jen tam.
Kdo chce, může místo toho použít osobní odkaz („Jan Novák“ → /jannovak).
Je odvozený ze jména, takže ho administrace nevypisuje — kdo ho potřebuje,
složí si ho sám (seznam i s odkazy ukáže npm run stav). Na přesný tvar si vzpomínat nemusí —
/Jan-Novák, /JanNovak i /jan_novak skončí přesměrováním na /jannovak.
Odkaz zůstává platný, takže se k losu dá vrátit kdykoli a odkudkoli.
Každý daruje i dostane právě jednou, nikdo nedaruje sám sobě ani partnerovi či nikomu z vlastní domácnosti a losování nikdy neuvázne — ani když všichni zmáčknou Losovat! ve stejný okamžik. Losuje se v transakci pod advisory lockem, takže dva lidé nemohou dostat téhož obdarovaného, a kdyby logika selhala, odmítne to databáze.
Nikdo se nedozví, z kolika lidí losoval ani jak dopadli ostatní — páry se nezobrazují ani v administraci. Animace je pro všechny stejně dlouhá, i pro posledního, kterému už zbývá jediná možnost.
Přeověřit to jde kdykoli: npm run kontrola -- --force. Podrobnosti a pravidla
pro úpravy jsou v AGENTS.md.
| Příkaz | Co dělá |
|---|---|
npm run dev | vývojový server na http://localhost:3000 |
npm run build / npm start | produkční build / jeho spuštění |
npm test | testy losovací logiky (Vitest) |
npm run typecheck / npm run lint | tsc --noEmit / ESLint |
npm run db:push | vytvoří tabulky podle lib/db/schema.ts |
npm run seed | naplní testovací jména (scripts/seed.ts) |
npm run stav | vypíše jména, odkazy a kolik lidí už losovalo |
npm run kontrola -- --force | prověří koncovku a souběh proti databázi (destruktivní) |
# 1. Databáze — buď Supabase, nebo Postgres v Dockeru:
docker run -d --name pipi-tree-pg \
-e POSTGRES_PASSWORD=pipi -e POSTGRES_DB=pipitree \
-p 55432:5432 postgres:16-alpine
# 2. Konfigurace — doplň DATABASE_URL a ADMIN_PASSWORD
cp .env.local.example .env.local
# 3. Tabulky, testovací data, start
npm install
npm run db:push
npm run seed
npm run dev
Administrace je na http://localhost:3000/admin (uživatel libovolný, heslo
ADMIN_PASSWORD). Až databázi nebudeš potřebovat: docker rm -f pipi-tree-pg.
Všechno v Postgresu, v prohlížeči nic — žádné localStorage ani cookies. Los tak nezmizí smazáním dat prohlížeče; kdo má odkaz, dostane ho ze serveru.
participants — seznam lidí a jejich odkazy (name, slug, …)draws — vylosované páry. Pravidla hry vynucuje i databáze, ne jen kód:
giver_id je primární klíč (daruje se jednou), receiver_id má unique index
(dostane se jednou), omezení draws_not_self zakáže darovat sám sobě
a draws_not_same_group partnerovi či nikomu z vlastní domácnosti.Schéma je v lib/db/schema.ts. Lokálně běží Postgres
v Dockeru na portu 55432, v produkci Supabase přes DATABASE_URL.
DATABASE_URL — Supabase session pooler, port 5432
(Supabase → Connect → Session pooler)ADMIN_PASSWORD — heslo do /adminmain = produkční deploy. npm run db:push se pouští z lokálu
(DIRECT_URL je stejná adresa a Vercel ji nepotřebuje).Po deployi musí GET /api/health vrátit {"ok":true}.
Ne transaction pooler (port
6543) — postgres.js na něm při souběžných dotazech zamrzá. Aplikace ho proto odmítne a health check vrátí"kod":"TRANSACTION_POOLER". Ani přímá adresadb.…supabase.conejde: je jen přes IPv6 a Vercel se k ní nepřipojí. Podrobnosti vlib/db/client.ts.
Aplikace nemá přihlašování: kdo klikne na cizí jméno (nebo uhádne cizí odkaz —
je odvozený ze jména, takže /petrsvoboda je snadné), dostane se k cizímu
losu. Vědomá volba ve prospěch jednoduchosti; hra je pro jednu domácnost, kde
se lidi znají. Proti překliknutí je aspoň potvrzovací krok.
Kdyby to nestačilo, přidej v lib/game/slug.ts ke slugu
náhodnou příponu a rozesílej jen osobní odkazy — zbytek aplikace se měnit
nemusí.
Co hra nedovolí ani tak: zjistit, kolik lidí ještě zbývá, přečíst si los někoho, kdo už losoval, ani losovat dvakrát.
app/
page.tsx odpočet do oslavy + výběr jména ze seznamu
[slug]/page.tsx osobní stránka: zalosovat / připomenout si los
[slug]/loading.tsx okamžitá odezva, než se stránka načte
actions.ts server actions: losování, admin
admin/page.tsx seznam lidí, stav losování, kontrola losů, reset
api/health/route.ts health check
not-found.tsx česká 404
globals.css designové tokeny (@theme), tlačítka, animace
components/
VyberJmena.tsx výběr jména ze seznamu + potvrzení proti překliknutí
PersonalDraw.tsx hra na klientovi — losovat, válec, odhalení
DrawReel.tsx výherní válec se jmény
Backdrop.tsx fotka na pozadí, ztmavení, sněžení
CandyButton.tsx / Confetti.tsx / Snow.tsx
lib/
game/draw.ts čistá logika losování (derangement + dokončitelnost)
game/letters.ts první písmeno jména česky (háčky, „Ch“, Á → A)
game/groups.ts řádky z administrace na skupiny (páry, domácnosti)
game/audit.ts zpětná kontrola losů — jen ano/ne, žádná jména
game/slug.ts osobní odkaz ze jména + tolerance k zápisu
game/countdown.ts fakta o události (název, datum, cena) + odpočet
game/random.ts kryptografická náhoda
db/schema.ts participants, draws
db/queries/game.ts serverová pravidla hry (transakce + advisory lock)
admin.ts kontrola admin hesla
proxy.ts brána pro /admin
scripts/ seed.ts, stav.ts, kontrola.ts
tests/game/ testy logiky, písmen, odkazů a odpočtu