Files
desa-darmasaba/src/state/admin/adminFormState.ts
nico 6ed2392420 Add comprehensive testing suite and fix QC issues
- Add 115+ unit, component, and E2E tests
- Add Vitest configuration with coverage thresholds
- Add validation schema tests (validations.test.ts)
- Add sanitizer utility tests (sanitizer.test.ts)
- Add WhatsApp service tests (whatsapp.test.ts)
- Add component tests for UnifiedTypography and UnifiedSurface
- Add E2E tests for admin auth and public pages
- Add testing documentation (docs/TESTING.md)
- Add sanitizer and WhatsApp utilities
- Add centralized validation schemas
- Refactor state management (admin/public separation)
- Fix security issues (OTP via POST, session password validation)
- Update AGENTS.md with testing guidelines

Test Coverage: 50%+ target achieved
All tests passing: 115/115

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-09 14:05:03 +08:00

113 lines
2.7 KiB
TypeScript

/**
* Admin Form State
*
* State management untuk form di admin dashboard
* Menggunakan Valtio untuk reactive state
*/
import { proxy } from "valtio";
export interface FileStorageItem {
id: string;
name: string;
path: string;
link: string;
realName: string;
mimeType: string;
category: string;
isActive: boolean;
createdAt: Date;
updatedAt: Date;
deletedAt: Date | null;
}
export interface ListItem {
id: string;
name: string;
url: string;
total: number;
realName: string;
}
export const adminFormState = proxy<{
list: ListItem[] | null;
page: number;
count: number;
total: number | undefined;
isLoading: boolean;
error: string | null;
load: (params?: { search?: string; page?: number }) => Promise<void>;
del: (params: { id: string }) => Promise<void>;
reset: () => void;
}>({
list: null,
page: 1,
count: 10,
total: undefined,
isLoading: false,
error: null,
async load(params?: { search?: string; page?: number }) {
const { search = "", page = this.page } = params ?? {};
this.page = page;
this.isLoading = true;
this.error = null;
try {
// Import dinamis untuk menghindari circular dependency
const ApiFetch = (await import('@/lib/api-fetch')).default;
const response = await ApiFetch.api.fileStorage["findMany"].get({
query: {
page: this.page,
search,
},
}) as { data: { data: FileStorageItem[]; meta: { total: number; totalPages: number } } };
if (response?.data?.data) {
this.list = response.data.data.map((file) => ({
id: file.id,
name: file.name,
url: file.link || `/api/fileStorage/${file.realName}`,
total: response.data.meta?.total || 0,
realName: file.realName,
}));
this.total = response.data.meta?.totalPages;
}
} catch (error) {
console.error("Error loading images:", error);
this.error = error instanceof Error ? error.message : 'Failed to load images';
this.list = [];
} finally {
this.isLoading = false;
}
},
async del({ id }: { id: string }) {
try {
const ApiFetch = (await import('@/lib/api-fetch')).default;
await ApiFetch.api.fileStorage.delete({ id });
await this.load({ page: this.page });
} catch (error) {
console.error("Error deleting image:", error);
throw error;
}
},
reset() {
this.list = null;
this.page = 1;
this.count = 10;
this.total = undefined;
this.isLoading = false;
this.error = null;
},
});
// Helper hook untuk React components
export const useAdminForm = () => {
return adminFormState;
};
export default adminFormState;