38 Commits

Author SHA1 Message Date
Chever John
c8b42edaa7
fix: resolve infinite loading in new plan page product selector
The page called a non-existent /purchaser/products/yarn-ratios endpoint.
When that 404'd, the unhandled error prevented setLoading(false) from running,
leaving the product selector stuck on "加载中". Now extracts yarn_ratios
directly from the product list response (already included in each product object).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 23:25:16 +08:00
Chever John
b24de9ac11
fix: handle null response from records API to prevent product list crash
When products have no inventory records, the backend returns {"code":0,"data":null}.
getRecords() resolved with null, causing records.filter() to throw TypeError,
which crashed the entire fetchData() and left the product list empty.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 22:11:09 +08:00
Chever John
29451277d1
fix: use authenticated upload in ProductForm and AccountProfileCard
Both components had raw fetch to /api/v1/common/upload without the
Authorization header. Replace with commonApi.uploadFile which handles
token refresh and auth headers.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 20:39:15 +08:00
Chever John
284499745a
fix: ensure auth token is present before upload request
Add proactive token refresh when getAccessToken() returns null, plus
401 retry logic. The in-memory token can be null if it expired between
page load and upload attempt.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 20:35:08 +08:00
Chever John
1b506edfbf
feat: use authenticated upload API in ImageUploader
- Add uploadFile function to commonApi with Authorization header
- Replace raw fetch with commonApi.uploadFile in ImageUploader

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 16:27:17 +08:00
Chever John
01026a17d8
fix: align share link request fields with backend API
Frontend was sending `type` and `target_id` but backend expects
`resource_type` and `resource_id`, causing 40000 validation error.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 07:15:26 +08:00
Chever John
ee8fc85516
fix: remove bing redirect, fix modal centering across all pages
- DemoDisclaimerModal: remove bing redirect on "稍后再说", just close
- App.tsx: remove will-change:transform from AnimatedRoute which created
  a new containing block and broke fixed positioning for all modals
- OnboardingGuide: add Portal as extra safety for centering

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 03:11:25 +08:00
Chever John
124d0e8ff7
fix: use Portal to render ShareModal at document.body
AnimatedRoute's will-change:transform creates a new containing block,
which makes fixed positioning relative to that element instead of the
viewport. When the page is scrolled, the modal appears off-center.
Using createPortal to render at document.body bypasses this issue and
ensures the modal always appears centered in the viewport.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 03:02:04 +08:00
Chever John
aba6330db7
fix: eliminate blank overlay flash when opening ShareModal
Initialize hasRelationship and isCheckingRelationship based on whether
factoryId is present, so the first render frame already shows the correct
content instead of an empty backdrop overlay.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 02:58:39 +08:00
Chever John
a3e9361cab
fix: use expanded regex in nginx location for hashed assets
Replace {8} quantifier with 8 repeated character classes for
compatibility with nginx regex parsing.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 02:52:32 +08:00
Chever John
68da2c2c20
fix: ShareModal shows blank overlay when factoryId is undefined
When clicking "分享链接" for unlinked plans, factoryId is undefined.
The ShareModal's useEffect returned early without setting hasRelationship,
leaving it as null — none of the three conditional branches rendered,
showing only the backdrop overlay with no content.

