diff --git a/apps/web/src/app.tsx b/apps/web/src/app.tsx
index cd597a9..fcbcd47 100644
--- a/apps/web/src/app.tsx
+++ b/apps/web/src/app.tsx
@@ -5,28 +5,22 @@ import {
Navigate,
} from "react-router-dom";
import { DashboardPage } from "@/pages/dashboard-page";
-// import { LandingPage } from "@/pages/landing-page";
import { ScanPage } from "@/pages/scan-page";
import { LibraryPage } from "@/pages/library-page";
import { CatalogPage } from "@/pages/catalog-page";
import { DiseaseDetailPage } from "@/pages/disease-detail-page";
import { DiagnosisDetailPage } from "@/pages/diagnosis-detail-page";
import { ExpertReviewsPage } from "@/pages/expert-reviews-page";
-// import { LoginPage } from "@/pages/login-page";
-// import { RegisterPage } from "@/pages/register-page";
+import { DiagnosesPage } from "@/pages/diagnoses-page";
import { MainLayout } from "@/components/layout/main-layout";
const queryClient = new QueryClient();
const router = createBrowserRouter([
- // {
- // path: "/",
- // element: (
- //
- //
- //
- // ),
- // },
+ {
+ path: "/",
+ element: ,
+ },
{
path: "/",
element: ,
@@ -47,8 +41,7 @@ const router = createBrowserRouter([
),
},
- // { path: "/login", element: },
- // { path: "/register", element: },
+
{
path: "/dashboard",
element: (
@@ -61,6 +54,14 @@ const router = createBrowserRouter([
path: "/diagnoses/:id",
element: ,
},
+ {
+ path: "/diagnoses",
+ element: (
+
+
+
+ ),
+ },
{
path: "/expert/reviews",
element: ,
diff --git a/apps/web/src/pages/dashboard-page.tsx b/apps/web/src/pages/dashboard-page.tsx
index aadf457..17a1308 100644
--- a/apps/web/src/pages/dashboard-page.tsx
+++ b/apps/web/src/pages/dashboard-page.tsx
@@ -156,8 +156,11 @@ export function DashboardPage() {
{summary.diseaseCount}
-
-
+
+ Lihat daftar
+
+
+
@@ -169,8 +172,11 @@ export function DashboardPage() {
{summary.imageClassificationCount}
-
-
+
+ Lihat daftar
+
+
+
@@ -182,6 +188,9 @@ export function DashboardPage() {
{summary.needsReviewCount}
+
+ Lihat daftar
+
@@ -195,6 +204,9 @@ export function DashboardPage() {
{summary.riskDistribution.high}
+
+ Lihat daftar
+
diff --git a/apps/web/src/pages/diagnoses-page.tsx b/apps/web/src/pages/diagnoses-page.tsx
new file mode 100644
index 0000000..f05b946
--- /dev/null
+++ b/apps/web/src/pages/diagnoses-page.tsx
@@ -0,0 +1,146 @@
+import { useMemo, useState } from "react";
+import { Link } from "react-router-dom";
+import { useQuery } from "@tanstack/react-query";
+import { Button } from "@/components/ui/button";
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+import { DiagnosisStatusBadge } from "@/components/diagnosis-status-badge";
+import { RiskBadge } from "@/components/risk-badge";
+import { apiClient } from "@/lib/api-client";
+
+export function DiagnosesPage() {
+ const [statusFilter, setStatusFilter] = useState<
+ "all" | "needs_review" | "verified" | "failed"
+ >("all");
+ const [riskFilter, setRiskFilter] = useState<
+ "all" | "high" | "medium" | "low"
+ >("all");
+
+ const query = useQuery({
+ queryKey: ["diagnoses"],
+ queryFn: () => apiClient.getDiagnoses(),
+ });
+ const diagnoses = query.data ?? [];
+
+ const filtered = useMemo(() => {
+ return diagnoses.filter((d) => {
+ if (statusFilter !== "all" && d.status !== statusFilter) return false;
+ if (riskFilter !== "all") {
+ const level = d.disease?.riskLevel ?? "low";
+ if (level !== riskFilter) return false;
+ }
+ return true;
+ });
+ }, [diagnoses, statusFilter, riskFilter]);
+
+ return (
+
+
+
+
+
+ Manajemen Diagnosis
+
+
Daftar Diagnosis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total: {filtered.length}
+
+
+
+ {query.isLoading ? (
+
+ Memuat diagnosis...
+
+ ) : query.isError ? (
+
+ Gagal memuat diagnosis
+
+ ) : filtered.length === 0 ? (
+
+ Tidak ada diagnosis sesuai filter
+
+ ) : (
+
+ {filtered.map((d) => (
+
+
+
+
+
+
+
+ {d.disease?.commonName ?? "Unknown"}
+
+
+ {d.predictedDiseaseSlug ?? ""}
+
+
+
+
+
+
+
+
+
+
+ {new Date(d.createdAt).toLocaleString("id-ID")}
+
+
+ Lihat detail
+
+
+
+
+
+ ))}
+
+ )}
+
+
+
+
+ );
+}
+
+export default DiagnosesPage;
diff --git a/apps/web/src/pages/scan-page.tsx b/apps/web/src/pages/scan-page.tsx
index 28fd0aa..82e5dae 100644
--- a/apps/web/src/pages/scan-page.tsx
+++ b/apps/web/src/pages/scan-page.tsx
@@ -1,6 +1,6 @@
import React, { useRef, useState } from "react";
-import { useNavigate } from "react-router-dom";
-import { useMutation, useQueryClient } from "@tanstack/react-query";
+import { useNavigate, Link } from "react-router-dom";
+import { useMutation, useQueryClient, useQuery } from "@tanstack/react-query";
import { apiClient } from "@/lib/api-client";
import { Modal } from "@/components/ui/modal";
import type { DiagnosisRecord } from "@zeavis/shared";
@@ -16,7 +16,7 @@ export function ScanPage() {
onSuccess: (diagnosis) => {
queryClient.invalidateQueries({ queryKey: ["diagnoses"] });
// show preview modal instead of immediate navigation
- setDiagnosisPreview(diagnosis as DiagnosisRecord);
+ setDiagnosisPreview(diagnosis);
setPreviewOpen(true);
},
});
@@ -31,6 +31,12 @@ export function ScanPage() {
const [diagnosisPreview, setDiagnosisPreview] =
useState(null);
+ const diagnosesQuery = useQuery({
+ queryKey: ["diagnoses"],
+ queryFn: () => apiClient.getDiagnoses(),
+ enabled: previewOpen,
+ });
+
return (
Scan Tanaman
@@ -135,6 +141,53 @@ export function ScanPage() {
+
+
+ Daftar Diagnosis Terbaru
+
+ {diagnosesQuery.isLoading && (
+
+ Memuat daftar...
+
+ )}
+ {diagnosesQuery.isError && (
+
+ Gagal memuat daftar diagnosis
+
+ )}
+ {!diagnosesQuery.isLoading && !diagnosesQuery.isError && (
+
+ {(diagnosesQuery.data ?? []).slice(0, 5).map((d) => (
+
+
+

+
+
+ {d.disease?.commonName ?? d.predictedDiseaseSlug}
+
+
+ {new Date(d.createdAt).toLocaleString("id-ID")}
+
+
+
+
+ Lihat
+
+
+ ))}
+
+ )}
+
) : null}