Commit Graph
388 Commits
Author SHA1 Message Date
openhands b1eeda8de0 feat(nitro-cleanup): make delete button visible
CI / check (push) Failing after 4m15s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
2026-09-20 16:54:41 +02:00
openhands c3ff497050 feat(referrals): add referral attribution and daily login rewards
CI / check (push) Successful in 4m25s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m54s
- Track referral attribution at registration via ?ref code with
  same-IP and duplicate-pair guards
- Add daily login rewards with streak tracking, claim flow and
  sendCurrency payout backed by RCON with DB fallback
- Add admin pages for referral settings and the daily reward schedule
- Add migration 0033 with tables, seed schedule, settings and ACL grants
- Add admin.referrals.* and admin.dailyrewards.* permission slugs
- Localize new copy in en, nl and it
2026-09-20 12:29:01 +02:00
openhands 9813dbc2a4 fix(studio): surface selected nitro cleanup actions in sticky bar
CI / check (push) Failing after 20s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
2026-09-19 23:18:57 +02:00
openhands 6c53f4680c feat(studio): run nitro scans in the background with cancel-re-attach and nightly auto-clean 2026-09-19 13:41:14 +02:00
openhands 9d571e0c29 perf(studio): stream nitro repair progress over SSE and allow cancelling
CI / check (push) Successful in 4m23s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m43s
2026-09-19 13:12:45 +02:00
openhands ba81d16f00 perf(studio): cache nitro scan, stream progress, virtualize cleanup list
CI / check (push) Successful in 4m14s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m10s
2026-09-19 13:01:59 +02:00
openhands c916e42572 perf(studio): speed up nitro scan and stop the cleanup panel freezing
CI / check (push) Successful in 4m13s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m0s
2026-09-19 11:39:19 +02:00
openhands 91e649398c feat(i18n): make admin and catalog components fully translatable
CI / check (push) Successful in 4m18s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m58s
2026-09-18 16:02:08 +02:00
openhands 03774bb411 feat(i18n): make admin and catalog components translatable
CI / check (push) Failing after 30s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
2026-09-18 14:56:36 +02:00
openhands 469f69ddd7 feat(home): two-column hero with live status panel, explore nav, featured news
CI / check (push) Successful in 4m8s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m0s
2026-09-18 13:27:08 +02:00
openhands a6e808a099 perf(landing): share one SSE socket for online counters, respect reduced motion
CI / check (push) Successful in 4m10s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m43s
Header and hero/stats counters each opened their own EventSource to the
online-count stream; a shared subscriber now opens a single socket and
multicasts to every mounted counter. The entrance count-up animation skips
its requestAnimationFrame loop when the user prefers reduced motion.
2026-09-18 12:57:52 +02:00
openhands d131124515 feat(theme): animate public background with aurora and particles, polish landing pages
Add background_effect (aurora/particles), background_overlay tint and
opacity to the theme manager, rendered site-wide by ThemeVars on every
public page. Polish the home and register pages (hero mascot, live stat
pulse, date pills, photo strip, CTA band, theme-aware register intro,
i18n for home/register section).
2026-09-18 12:44:39 +02:00
openhands 5923b736fa refactor(studio): extract helper components from OrganizeImportsDialog
CI / check (push) Successful in 4m27s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m5s
Extract FurniThumb, LayoutPreview, and GroupItemList into a dedicated
mall-helpers module alongside OrganizeImportsDialog. Preserves all
virtualization, drag-and-drop, and preview behavior while reducing
the main dialog component size.
2026-09-17 21:35:16 +02:00
openhands 3862649369 refactor(catalog): extract AddItemFormFields from CatalogItemsTable
Split the Add Item dialog form fields into its own module,
reducing the main table component size while preserving all
form fields, validation and handler logic.
2026-09-17 21:21:40 +02:00
openhands 5b4b275b2a feat(housekeeping): add per-hotel theme manager with import/export and background
CI / check (push) Failing after 20s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
Theme Manager under /admin-next/hotel/theme-manager lets the owner save, apply, rename, delete, import, and export custom themes, plus set a custom site background by URL or upload. Themes are stored in WebsiteSetting/custom_themes JSON so they survive CMS updates.
2026-09-16 19:45:57 +02:00
openhands 3d7278e96d perf(studio): header-only nitro validation for fake/broken scan
CI / check (push) Successful in 4m23s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m23s
The cleanup scan used to read every .nitro bundle in full and decompress
the large PNG texture just to confirm the file is structurally valid. On
directories with hundreds of thousands of bundles this took minutes, the
reverse proxy cut the request at its 30s timeoutable with an HTML 504, and
the panel then crashed with "Unexpected token '<'".

