JS files were output as main.js without content hash, combined with
nginx's 30-day immutable cache. Browsers would never fetch updated code.
- Add [contenthash:8] to webpack output filenames in production
- Set index.html to no-cache so browsers always check for new bundles
- Only apply immutable cache to hashed filenames (*.abcdef01.js)
Co-Authored-By: Claude <noreply@anthropic.com>
The /purchaser/plans API returns data as a plain array, but usePlanData
destructured res.data expecting {plans, factories, plan_factories, operator_names}.
This caused the PlanOverview page to render nothing despite receiving data.
Co-Authored-By: Claude <noreply@anthropic.com>
The purchaser plans endpoint returns data as a plain array, not wrapped
in {plans:[...]}. Added Array.isArray check to handle both formats.
Co-Authored-By: Claude <noreply@anthropic.com>
When API returns {"data": null} for empty lists, accessing .plans on
null throws an exception. fetchPlans never reaches setLoading(false),
causing the dashboard to spin forever. Added optional chaining,
fallback defaults, and try-catch-finally to ensure loading stops.
Co-Authored-By: Claude <noreply@anthropic.com>
Dashboard pages hung on "加载仪表盘数据..." when auth.company was null
(e.g. admin user). Now sets loading=false immediately when no company
is present, so the page renders instead of spinning forever.
Co-Authored-By: Claude <noreply@anthropic.com>
The refresh endpoint expects {"refresh_token":"..."} in the POST body,
but the frontend was sending an empty body (EOF error). Now stores the
refresh_token from login response and sends it on refresh requests.
Co-Authored-By: Claude <noreply@anthropic.com>
Add a prominent green banner at the top of the login page to visually
verify that the GitOps CI/CD pipeline auto-deploys successfully.
Co-Authored-By: Claude <noreply@anthropic.com>
Copy .npmrc for registry mirror, set NODE_ENV=development during
npm ci to ensure webpack (devDep) is installed, use npx webpack
for build step.
Co-Authored-By: Claude <noreply@anthropic.com>
Docker Hub unreachable from k3s cluster. Switch Dockerfile to pull
node and nginx base images from Harbor registry.
Co-Authored-By: Claude <noreply@anthropic.com>
Set DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH for k8s runner
DinD sidecar communication. Add 'until docker info' wait loop to
ensure daemon is ready before build starts.
Co-Authored-By: Claude <noreply@anthropic.com>
Multi-stage Docker build: node:20-alpine + nginx:1.27-alpine.
CI builds and pushes to harbor-in-k3s.cheverjohn.me/iloom/iloom-frontend.
Co-Authored-By: Claude <noreply@anthropic.com>
WHY: migrating from Supabase BaaS to self-hosted iloom backend
(Go microservices) deployed on K3s. Supabase client and realtime
subscriptions no longer applicable.
HOW:
- add src/api/ layer (client.ts, auth.ts, purchaser.ts, textile.ts,
washing.ts, websocket.ts) targeting iloom-gateway REST endpoints
- rewrite all hooks (usePlanData, useInventoryData, useDashboardData,
useRealtime, etc.) to use new API client instead of Supabase queries
- rewrite all page/component data fetching and mutations accordingly
- delete src/supabase/client.ts, remove @supabase/supabase-js dep
- add Dockerfile (multi-stage node build + nginx) and nginx.conf
with reverse proxy to iloom-gateway for /api/ and /ws/ routes
- adjust webpack.config.js for API_URL environment variable injection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>