Migrated backoffice, hackathon, dimentorin, gacha, qrcampaign, and
infra from custom react-router file-based routing to TanStack Router
file-based routing following the tanstack-frontend-best-practice
convention.
Key changes per app:
- New routes/ directory with __root.tsx, _public.tsx, _authenticated.tsx
- Auth guards via beforeLoad (replaces old middleware.ts)
- createFileRoute pattern for all page components
- TanStackRouterVite plugin in vite.config for auto route generation
- _components/_hooks folders colocated with routes (ignored by router)
- routeTree.gen.ts auto-generated on dev/build
Convention:
- _public/* routes redirect to dashboard if authenticated
- _authenticated/* routes redirect to /auth/login if not authenticated
- $param for dynamic segments (was [param] in old convention)
- _layout suffix for pathless layout routes
Removed:
- Old src/app/ directories from all apps
- Old src/middleware.ts files
- Custom convertPagesToRoute utility (no longer needed)
- react-router dependency usage (kept in package.json for shared libs)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The file-based router was converting (group) segments to 'group?'
optional parameters, which broke all SPA routes (404 on every page).
Now (group) segments map to empty path '' which creates pathless
layout wrapper routes in react-router, matching Next.js behavior.
e.g. (public)/auth/login/page.tsx → route path '/auth/login'
(protected)/dashboard/page.tsx → route path '/dashboard'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The <link rel="stylesheet" href="/src/..."> tags reference source
paths that only exist in dev mode. In production builds, Vite injects
CSS through the JS bundle. These broken links caused 404 errors and
unstyled pages in production.
Affected: backoffice, dimentorin, gacha, hackathon, infra
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Stripped dark: classes from Input, Textarea, Button, and InputField
components. These were causing black/dark backgrounds in modals and
forms across all apps (backoffice, gacha, dimentorin, etc).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the heavy Next.js SSR app with Astro static site:
- Zero JS shipped for static pages (hero, community, CTA, footer)
- Server-side data fetching in Astro frontmatter (events, hackathon, testimonials)
- Only 4 React islands for interactive parts (mobile menu, roadmap voting, testimonials home, feature request)
- Google Fonts via <link> instead of next/font
- Nix build changed from Node.js systemd service to static nginx (mkStaticAppModule)
- npmDepsHash needs update (set to fake hash, CI will provide correct one)
Performance gains:
- No Node.js server process needed (was using ~10MB RAM)
- No Next.js runtime JS (~200KB+ saved)
- No framer-motion bundle (~130KB saved)
- Static HTML served directly by nginx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Performance improvements:
- Replaced framer-motion animations with CSS @keyframes in hero,
testimonial, and community sections (saves ~130KB bundle)
- Switched from local Poppins/BaiJamjuree font files (750KB) to
next/font/google with auto-subsetting
- Deleted 10 local .ttf font files
- Community section is now a server component (no 'use client')
- Removed scroll parallax effect from hero (was causing repaints)
- Hero image marked as priority for LCP optimization
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Landing page changes:
- Removed entire (auth) directory — landing doesn't need login/signup
- Removed auth buttons (Masuk/Daftar) from header navigation
- Hackathon page now fetches teams + winners from real API
- Roadmap page now fetches from /v1/landing/cms/roadmap API with
real-time voting via POST /roadmap/vote/{id}
- Deleted dummy JSON files: events.json, testimonials.json, hackathons.json
- Kept static config: hero-content, hero-stats, navigations, socials
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All login pages now use react-hook-form with zod resolver for
real-time validation:
- Email validated as proper email format on each keystroke
- Password required validation
- Red border + error message shown inline below invalid fields
- Submit button disabled until all fields are valid
- Input type="text" instead of type="email" to avoid browser tooltip
Also fixed:
- Gacha API trailing slash on /items/ and /credits/ causing 404s
Apps updated: hackathon, dimentorin, backoffice, qrcampaign, gacha
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server-side fetch fails during Nix build due to SSL cert issues in
the sandbox. Converted to client components with useEffect+fetch
so data loads at runtime instead of build time.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Updated default HydrateFallback in file-based-routing to show a
centered blue spinner instead of bare "Loading..." text
- Added inline spinner to all index.html root divs so users see a
spinner immediately while JS bundles load (instead of blank white)
- Affects: dimentorin, hackathon, backoffice, gacha, qrcampaign, infra
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Stripped all dark: classes from hackathon, dimentorin, backoffice,
and qrcampaign login pages — light mode only
- Rewrote gacha login modal to match the unified clean design:
clean typography, native inputs with eye toggle, proper spacing,
removed old IMPHNEN logo header and Indonesian text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard (/dashboard):
- Welcome header with user name
- Stats cards: upcoming sessions, completed, role (mentor/mentee)
- Mentor registration CTA for non-mentors
- Upcoming sessions list with status badges
- Profile card with avatar and gradient header
Settings (/dashboard/settings):
- Account Details: displays user info and role
- Privacy & Security: 2FA (coming soon), change password, active sessions
- Preferences: email notifications, language, theme
- FAQ & Support: expandable FAQ accordion with contact info
Dashboard Layout:
- Top nav with Dimentorin branding
- Navigation links: Dashboard, Settings
- Auth guard redirects to login if not authenticated
- Logout button
Closes#42, #43, #54
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dimentorin: replaced anime-themed login with clean dark-mode design,
removed Google login, uses shared useLogin hook
- Backoffice: replaced custom hook login with unified design, clean
admin-only layout (no signup link)
- QR Campaign: added dark mode support to match hackathon style
All login pages now share consistent:
- Dark/light mode support
- Email + password fields with show/hide toggle
- GitHub OAuth button
- Error handling UI
- Same Tailwind class patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
VITE_API_URL was never set in the Nix build, so getBaseURL() returned
empty string causing all API calls to hit the current origin (e.g.
hackathon.imphnen.dev) instead of api.imphnen.dev. This caused 405
errors on login since the frontend server doesn't handle POST.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix API service paths to use /v1/iam/, /v1/dimentorin/, /v1/gacha/, /v1/hackathon/ prefixes
- Add roles, permissions, events, testimonials, sessions API services and hooks
- Rewrite gacha service with full CRUD + roll/claim endpoints
- Replace all mock data in backoffice pages with real API calls (accounts, roles, permissions, gacha-roll, dashboard, sessions, users-dimentorin, feedback-review, settings)
- Wire dimentorin mentoring list to useMentorList with search + pagination
- Wire dimentorin mentor detail page to useMentorById, pass real data to all sections
- Wire appointment modal to useBookSession with controlled schedule inputs
- Wire gacha app Spin Now to useExecuteGachaRoll, show credits and real items
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Server pulls pre-built packages from Cachix, no need to build
the NixOS closure in CI. Just update flake.lock and trigger
a remote rebuild.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update flake.lock in imphnen-infrastructure
- Deploy to Hetzner server using clan machines update
- Requires SERVER_SSH_KEY secret for server access
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Upgrade Nx 22.1.1 → 22.6.3 and all patch/minor dependencies
- Restructure shared libs: move business logic from utils to service
- Consolidate shadcn-ui into ui lib with atomic design pattern
- Fix container centering for landing app (Tailwind v4 compatibility)
- Fix button styling by updating @source directive in globals.css
- Fix SiCss3 → SiCss rename in react-icons 5.6
- Fix duplicate useSession export conflict
- Remove dead code, comments, and unused files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Skip unchanged apps to speed up CI. Uses nx affected to detect
which apps need rebuilding, then runs nix builds in parallel
via GitHub Actions matrix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After building and pushing to Cachix, the CI now clones
imphnen-infrastructure and updates its flake.lock to point
to the latest frontend service commit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove all Docker files, Vercel config, Verdaccio, and old CI workflow.
Standardize on nodejs_22 across devShell and nix build helpers.
Update CI to build all packages and push to Cachix on merge to develop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(qr): add empty state for campaign & user management page to handle unexcepted null error
* fix(qr): fix empty state logic in the user management page