Validate bundles with a cheap header-only read (a few KB, no decompression)
that mirrors parseNitroBundle's byte layout; only files whose header looks
suspicious get the expensive full parse. Robust against downloads that
landed as an HTML error page, truncated or zero-filled files. The scan
drops from minutes to seconds on large nitro directories.

Also guard the panel against non-JSON (proxy error page / HTML) responses
so it reports a clear error message instead of a JSON parse failure.
2026-09-16 15:50:04 +02:00
openhands 438277a17a feat(studio): expand nitro cleanup with repair, auto-clean, and orphaned assets
CI / check (push) Successful in 4m15s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m59s
Scan distinguishes fake, broken, and orphaned SWF/icon assets with age
metadata, deletes per asset kind, re-downloads broken nitro bundles from
configured sources, auto-cleans old fake leftovers, and exports a JSON
manifest. Adds rebuild and auto-clean API endpoints with audit coverage
and a housekeeping preview route under the hotel domain.

Verified: full vitest suite (2213 tests), typecheck, and biome all pass.
2026-09-15 21:59:21 +02:00
openhands 694f87d98c feat(studio): add nitro cleanup tool for fake and broken bundles
CI / check (push) Failing after 1m22s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
2026-09-15 20:54:10 +02:00
openhands ce93b92a81 fix(avatar): render onError avatars only in client components
CI / check (push) Successful in 4m33s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m51s
AvatarImage is used on server pages via UserAvatarThumbnail but lacked
'use client', so the onError handler on its <img> could not cross the
RSC boundary. /login rendered the error page, hanging the news e2e
journey until the 240s test timeout.

- Mark AvatarImage as a client component like ProfileImage
- Replace inline <img onError> on mod/users server pages with the
  client AvatarImage component
2026-09-15 11:43:47 +02:00
openhands 0f01ebf48b Organize imports: persist undo across sessions, translate UI to 23 languages
CI / check (push) Failing after 5m7s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-14 19:07:56 +02:00
openhands 3a4089a5fa Organize imports: drag & drop, virtualization, dupes, undo, days select, localStorage
CI / check (push) Failing after 5m4s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
- Native HTML5 drag & drop between categories with drop-target highlight
- Virtualized item lists via @tanstack/react-virtual (fixed 34px rows)
- Auto-batching of large groups (500 items / 50 groups per run)
- Duplicate detection against the destination page with badge + summary
- Per-category layout preview grid
- Undo history for item moves (single + batch, tracks source groups)
- Days-range selector to load older imports (30/60/90/180)
- LocalStorage persistence of user settings (mode, destination, price, days)
- Added translation keys across all 25 locales
2026-09-14 18:40:50 +02:00
openhands 644d53ca16 Rebuild organize imports: move furniture between categories, 500-item cap
CI / check (push) Failing after 5m12s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-14 18:24:48 +02:00
openhands 67430e7e9d Polish catalog studio: undo delete, save status pill, faster totals 2026-09-14 18:24:47 +02:00
openhands 6ea0ec7d99 Resolve remaining biome lint and formatting errors
CI / check (push) Failing after 1m23s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-14 17:43:54 +02:00
openhands 1df1ffc3e9 Make avatar imager resilient with upstream fallback everywhere
CI / check (push) Failing after 24s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-14 17:35:36 +02:00
openhands 1bbd809b43 Replace standalone catalog editor with the unified Visual Catalog studio
CI / check (push) Failing after 26s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
Make /admin/catalog a full-screen catalog studio that replaces the old
listing plus separate [id]/builder-club detail pages:

