Commit Graph
113 Commits
Author SHA1 Message Date
MythEclipseandClaude 7423e4d83b fix(tauri): use raw __TAURI_INTERNALS__ invoke, fix dynamic import on Android
Root cause: dynamic import('@tauri-apps/plugin-opener') silently fails on
Android Tauri WebView because the module resolution path for @tauri-apps/api
(plugin dependency) differs from npm expectations in the bundled context.

Rewrote tauri.ts to use window.__TAURI_INTERNALS__.invoke() directly:
- openUrl() → invoke('plugin:opener|open_url', {url})
- setupDeepLinkHandler() → invoke('plugin:deep-link|get_current')
- Warm-start listener still uses import('@tauri-apps/api/event') for
  deep-link://new-url events (bundled as separate chunk by Vite)
- Added @tauri-apps/api as direct dependency

Also kept withGlobalTauri: true (needed for __TAURI_INTERNALS__ injection)
but reverted APK frontendDist back to bundled React app (../web/dist)
since redirect-to-live-web approach was unreliable.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 04:34:13 +07:00
MythEclipseandClaude 7148e1026e feat(android): APK loads live web, fix cold-start deep links for Google OAuth
APK architecture change: replaces bundled React SPA with minimal redirect
page that always loads live web content. No more APK rebuilds for web changes.

Root cause of OAuth failure on Android:
1. Cold-start deep links lost — APK's old bundled JS called onOpenUrl()
   (warm-start listener only) but NOT getCurrent() which is required for
   cold-start deep links. Fix: redirect page + setupDeepLinkHandler both
   call getCurrent() before redirecting/navigating.
2. Session cookie was dropped — renderTauriDeepLinkPage returned a raw
   new Response() which overwrote the Set-Cookie header set by the
   callback handler. Fix: inject Set-Cookie into the Response.
3. tauri.conf.json frontendDist → "./web/dist-tauri" (redirect page)
4. Added @tauri-apps/plugin-deep-link and @tauri-apps/plugin-opener as
   web app deps so live-web imports work in Tauri WebView.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 03:47:22 +07:00
