feat(admin): refactor UMKM edit pages to match berita pattern with interfaces

This commit is contained in:
2026-04-24 14:34:02 +08:00
parent 7f5588f69e
commit 187e3a2115
6 changed files with 72 additions and 34 deletions

View File

@@ -14,9 +14,9 @@ The edit pages for UMKM (Data UMKM and Produk) use an older UI pattern. The user
## Progress ## Progress
- [x] Analyze Berita edit page pattern - [x] Analyze Berita edit page pattern
- [x] Refactor UMKM Produk edit page - [x] Refactor UMKM Produk edit page (with interfaces)
- [x] Refactor Data UMKM edit page - [x] Refactor Data UMKM edit page (with interfaces)
- [ ] Run build and fix any errors - [x] Run build and fix any errors
- [ ] Update version in package.json - [ ] Update version in package.json
- [ ] Commit and push to task branch - [ ] Commit and push to task branch
- [ ] Merge to stg branch - [ ] Merge to stg branch

View File

@@ -4,9 +4,9 @@ Refactor Data UMKM and Produk edit pages to match the Berita edit page UI patter
## Steps ## Steps
1. [x] Analyze `berita/list-berita/[id]/edit/page.tsx` for the desired pattern. 1. [x] Analyze `berita/list-berita/[id]/edit/page.tsx` for the desired pattern.
2. [x] Implement the pattern in `ekonomi/umkm/produk/[id]/edit/page.tsx`. 2. [x] Implement the pattern in `ekonomi/umkm/produk/[id]/edit/page.tsx` (using interfaces).
3. [x] Implement the pattern in `ekonomi/umkm/data-umkm/[id]/edit/page.tsx`. 3. [x] Implement the pattern in `ekonomi/umkm/data-umkm/[id]/edit/page.tsx` (using interfaces).
4. [ ] Run `bun run build` to verify. 4. [x] Run `bun run build` to verify.
5. [ ] Update `package.json` version. 5. [x] Update `package.json` version.
6. [ ] Commit with message: "feat(admin): refactor UMKM edit pages to match berita pattern". 6. [x] Commit with message: "feat(admin): refactor UMKM edit pages to match berita pattern with interfaces".
7. [ ] Create summary in `MIND/SUMMARY/refactor-umkm-edit-pages-pattern-summary.md`. 7. [ ] Create summary in `MIND/SUMMARY/refactor-umkm-edit-pages-pattern-summary.md`.

View File

@@ -1,11 +1,12 @@
# Summary - Refactor UMKM Edit Pages Pattern # Summary - Refactor UMKM Edit Pages Pattern
## Changes ## Changes
1. **UMKM Produk Edit Page**: Refactored `src/app/admin/(dashboard)/ekonomi/umkm/produk/[id]/edit/page.tsx` to match the "Berita" edit page pattern. Added Reset ("Batal") functionality, standardized header, paper, and dropzone styling, and used `EditEditor`. 1. **UMKM Produk Edit Page**: Refactored `src/app/admin/(dashboard)/ekonomi/umkm/produk/[id]/edit/page.tsx` to match the "Berita" edit page pattern. Added explicit `ProdukData` and `ProdukForm` interfaces. Added Reset ("Batal") functionality, standardized header, paper, and dropzone styling, and used `EditEditor`.
2. **Data UMKM Edit Page**: Refactored `src/app/admin/(dashboard)/ekonomi/umkm/data-umkm/[id]/edit/page.tsx` with the same pattern and improvements. 2. **Data UMKM Edit Page**: Refactored `src/app/admin/(dashboard)/ekonomi/umkm/data-umkm/[id]/edit/page.tsx` with the same pattern and interfaces (`UmkmData`, `UmkmForm`).
3. **UI Consistency**: Standardized colors and component usage across UMKM edit pages. 3. **Type Safety**: Improved type safety by using explicit interfaces for data fetching and form state management.
4. **UX Improvement**: Added a "Batal" button that resets the form to its original data state. 4. **UI Consistency**: Standardized colors and component usage across UMKM edit pages.
5. **Build Verification**: Confirmed that the project builds successfully with `bun run build`. 5. **UX Improvement**: Added a "Batal" button that resets the form to its original data state.
6. **Build Verification**: Confirmed that the project builds successfully with `bun run build`.
## Verification Results ## Verification Results
- `bun run build`: Success. - `bun run build`: Success.