- Embed CatalogManagerWorkspace on /admin/catalog with a Normal/Builder
  Club toggle, Catalog Sync status, packages (normal), Organize imports
  and a diagnostics link to /admin/studio/maintenance.
- Manage BC items directly in the studio Items tab (new BcItemsEditor,
  CRUD via existing bc actions; /api/admin/catalog/items now serves BC).
- Inline editor: add pageTextTeaser field for both catalogs and remove
  the legacy full-editor links.
- Remove the 'Open full editor' context action from the tree.
- Move catalog-items-table (dir + barrel) and catalog-translate-tab out
  of the app route into src/components/admin/catalog and update all
  importers.
- Keep /admin/catalog/[id], builder-club/[id] and /admin/catalog/maintenance
  as redirects into the new studio; consolidate maintenance panels into
  /admin/studio/maintenance and point the nav item there.
- Delete the old listing/table/tabs/forms and the standalone bc-manager.
2026-09-14 17:20:52 +02:00
openhands 1a9e1e791a Improve catalog studio UX and aggressive docker cleanup
CI / check (push) Failing after 1m25s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
Catalog Studio:
- Cross-parent drag & drop now uses optimistic updates with rollback
  on failure (no more full tree reload / visible delay)
- Subpage creation adds the node optimistically then refreshes parent
  only (was full tree reload)
- Single page deletion refreshes only the affected parent (was full
  tree reload)
- Root page creation replaces native prompt() with an inline input
  in the root tab bar
- Escape key no longer closes the dialog when an input field is focused
- TreeNodeUpdate type now supports parentId and orderNum for
  optimistic structural changes

Docker:
- docker-prune.sh default mode now aggressively cleans all unreferenced
  build cache, images >1h old, and stopped containers >1h old
  (was 72h/7d/24h which let cache grow past 80% on every push)