Fix: when factoryId is missing, set hasRelationship=false directly to
show the share link generation UI. Also remove the factoryId guard from
generateShortLink since it only needs planId and factoryType.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 02:31:57 +08:00
Chever John
31ea850769
fix: add content hash to JS bundles and fix caching strategy
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>
2026-06-30 02:25:33 +08:00
Chever John
091fc24d90
fix: handle plans list API returning array format in usePlanData hook
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>
2026-06-30 02:13:37 +08:00
Chever John
c641831251
fix: handle plans API returning array instead of {plans:[]} object
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>
2026-06-30 02:07:18 +08:00
Chever John
69543a8aef
fix: handle null API response data to prevent infinite loading
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>
2026-06-30 02:00:04 +08:00
Chever John
6b866738be
fix: stop infinite loading spinner when user has no company
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>
2026-06-30 01:31:25 +08:00
Chever John
9ecf3c3179
fix: pass refresh_token in body when calling /auth/refresh
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>
2026-06-30 01:28:45 +08:00
Chever John
df0d490a42
Merge remote-tracking branch 'upstream/main'
# Conflicts:
#	Dockerfile
2026-06-23 09:34:08 +08:00
Chever John
f5071cb01d
Revert "feat: add GitOps CI/CD test banner to login page"
This reverts commit aff18e9adc6d50c9e508aad7bbb25920daaa6e8d.
2026-06-17 20:06:54 +08:00
Chever John
aff18e9adc
feat: add GitOps CI/CD test banner to login page
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>
2026-06-17 20:03:16 +08:00
Chever John
89106e95af
fix(ci): use host networking and custom DNS for DinD builds
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-17 10:28:17 +08:00
Chever John
a4914dd14c
fix: ensure devDependencies install for webpack build
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>
2026-06-17 10:23:29 +08:00
Chever John
095fe1b9b7
fix(ci): add retry: 2 for transient Harbor failures
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-17 10:20:11 +08:00
Chever John
6558d137d9
fix: use --legacy-peer-deps for npm ci
Resolves peer dependency conflict with @testing-library/react-hooks
and @types/react versions.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-17 10:18:45 +08:00
Chever John
5591c705de
fix: use Harbor base images for CI builds
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>
2026-06-17 10:17:38 +08:00
Chever John
792ffadfb2
fix(ci): add Docker daemon wait and TLS env vars for DinD
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>
2026-06-17 10:10:57 +08:00
Chever John
e399f0070e
feat: add Dockerfile and GitLab CI pipeline for Harbor
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>
2026-06-17 10:01:55 +08:00
Chever John
5fb22cb120
Merge pull request #1 from kihaneseifu/feat/k8s-deployment-adaptation
refactor: replace Supabase SDK with self-hosted REST API client layer
2026-06-14 15:12:02 +08:00
Chever John
b1c2c33aa2
refactor: replace Supabase SDK with self-hosted REST API client layer
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>
2026-06-14 12:38:47 +08:00
github-actions[bot]
3093ae18c2 sync: Add files via upload (A@cb7b0c57defc79e2dff2a711987b761de178c04f) 2026-06-05 03:34:05 +00:00
github-actions[bot]
d06690963c sync: Add files via upload (A@f3f0916866583911d315136c8b16f45e6a96c236) 2026-06-04 15:56:19 +00:00
github-actions[bot]
e604317c7f sync: Add files via upload (A@90dbd4d185c93e599be85a4cb190f35d45c1495f) 2026-06-04 15:09:31 +00:00
github-actions[bot]
b6e2e526d9 sync: Add files via upload
重大版本更新 (A@029ab8fcd9c4f587ce7a2394252868172d8e5d79)
2026-06-04 13:57:36 +00:00
github-actions[bot]
e713fcbf18 sync: Add files via upload (A@e5347bf93cdb38c0fdf86271231c0e884465195a) 2026-05-28 06:28:50 +00:00
github-actions[bot]
3f7377b142 sync: Add files via upload (A@87b0a27431d8596edf55a7e623f944ca2f39f234) 2026-05-28 05:54:23 +00:00
github-actions[bot]
37ecf1a056 sync: Add files via upload (A@f25beaaf2f1fcd0c8fca85fa622d846392968047) 2026-05-27 03:17:46 +00:00
github-actions[bot]
6517a3f4cd sync: update auto sync (A@67794d69b70f7d291333020c5ffd071a7836d177) 2026-05-26 05:15:10 +00:00
kae_mihara
ad0f058baa
Initial commit 2026-05-26 14:08:26 +09:00