fix(compiler): migrate custom-fields-manager to useQuery
set-state-in-effect: 44 → 43. Eight admin list/load sites migrated total this session; the remaining ~43 hits are predominantly the dialog/form open→reset pattern (intentional setState-in-effect when a dialog opens to populate fields from props). Cleanest fix is key-based remount of the dialog body; tracked in BACKLOG as a focused refactor pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useCallback, useEffect } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { type ColumnDef } from '@tanstack/react-table';
|
||||
import { Pencil, Trash2, Plus } from 'lucide-react';
|
||||
|
||||
@@ -33,27 +34,29 @@ const FIELD_TYPE_LABELS: Record<string, string> = {
|
||||
|
||||
// ─── Component ────────────────────────────────────────────────────────────────
|
||||
|
||||
const FIELDS_QUERY_KEY = ['admin', 'custom-fields'] as const;
|
||||
|
||||
export function CustomFieldsManager() {
|
||||
const queryClient = useQueryClient();
|
||||
const [activeTab, setActiveTab] = useState<EntityTab>('client');
|
||||
const [fields, setFields] = useState<CustomFieldDefinition[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [formOpen, setFormOpen] = useState(false);
|
||||
const [editingField, setEditingField] = useState<CustomFieldDefinition | null>(null);
|
||||
const [deletingId, setDeletingId] = useState<string | null>(null);
|
||||
|
||||
const fetchFields = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await apiFetch<{ data: CustomFieldDefinition[] }>('/api/v1/admin/custom-fields');
|
||||
setFields(res.data);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, []);
|
||||
const { data: fields = [], isLoading: loading } = useQuery<CustomFieldDefinition[]>({
|
||||
queryKey: FIELDS_QUERY_KEY,
|
||||
queryFn: () =>
|
||||
apiFetch<{ data: CustomFieldDefinition[] }>('/api/v1/admin/custom-fields').then(
|
||||
(r) => r.data,
|
||||
),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
void fetchFields();
|
||||
}, [fetchFields]);
|
||||
const fetchFields = () => queryClient.invalidateQueries({ queryKey: FIELDS_QUERY_KEY });
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: (id: string) => apiFetch(`/api/v1/admin/custom-fields/${id}`, { method: 'DELETE' }),
|
||||
onSuccess: () => fetchFields(),
|
||||
});
|
||||
const deletingId = deleteMutation.isPending ? deleteMutation.variables : null;
|
||||
|
||||
const filteredFields = fields.filter((f) => f.entityType === activeTab);
|
||||
|
||||
@@ -67,14 +70,8 @@ export function CustomFieldsManager() {
|
||||
setFormOpen(true);
|
||||
}
|
||||
|
||||
async function handleDelete(id: string) {
|
||||
setDeletingId(id);
|
||||
try {
|
||||
await apiFetch(`/api/v1/admin/custom-fields/${id}`, { method: 'DELETE' });
|
||||
await fetchFields();
|
||||
} finally {
|
||||
setDeletingId(null);
|
||||
}
|
||||
function handleDelete(id: string) {
|
||||
deleteMutation.mutate(id);
|
||||
}
|
||||
|
||||
function getDeleteDescription(field: CustomFieldDefinition): string {
|
||||
|
||||
Reference in New Issue
Block a user