diff --git a/src/api.js b/src/api.js
new file mode 100644
index 0000000..4d0b40d
--- /dev/null
+++ b/src/api.js
@@ -0,0 +1,93 @@
+// src/api.js
+// API utama untuk flow auth dan solid data (upload, fetch dokumen, organisasi)
+
+// Membuat header auth
+export const authHeaders = (extra = {}) => {
+ const token = localStorage.getItem("token");
+ const headers = {
+ Authorization: `Bearer ${token}`,
+ "Content-Type": "application/json",
+ ...extra,
+ };
+ return headers;
+};
+
+// Ambil daftar organisasi user
+export const getOrganizationsFromBackend = async () => {
+ const token = localStorage.getItem("token");
+ if (!token) throw new Error("Token tidak ditemukan. Silakan login.");
+ const res = await fetch("https://bot.kediritechnopark.com/webhook/soliddata/get-organization", {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ Accept: "application/json",
+ },
+ });
+ return await res.json();
+};
+
+// Pilih organisasi aktif
+export const pickOrganization = async (organization_id, nama_organization) => {
+ const token = localStorage.getItem("token");
+ const chosen = { organization_id, nama_organization };
+ await fetch("https://bot.kediritechnopark.com/webhook/soliddata/pick-organization", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ body: JSON.stringify(chosen),
+ });
+ localStorage.setItem("selected_organization", JSON.stringify(chosen));
+};
+
+// Ambil daftar tipe dokumen (jenis dokumen)
+export const fetchDocumentTypes = async (organizationId) => {
+ const token = localStorage.getItem("token");
+ const res = await fetch(
+ "https://bot.kediritechnopark.com/webhook/solid-data/files",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ },
+ body: JSON.stringify({ organization_id: organizationId }),
+ }
+ );
+ return await res.json();
+};
+
+// Ambil entry/data per tipe dokumen
+export const fetchEntries = async (dataTypeId) => {
+ const token = localStorage.getItem("token");
+ const res = await fetch(
+ "https://bot.kediritechnopark.com/webhook/solid-data/files/entry",
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ },
+ body: JSON.stringify({ data_type_id: dataTypeId }),
+ }
+ );
+ return await res.json();
+};
+
+// Upload dokumen (gambar/file)
+export const uploadDocument = async (organizationId, dataTypeId, file) => {
+ const token = localStorage.getItem("token");
+ const formData = new FormData();
+ formData.append("organization_id", organizationId);
+ formData.append("data_type_id", dataTypeId);
+ formData.append("file", file);
+ const res = await fetch("https://bot.kediritechnopark.com/webhook/solid-data/upload", {
+ method: "POST",
+ headers: {
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
+ },
+ body: formData,
+ });
+ return await res.json();
+};
diff --git a/src/pages/DashboardPage.js b/src/pages/DashboardPage.js
index 5b518de..4ccdc00 100644
--- a/src/pages/DashboardPage.js
+++ b/src/pages/DashboardPage.js
@@ -1,17 +1,8 @@
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
+import { fetchDocumentTypes } from '../api';
import { Link } from 'react-router-dom';
import AddDocumentModal from '../components/AddDocumentModal'; // Kita akan buat ini
-// Data dummy
-const documentTypes = [
- { name: 'Akta Kelahiran', count: 0 },
- { name: 'Ijazah', count: 0 },
- { name: 'KK', count: 0 },
- { name: 'KTP', count: 6 },
- { name: 'Polinema', count: 3 },
- { name: 'Sampul Buku', count: 1 },
-];
-
const StatCard = ({ title, value }) => (
{title}
@@ -19,17 +10,40 @@ const StatCard = ({ title, value }) => (
);
-export default function DashboardPage() {
+function DashboardPage() {
const [isModalOpen, setIsModalOpen] = useState(false);
+ const [documentTypes, setDocumentTypes] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState('');
+
+ useEffect(() => {
+ const org = localStorage.getItem('selected_organization');
+ if (!org) {
+ setError('Organisasi belum dipilih.');
+ setLoading(false);
+ return;
+ }
+ const { organization_id } = JSON.parse(org);
+ setLoading(true);
+ fetchDocumentTypes(organization_id)
+ .then((data) => {
+ setDocumentTypes(Array.isArray(data) ? data : data.data || []);
+ setError('');
+ })
+ .catch((err) => {
+ setError(err.message || 'Gagal memuat dokumen');
+ })
+ .finally(() => setLoading(false));
+ }, []);
return (
{/* Statistik */}
-
-
-
+
+
+
{/* Daftar Jenis Dokumen */}
@@ -44,16 +58,32 @@ export default function DashboardPage() {
- {documentTypes.map((doc, index) => (
-
-
{index + 1}
-
-
{doc.name}
-
{doc.count} data tersedia
-
- {/* Arrow Icon */}
-
- ))}
+ {loading ? (
+
Memuat data...
+ ) : error ? (
+
{error}
+ ) : documentTypes.length === 0 ? (
+
Belum ada jenis dokumen.
+ ) : (
+ documentTypes.map((doc, index) => (
+
+
{index + 1}
+
+
{doc.nama_tipe || doc.name}
+
{doc.total_entries || doc.count || 0} data tersedia
+
+
+ ))
+ )}
@@ -61,4 +91,6 @@ export default function DashboardPage() {
setIsModalOpen(false)} />
);
-}
\ No newline at end of file
+}
+
+export default DashboardPage;
\ No newline at end of file
diff --git a/src/pages/InputDataPage.js b/src/pages/InputDataPage.js
index ba4288c..3f6b125 100644
--- a/src/pages/InputDataPage.js
+++ b/src/pages/InputDataPage.js
@@ -1,5 +1,5 @@
import { useState, useRef } from 'react';
-import { useParams, Link } from 'react-router-dom';
+import { useParams, Link, useLocation } from 'react-router-dom';
// Ikon (tidak ada perubahan)
const BackIcon = () => ();
@@ -10,6 +10,9 @@ const TrashIcon = () => (