Selly SupriyatinandGitHub 3b5839ebd5 Merge pull request #42 from ATLAS-PJK-GM007/selly/frontend
style(sidebar): standardize capitalization of feature titles
2026-06-16 02:48:40 +07:00
MythEclipseandClaude e2742a7a60 fix(auth): fix Android deep link intent URL format for Google OAuth
The intent:// URL in renderTauriDeepLinkPage was intent:/path (single slash),
producing zeavisedu:/login?token=xxx — a non-hierarchical URL that new URL()
cannot parse. Fixed to intent://login/path which produces a proper
hierarchical URI (zeavisedu://login/login?token=xxx).

Also hardened setupDeepLinkHandler to handle both double-slash (://) and
single-slash (:/) custom-scheme URLs as fallback.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 02:44:33 +07:00
seriouselly ae22adee40 style(sidebar): standardize capitalization of feature titles
- Update navigation labels in the sidebar for consistent casing and better visual uniformity.
2026-06-16 02:38:01 +07:00
seriouselly ccbcd99053 refactor(ui): remove local image assets and use external URLs
- Delete the `assets/images` directory to reduce repository size and footprint.
- Update `dashboard-page.tsx` to fetch background images from external URLs instead of local file imports.
2026-06-16 02:13:17 +07:00
seriouselly 52e60b99dd Revert "refactor(ui): remove local image assets and use external URLs"
This reverts commit e19321a2b7.
2026-06-16 02:10:32 +07:00
seriouselly e19321a2b7 refactor(ui): remove local image assets and use external URLs
- Delete the `assets/images` directory to reduce repository size and footprint.
- Update `dashboard-page.tsx` to fetch background images from external URLs instead of local file imports.
2026-06-16 02:09:36 +07:00
seriouselly d1282364e7 refactor(auth): replace local background images with external URLs
- Remove local image imports for the background in login and register pages.
- Update background-image styles to use external URL links for easier asset management.
2026-06-16 01:51:22 +07:00
MythEclipseandClaude 1afd2e013c fix(android): add deep link handler to intercept zeavisedu:// URLs and navigate WebView
Login-page won't auto-process token on deep link return because
the WebView stays on the page it was on. Added setupDeepLinkHandler()
which listens for zeavisedu:// scheme URLs and navigates the WebView
to the correct path+query.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 01:03:45 +07:00
MythEclipseandClaude fc832b404e fix(auth): use VITE_API_BASE_URL for Google OAuth redirect instead of window.location.origin
On Tauri Android, window.location.origin = http://tauri.localhost
which is the embedded dev server URL, not the API server.
Use VITE_API_BASE_URL env var which points to the production API.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-16 00:23:46 +07:00
MythEclipseandClaude ac59548337 feat(android): Google OAuth via system browser + deep link for Android
Background: Google blocks OAuth in embedded WebView (403 disallowed_useragent).
Solution: open Google login in the Android system browser, then deep-link
back to the Tauri app via custom scheme after callback.

Changes:
- Tauri: add tauri-plugin-opener + tauri-plugin-deep-link to Cargo.toml
- Tauri: register plugins in lib.rs, add capabilities
- Web: auth-form.tsx Google button uses openUrl() via @tauri-apps/plugin-opener
  on Tauri (opens in system browser), falls back to window.location.href
- Web: add lib/tauri.ts for isTauri() detection + lazy opens
- API: /auth/google accepts ?platform=tauri → encodes into OAuth state param
- API: /auth/google/callback decodes state → if tauri, renders HTML page
  that deep-links back via zeavisedu:// scheme; if web, 302 redirect
- Android: patch script adds deep link intent filter for zeavisedu:// scheme

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 23:49:47 +07:00
MythEclipseandClaude d292bc4b3c feat(auth): add Google logo SVG to 'Masuk dengan Google' button
Inline SVG with official Google brand colors (blue, green, yellow, red)
placed before the label text with gap-2.5 spacing.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 23:17:46 +07:00
MythEclipseandClaude 787acf077f fix(vite): add data-cfasync="false" to script tags to prevent Cloudflare Rocket Loader breaking JS
Cloudflare Rocket Loader rewrites <script type="module"> to
<script type="randomhash-module"> which browsers can't parse,
causing complete blank page. data-cfasync="false" disables this.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 23:00:30 +07:00
MythEclipseandClaude 250355562f fix(login): replace useSearchParams with native URLSearchParams + loading spinner
- useSearchParams can lose params during re-renders, causing blank page
- Use native window.location.search + URLSearchParams instead (always accessible)
- Add oauthProcessing spinner state so user sees 'Menyelesaikan login...'
  instead of blank page while /auth/me is being called

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 22:38:11 +07:00
MythEclipseandClaude c9ae90a042 feat(auth): implement Google OAuth callback with user auto-creation
API (apps/api/src/routes/auth.ts):
- Exchange authorization code for tokens via Google's token endpoint
- Decode id_token payload (JWT) to extract sub, email, name
- Find user by googleId → fall back to email match (link accounts)
- Auto-create user if neither found (role: 'user', no password)
- Create session + set cookie, redirect to /login?token=<token>

Web (apps/web/src/pages/login-page.tsx):
- Consume ?token= query param from OAuth redirect
- Store token in localStorage for future API calls
- Fetch /auth/me to hydrate Zustand store, then navigate to dashboard
- Show OAuth errors from ?error= query param

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 21:35:40 +07:00
seriouselly 2eabf12b36 Merge branch 'main' of https://github.com/ATLAS-PJK-GM007/ZeaVis-Edu into selly/frontend 2026-06-15 20:55:21 +07:00
seriouselly b18b98e1a7 fix(scan): resolve empty medicine data and clean up linter warning
- Add local fallback using `diseaseCatalogSeed` to populate medicine recommendations in the diagnosis preview modal when API data is missing.
- Remove unused `diagnosesQuery` assignment to resolve SonarLint warning while preserving the background prefetching logic.
2026-06-15 20:54:44 +07:00
MythEclipseandClaude a36b74a1cf feat(scan): add camera capture for Android with toggle between upload and live camera
- Add CameraCapture component with live viewfinder via getUserMedia
- Support rear/environment camera (default) with switch to front/user
- Capture to JPEG 92% quality via canvas, reuse existing upload flow
- Toggle between 'Unggah' (file upload) and 'Kamera' (live capture) modes
- Error handling for denied/not found/not readable in Bahasa Indonesia
- Add patch script for AndroidManifest CAMERA permission (gen/ is gitignored)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 20:54:11 +07:00
seriouselly 9cfbef4598 Merge branch 'main' of https://github.com/ATLAS-PJK-GM007/ZeaVis-Edu into selly/frontend 2026-06-15 20:39:01 +07:00
seriouselly 8f1308c8af fix(diagnosis): correct risk level mapping and dynamic confidence UI
- Fix `getRiskLevelKey` to properly recognize English risk level values ("low", "high"), preventing "Healthy Leaf" from incorrectly defaulting to medium risk.
- Update confidence bar text and colors to dynamically show warning alerts when AI confidence falls below the 75% threshold.
2026-06-15 20:38:26 +07:00
MythEclipseandClaude 7693a02c98 fix(auth): add bearer token auth as fallback for Android WebView third-party cookie blocking
Android WebView blocks third-party cookies by default. This patch:
- Returns session token in login/register response body
- Stores token in localStorage, sends via Authorization: Bearer header
- Backend getCurrentUser supports Authorization header fallback

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 19:43:02 +07:00
MythEclipseandClaude 528a1622d0 fix(auth): prevent AuthInitializer from overwriting Zustand with null user
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 19:04:29 +07:00
MythEclipseandClaude 51a4cb9ed2 fix(auth): detect HTTPS via X-Forwarded-Proto for SameSite=None cookies, fix AuthGuard null overwrite
- Cookie SameSite now dynamic: None;Secure when behind HTTPS proxy, Lax otherwise
- AuthGuard useEffect no longer overwrites Zustand store with null from background refetch
- AuthInitializer: add staleTime 30s

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 18:17:26 +07:00
MythEclipseandClaude 41e0501e6b fix(tauri): add absolute API base URL default and CORS origins for Android WebView
- Set VITE_API_BASE_URL default to production API URL in api-client.ts
  so fetch() uses absolute URLs instead of relative paths that fail on Tauri
- Add tauri://localhost and https://tauri.localhost to API CORS allowed origins
- Also fix .env WEB_APP_URL from stale .tech to .my.id

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 14:32:54 +07:00
MythEclipseandClaude 8954535e08 fix(ci): add tauri package.json to Dockerfiles and fix Android NDK/build issues
Build and Deploy: workspace has 4 members (api/web/shared/tauri) but
Dockerfiles only copied 3 package.json files. Missing tauri workspace
member caused bun install --production to fail with frozen lockfile
error.

Build Android APK:
- Remove explicit NDK 28 install (runner has NDK 29 pre-installed, dual
  NDK presence broke ANDROID_NDK_HOME resolution)
- Auto-pin NDK version from runner's SDK
- rm -rf gen/android before tauri android init (stale cache recovery)
- Remove gen/android/.gradle from Gradle cache (causes stale state)
- Use --apk flag for faster APK-only build

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 13:54:55 +07:00
MythEclipseandClaude b93be6c6cb fix(docker): copy bun.lock and workspace node_modules to API runner stage
Bun workspace symlinks (apps/api/node_modules/*) pointed to root
.bun cache but were never copied from deps→runner. Added bun.lock,
apps/api/node_modules, and packages/shared/node_modules to the
runner COPY chain so  and  resolve at runtime.

Also added bun.lock to web Dockerfile for deterministic installs.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 03:30:18 +07:00
seriouselly 3b37a92d1e Merge branch 'main' of https://github.com/ATLAS-PJK-GM007/ZeaVis-Edu into selly/frontend 2026-06-15 01:27:40 +07:00
seriouselly 6c1006d4a0 Merge branch 'main' of https://github.com/ATLAS-PJK-GM007/ZeaVis-Edu into selly/frontend 2026-06-15 01:27:13 +07:00
MythEclipseandClaude 03c1e4edb8 fix(ci): add tailwindcss as direct dependency
PostCSS plugin needs tailwindcss package available in node_modules
at build time. Adding it as a direct dependency ensures consistent
resolution.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 01:23:51 +07:00
seriouselly 56b683392c feat(diagnosis): add back to history button and update UI icons
- Add "Kembali ke Riwayat" button to `diagnosis-detail-page.tsx` for better navigation flow.
- Update camera icon in `diagnose-result-view.tsx` to align with the new UI design.
- Resolve merge conflicts with main to sync latest workflow changes.
2026-06-15 01:20:41 +07:00
MythEclipseandClaude 05055ed9cf fix(ci): remove bun.lock from Docker COPY to avoid version mismatch
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 01:17:25 +07:00
seriouselly 4b5530ef73 Merge branch 'main' of https://github.com/ATLAS-PJK-GM007/ZeaVis-Edu into selly/frontend 2026-06-15 01:09:04 +07:00
MythEclipseandClaude 02ae022174 fix(ci): regenerate bun.lock and disable frozen-lockfile in Dockerfiles
bun auto-enables --frozen-lockfile in CI by default. Use env var
BUN_INSTALL_FROZEN_LOCKFILE=0 to override this behavior. Also
regenerate lockfile fresh to ensure it is compatible with bun 1.3.14.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 01:06:17 +07:00
seriouselly 61a4043967 Revert "fix(ci): add --no-frozen-lockfile to bun install in Dockerfiles"
This reverts commit 9ee3af8a1f.
2026-06-15 01:05:04 +07:00
MythEclipseandClaude 9ee3af8a1f fix(ci): add --no-frozen-lockfile to bun install in Dockerfiles
bun defaults to --frozen-lockfile in CI environments, causing failures
when the lockfile format differs from the version used at build time.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 01:02:35 +07:00
MythEclipseandClaude 3d3ca72230 fix(ci): remove --frozen-lockfile to prevent bun version mismatch failures
CI uses bun 1.3.14 (stable) but local dev uses canary. Lockfile
format can differ between versions causing spurious failures.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 00:57:31 +07:00
seriouselly 21ca1befcd refactor(diagnosis/catalog): improve UI consistency and fix data rendering
- Fix reference error in `DiagnosisResultView` by correctly mapping `riskLevel` prop.
- Integrate dynamic `RiskBadge` with automated severity-to-color mapping for both diagnosis and catalog views.
- Update icons in the medicine recommendation section of `catalog-page` and `DiagnosisResultView` for better visual consistency and intuition.
2026-06-14 23:59:59 +07:00
seriouselly 3ce565509f style(catalog): update medicine recommendation icons for better visual clarity
- Replace previous icons in the medicine recommendation section with more intuitive visual elements.
- Enhance the user interface consistency within the catalog page.
2026-06-14 23:27:06 +07:00
seriouselly d07d47b974 refactor(diagnosis): enhance detail page usability and data robustness
- Implement `useEffect` to ensure smooth scroll-to-top on navigation.
- Add fallback logic to populate medicine recommendations from local seed data if backend payload is incomplete.
- Integrate dynamic `RiskBadge` component with automated severity-to-color mapping for better visual clarity.
2026-06-14 23:19:42 +07:00
seriouselly e9d175a2b5 fix(diagnosis): add fallback seed data for medicine recommendations
- Import diseaseCatalogSeed into diagnosis detail and scan pages.
- Implement fallback logic to populate medicine recommendations when backend payload lacks treatment data.
- Ensure consistent educational content display across catalog and diagnosis views.
2026-06-14 22:43:21 +07:00
seriouselly fe2734310a fix(layout): correct sidebar toggle behavior and navigation logic
- Remove `onClick` toggle handler from `Sidebar` links to prevent unwanted state changes during navigation.
- Remove aggressive `onClick` auto-collapse from `MainLayout` content wrapper so the sidebar remains stable.
- Ensure sidebar state is exclusively managed by the dedicated toggle button, aligning with standard desktop UX.
2026-06-14 22:25:46 +07:00
seriouselly 5272968c6f refactor(scan): reset upload form state after successful diagnosis
- Restore setFileName(null) and setPreviewUrl(null) in the mutation onSuccess callback.
- Ensure the file upload area resets to its default state immediately after a successful scan, preparing the UI for the next input.
2026-06-14 21:01:21 +07:00
seriouselly daf679b31f chore(components): refine inline comments in diagnosis result view
- Update and clarify inline code comments in the diagnosis result view component.
- Improve code readability and maintainability without altering any underlying logic or UI behavior.
2026-06-14 20:57:48 +07:00
seriouselly 63ccc1255a fix(scan): resolve double scrollbar and modal size type errors
- Remove nested overflow and fixed height classes (`max-h-[75vh]`, `overflow-y-auto`) from the inner modal container to fix the double scrollbar UI glitch.
- Adjust the Modal `size` property to a supported type to resolve TypeScript compilation errors.
- Ensure a cleaner, more seamless scrolling experience for the diagnosis result pop-up.
2026-06-14 20:40:43 +07:00
seriouselly 2733a36ea8 feat(catalog): make entire disease card clickable to toggle accordion
- Move the `onClick` event handler from the accordion header to the outermost card container in `catalog-page.tsx`.
- Allow users to click anywhere on the expanded card (including the description and treatment sections) to collapse it.
- Improve overall user experience by providing a significantly larger tap target, especially beneficial for mobile or touch-screen users.
2026-06-14 19:46:38 +07:00
seriouselly 8d342e1269 fix(catalog): add fallback to local seed data for images and medicines
- Import `diseaseCatalogSeed` to use as a fallback data source in `catalog-page.tsx`.
- Implement logic to merge backend API responses with local seed data, ensuring `imageUrl` and `medicineRecommendations` are populated.
- Fix an issue where disease images and specific treatments were not rendering due to missing fields in the database payload.
- Enhance UI resilience by displaying accurate visual and medical data without requiring immediate backend updates.
- Convert static PNG image assets to WebP format and remove old PNG files to significantly reduce image payload size and improve page load performance.
- Enhance overall UI resilience and frontend speed.
2026-06-14 19:28:19 +07:00
seriouselly bc58b16ddd feat(layout): auto-collapse sidebar when clicking main content area
- Import `useUiStore` into `main-layout.tsx` to access the global sidebar state.
- Add an `onClick` event listener to the main content wrapper.
- Automatically close the sidebar if it is expanded and the user clicks outside of it.
- Enhance overall UX by providing a more intuitive, frictionless way to dismiss the navigation menu.
2026-06-12 12:57:30 +07:00
seriouselly 3b8cb49f2a fix(sidebar): toggle sidebar state when clicking navigation links
- Update the `onClick` handler for navigation links in `sidebar.tsx` to use `!isSidebarOpen` instead of a hardcoded boolean.
- Enable navigation items to act as smart toggles: expanding the sidebar when clicked in collapsed mode, and collapsing it when clicked in expanded mode.
- Improve overall user experience by reducing the need to manually click the main toggle button.
2026-06-12 12:35:46 +07:00
seriouselly a77a6c84ff fix(sidebar): persist sidebar state across page navigation
- Move `isSidebarOpen` state from local component (`useState`) to global Zustand store (`ui-store.ts`).
- Fix an issue where the sidebar would incorrectly reset to its default closed state when navigating between routes (e.g., to the Telemetry page) due to component remounting.
- Ensure consistent sidebar toggle behavior across the entire dashboard application.
2026-06-12 12:26:11 +07:00