2026-09-14 16:52:04 +02:00
Simo dd7613850e perf(studio): load import organization tools on demand
CI / check (push) Failing after 29s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-13 19:32:46 +02:00
Simo 8abfe352ef fix(security): authorize site uploads and harden tokens, media and request identity
CI / check (push) Successful in 3m15s
CI / deploy (push) Successful in 1m19s
CI / publish-container (push) Successful in 48s
2026-09-13 19:24:43 +02:00
Simo 52f6d1491f fix(news): persist publication requests and retry cache delivery
CI / check (push) Successful in 3m12s
CI / deploy (push) Successful in 1m13s
CI / publish-container (push) Successful in 42s
2026-09-13 18:33:45 +02:00
Simo c977fe95ba fix(studio): recover uncertain imports with persistent request identities
CI / check (push) Successful in 3m12s
CI / deploy (push) Successful in 19s
CI / publish-container (push) Successful in 1m12s
2026-09-13 18:33:06 +02:00
Simo afea80708c perf(studio): defer import history and Nitro scale tools until opened
CI / check (push) Successful in 3m7s
CI / deploy (push) Successful in 1m2s
CI / publish-container (push) Successful in 1m8s
2026-09-13 18:29:24 +02:00
Simo 1eee6661f9 feat(notifications): add account-scoped inbox and persistent preferences
CI / check (push) Failing after 1m18s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-13 17:59:22 +02:00
Simo a4266f297c fix(ci): resolve inherited formatter and navigation effect diagnostics
CI / check (push) Successful in 3m12s
CI / deploy (push) Successful in 19s
CI / publish-container (push) Successful in 2m47s
2026-09-13 17:55:01 +02:00
openhands 966a925614 feat(ui): add global progress bar for navigation feedback
CI / check (push) Failing after 25s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-13 14:44:46 +02:00
openhands ffcd4232d6 feat(import): durable batch checkpoint and transient auto-retry
CI / check (push) Successful in 2m24s
CI / deploy (push) Successful in 1m32s
CI / publish-container (push) Successful in 47s
Mirror interactive batch runs into the import-job store so interrupted imports (restart, time-out, disconnect) can be resumed from Import History. Items are checkpointed as they settle (coalesced, serialized saves) and the mirror starts 'running' so the boot-time worker marks it 'interrupted' instead of double-importing; done items are never re-imported. Add bounded backoff retry for transient download/connection failures before marking an item failed, and point the client's time-out/network toasts at Import History.
2026-09-13 12:50:17 +02:00
openhands af1a06b0a3 feat(studio): polish search highlight, zebra rows, and transitions
CI / check (push) Successful in 2m24s
CI / deploy (push) Successful in 1m22s
CI / publish-container (push) Successful in 45s
Highlight the active search term in names/classnames (grid + table), add zebra striping and a left accent bar on selected table rows, fade the results list when switching grid/table or on first load, and swap the broken-icon fallback for a cleaner placeholder.
2026-09-13 12:36:20 +02:00
openhands 2a708b01b1 perf(import): adjustable concurrency and skip redundant SWF downloads
CI / check (push) Successful in 2m22s
CI / deploy (push) Successful in 1m12s
CI / publish-container (push) Successful in 44s
Raise batch concurrency (furni 3->12, clone 10->12) with a Speed control next to Translate. Skip the SWF download when a .nitro bundle already exists on disk (color variants share the base nitro), and stop flagging that as a failed download.
2026-09-13 12:14:52 +02:00
openhands 641b6b8cb8 feat(studio): bulk select all results, persist view prefs, back-to-top
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m18s
CI / publish-container (push) Successful in 50s
2026-09-13 12:04:11 +02:00
openhands b92f897ba2 perf(studio): virtualize the furniture table and throttle batch progress
CI / check (push) Successful in 2m33s
CI / deploy (push) Successful in 1m28s
CI / publish-container (push) Successful in 57s
- Render the table view through a virtualizer too, using a shared grid
  template so the sticky header and rows keep perfect column alignment
- Keep semantic table/row/cell elements while virtualizing
- Cap the batch item-details list to the latest 60 rows (newest first)
- Coalesce per-item progress events server-side (120ms throttle) in both
  the exact-import and clone SSE batch runners
2026-09-13 11:53:07 +02:00
openhands d02aaa0d87 perf(studio): cache furni imports and virtualize the furniture grid
CI / check (push) Failing after 22s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
- Add TTL-based caching for local index lookup, furnidata classnames,
  catalog id set, nitro file presence and import stats
- Invalidate caches after furnace single/batch/clone imports
- Rewrite batch progress with elapsed time, rate and verification chips
- Virtualize the grid with @tanstack/react-virtual and replace the
  Load more button with infinite scroll via an IntersectionObserver
2026-09-13 11:40:55 +02:00
openhands 0af8d8a398 fix(lint): resolve biome formatting and unused variables across codebase
CI / check (push) Failing after 1m5s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-12 19:45:29 +02:00
openhands 8707c0d8fe feat(studio): improve organize imports UX with validation limits and translations
CI / check (push) Failing after 30s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-12 19:24:55 +02:00
openhands 31a89c505d fix(studio): count pages, not items, in organize-imports button
CI / check (push) Successful in 2m25s
CI / deploy (push) Successful in 1m14s
CI / publish-container (push) Successful in 51s
The "Create" CTA used totalSelected (the sum of furni items across
approved groups) as its plural count, so with many imported items it
claimed to create thousands of pages. One approved group creates exactly
one page, so the label now counts approved groups instead.
2026-09-12 18:08:10 +02:00
openhands 8a1b83b965 feat(site): make drifting clouds clearly visible and moving
CI / check (push) Successful in 2m35s
CI / deploy (push) Successful in 1m22s
CI / publish-container (push) Successful in 50s
The first cloud pass was to subtle: only five, up to 190s per crossing,
and they froze off-screen under prefers-reduced-motion. Rework:

- Eight clouds across the top 60% of the viewport with visible drift
  (28s–66s loops, staggered by negative delays so they are always mid
  scene on load).
- Higher opacity/steeper size contrast in light mode; dark mode dims
  them slightly.
- Reduced motion now freezes a static, evenly-spread cloud field across
  the width instead of pushing the clouds off-screen.
2026-09-12 17:51:37 +02:00
openhands e5e17d75ae perf(site): inline small classic icons and favicon as base64
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m34s
CI / publish-container (push) Successful in 50s
- New src/lib/site-icons.ts: base64 data URIs for the 13 tiny classic
  icons actually referenced in markup (100–2000 bytes), replacing extra
  requests with inline payloads. home.png, dynamic flags and currency
  sets stay on the filesystem.
- Default favicon is now served server-side as a base64 SVG data URI
  (memoized), while a DB-configured custom favicon still takes priority.
- Icons render through <Image unoptimized>, so data URIs pass through
  untouched on all affected pages (home, login, register, settings,
  navigation, auth top bar, client loading).
2026-09-12 17:28:01 +02:00
openhands 97012a78f6 feat(site): drifting cloud puffs across the public background
CI / check (push) Successful in 2m40s
CI / deploy (push) Successful in 2m13s
CI / publish-container (push) Successful in 2m10s
Add a fixed, decorative layer of soft clouds that slowly float across
the Habbo sky behind the content:
- Five clouds at staggered sizes, heights, opacities and loop timings
  (60s–190s) so the drift feels organic.
- Dimmed further in dark mode; frozen by prefers-reduced-motion.
- Pure decoration: aria-hidden, pointer-events: none, no color
  utilities in markup (cloud shapes live in globals.css).
2026-09-12 17:12:55 +02:00
openhands efd3b00075 feat(site): smoother motion across the landing pages
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m19s
CI / publish-container (push) Successful in 1m4s
- Slow Ken Burns drift on the hero artwork for cinematic depth.
- Gentle breathing pulse on the brand glows behind Frank and the hero.
- Silkier reveal easing (cubic-bezier .22/1/.36/1, 0.55s) site-wide.
- Eased, longer hover transitions on the hero CTAs.
- Smooth page scrolling, all guarded by prefers-reduced-motion.
2026-09-12 16:51:48 +02:00
openhands 3265cf1fad feat(site): consistent card radius and remove duplicate login CTAs
CI / check (push) Successful in 2m32s
CI / deploy (push) Successful in 1m17s
CI / publish-container (push) Successful in 53s
Professional tidy-up of the landing experience:
- SurfaceCard: unified rounded-xl radius for a crisper, consistent look.
- Hero: matches the new card radius and gains a dual-direction title
  shadow so the headline stays readable over the header artwork.
- Login/register: drop the duplicated "no account / have an account"
  paragraphs — the forms already ship an inline footer, so one clear CTA
  cluster remains and the side column is cleaner.
2026-09-12 16:35:28 +02:00
openhands 29b9a4b0dc feat(site): professional card system and tidy landing layout
CI / check (push) Successful in 2m26s
CI / deploy (push) Successful in 1m26s
CI / publish-container (push) Successful in 1m1s
Refine the public UI for a cleaner, more professional and scannable
landing experience without leaving the classic Habbo style:

- SurfaceCard: softer layered shadow, gradient accent hairline on the top
  edge and a bolder header title across all public cards.
- Home: gradient hotel-name in the hero headline, shine effect on the
  primary CTA, hairline on the top bar.
- Login/register: consistent avatar tiles with rounded corners, subtle
  borders and a gentle hover lift; uniform username sizing.
- Add reusable theme-aware .card-hairline and .gradient-text utilities.
2026-09-12 16:29:55 +02:00