View File

@@ -1,6 +1,6 @@
{ {
"name": "desa-darmasaba", "name": "desa-darmasaba",
"version": "0.1.22", "version": "0.1.23",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -32,18 +32,39 @@ import { toast } from "react-toastify";
import { useProxy } from "valtio/utils"; import { useProxy } from "valtio/utils";
import umkmState from "../../../../../_state/ekonomi/umkm/umkm"; import umkmState from "../../../../../_state/ekonomi/umkm/umkm";
interface UmkmData {
id: string;
nama: string;
pemilik: string;
kategoriId: string | null;
deskripsi: string | null;
alamat: string | null;
kontak: string | null;
imageId: string | null;
image?: { url: string } | null;
}
interface UmkmForm {
nama: string;
pemilik: string;
kategoriId: string;
deskripsi: string;
alamat: string;
kontak: string;
imageId: string;
}
function EditDataUmkm() { function EditDataUmkm() {
const router = useRouter(); const router = useRouter();
const params = useParams(); const params = useParams();
const id = params.id as string; const id = params.id as string;
const state = useProxy(umkmState.umkm);
const [previewImage, setPreviewImage] = useState<string | null>(null); const [previewImage, setPreviewImage] = useState<string | null>(null);
const [file, setFile] = useState<File | null>(null); const [file, setFile] = useState<File | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [isInitialLoading, setIsInitialLoading] = useState(true); const [isInitialLoading, setIsInitialLoading] = useState(true);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState<UmkmForm>({
nama: "", nama: "",
pemilik: "", pemilik: "",
kategoriId: "", kategoriId: "",
@@ -53,7 +74,7 @@ function EditDataUmkm() {
imageId: "", imageId: "",
}); });
const [originalData, setOriginalData] = useState({ const [originalData, setOriginalData] = useState<UmkmForm & { imageUrl: string }>({
nama: "", nama: "",
pemilik: "", pemilik: "",
kategoriId: "", kategoriId: "",
@@ -79,9 +100,9 @@ function EditDataUmkm() {
umkmState.umkm.findUnique.load(id) umkmState.umkm.findUnique.load(id)
]); ]);
const data = umkmState.umkm.findUnique.data; const data = umkmState.umkm.findUnique.data as UmkmData | null;
if (data) { if (data) {
const initialForm = { const initialForm: UmkmForm = {
nama: data.nama || "", nama: data.nama || "",
pemilik: data.pemilik || "", pemilik: data.pemilik || "",
kategoriId: data.kategoriId || "", kategoriId: data.kategoriId || "",
@@ -106,7 +127,7 @@ function EditDataUmkm() {
init(); init();
}, [id]); }, [id]);
const handleChange = (field: string, value: string) => { const handleChange = (field: keyof UmkmForm, value: string) => {
setFormData((prev) => ({ ...prev, [field]: value })); setFormData((prev) => ({ ...prev, [field]: value }));
}; };
@@ -291,7 +312,7 @@ function EditDataUmkm() {
label="Kategori Bisnis" label="Kategori Bisnis"
placeholder="Pilih kategori" placeholder="Pilih kategori"
required required
data={umkmState.kategoriProduk.findManyAll.data?.map(v => ({ data={umkmState.kategoriProduk.findManyAll.data?.map((v: any) => ({
value: v.id, label: v.nama value: v.id, label: v.nama
})) || []} })) || []}
value={formData.kategoriId} value={formData.kategoriId}

View File

@@ -33,18 +33,39 @@ import { toast } from "react-toastify";
import { useProxy } from "valtio/utils"; import { useProxy } from "valtio/utils";
import umkmState from "../../../../../_state/ekonomi/umkm/umkm"; import umkmState from "../../../../../_state/ekonomi/umkm/umkm";
interface ProdukData {
id: string;
nama: string;
harga: number;
stok: number;
umkmId: string | null;
deskripsi: string | null;
imageId: string | null;
kategoriId: string | null;
image?: { url: string } | null;
}
interface ProdukForm {
nama: string;
harga: number;
stok: number;
umkmId: string;
deskripsi: string;
imageId: string;
kategoriId: string;
}
function EditProdukUmkm() { function EditProdukUmkm() {
const router = useRouter(); const router = useRouter();
const params = useParams(); const params = useParams();
const id = params.id as string; const id = params.id as string;
const state = useProxy(umkmState.produk);
const [previewImage, setPreviewImage] = useState<string | null>(null); const [previewImage, setPreviewImage] = useState<string | null>(null);
const [file, setFile] = useState<File | null>(null); const [file, setFile] = useState<File | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [isInitialLoading, setIsInitialLoading] = useState(true); const [isInitialLoading, setIsInitialLoading] = useState(true);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState<ProdukForm>({
nama: "", nama: "",
harga: 0, harga: 0,
stok: 0, stok: 0,
@@ -54,7 +75,7 @@ function EditProdukUmkm() {
kategoriId: "", kategoriId: "",
}); });
const [originalData, setOriginalData] = useState({ const [originalData, setOriginalData] = useState<ProdukForm & { imageUrl: string }>({
nama: "", nama: "",
harga: 0, harga: 0,
stok: 0, stok: 0,
@@ -65,11 +86,6 @@ function EditProdukUmkm() {
imageUrl: "" imageUrl: ""
}); });
const isHtmlEmpty = (html: string) => {
const textContent = html.replace(/<[^>]*>/g, '').trim();
return textContent === '';
};
const isFormValid = () => { const isFormValid = () => {
return ( return (
formData.nama?.trim() !== '' && formData.nama?.trim() !== '' &&
@@ -88,9 +104,9 @@ function EditProdukUmkm() {
umkmState.produk.findUnique.load(id) umkmState.produk.findUnique.load(id)
]); ]);
const data = umkmState.produk.findUnique.data; const data = umkmState.produk.findUnique.data as ProdukData | null;
if (data) { if (data) {
const initialForm = { const initialForm: ProdukForm = {
nama: data.nama || "", nama: data.nama || "",
harga: data.harga || 0, harga: data.harga || 0,
stok: data.stok || 0, stok: data.stok || 0,
@@ -115,7 +131,7 @@ function EditProdukUmkm() {
init(); init();
}, [id]); }, [id]);
const handleChange = (field: string, value: any) => { const handleChange = (field: keyof ProdukForm, value: string | number) => {
setFormData((prev) => ({ ...prev, [field]: value })); setFormData((prev) => ({ ...prev, [field]: value }));
}; };
@@ -284,7 +300,7 @@ function EditProdukUmkm() {
placeholder="Siapa pemilik produk ini?" placeholder="Siapa pemilik produk ini?"
required required
searchable searchable
data={umkmState.umkm.findMany.data?.map(v => ({ data={umkmState.umkm.findMany.data?.map((v: any) => ({
value: v.id, label: v.nama value: v.id, label: v.nama
})) || []} })) || []}
value={formData.umkmId} value={formData.umkmId}
@@ -327,7 +343,7 @@ function EditProdukUmkm() {
label="Kategori Produk" label="Kategori Produk"
placeholder="Pilih kategori produk" placeholder="Pilih kategori produk"
required required
data={umkmState.kategoriProduk.findManyAll.data?.map(v => ({ data={umkmState.kategoriProduk.findManyAll.data?.map((v: any) => ({
value: v.id, label: v.nama value: v.id, label: v.nama
})) || []} })) || []}
value={formData.kategoriId} value={formData.kategoriId}