🆙 Cleanup

This commit is contained in:
duckietm
2026-03-24 11:56:51 +01:00
parent 47e07a5714
commit df1437c488
13 changed files with 506 additions and 685 deletions
+135 -69
View File
@@ -1,7 +1,4 @@
import { FurniEditorBySpriteComposer, FurniEditorCreateComposer, FurniEditorDeleteComposer, FurniEditorDetailComposer, FurniEditorDetailEvent as FurniEditorDetailMsgEvent, FurniEditorInteractionsComposer, FurniEditorInteractionsEvent as FurniEditorInteractionsMsgEvent, FurniEditorResultEvent as FurniEditorResultMsgEvent, FurniEditorSearchComposer, FurniEditorSearchEvent as FurniEditorSearchMsgEvent, FurniEditorUpdateComposer } from '@nitrots/nitro-renderer';
import { useCallback, useState } from 'react';
import { SendMessageComposer } from '../../api';
import { useMessageEvent } from '../events';
export interface FurniItem
{
@@ -49,6 +46,18 @@ export interface CatalogRef
pageName: string;
}
const API_BASE = '/api/admin/furni-editor';
async function apiFetch<T>(url: string, options?: RequestInit): Promise<T>
{
const res = await fetch(url, { credentials: 'include', ...options });
const data = await res.json();
if(!res.ok || data.error) throw new Error(data.error || 'API error');
return data;
}
export const useFurniEditor = () =>
{
const [ items, setItems ] = useState<FurniItem[]>([]);
@@ -60,114 +69,171 @@ export const useFurniEditor = () =>
const [ catalogItems, setCatalogItems ] = useState<CatalogRef[]>([]);
const [ interactions, setInteractions ] = useState<string[]>([]);
const [ furniDataEntry, setFurniDataEntry ] = useState<Record<string, unknown> | null>(null);
const [ lastResult, setLastResult ] = useState<{ success: boolean; message: string; id: number } | null>(null);
const clearError = useCallback(() => setError(null), []);
// Listen for search results
useMessageEvent(FurniEditorSearchMsgEvent, (event: any) =>
const searchItems = useCallback(async (query: string, type: string, pg: number) =>
{
const parser = event.getParser();
setItems(parser.items);
setTotal(parser.total);
setPage(parser.page);
setLoading(false);
});
// Listen for detail results
useMessageEvent(FurniEditorDetailMsgEvent, (event: any) =>
{
const parser = event.getParser();
setSelectedItem(parser.item as FurniDetail);
setCatalogItems(parser.catalogItems as CatalogRef[]);
setLoading(true);
setError(null);
try
{
setFurniDataEntry(parser.furniDataJson ? JSON.parse(parser.furniDataJson) : null);
const params = new URLSearchParams({ q: query, limit: '20', page: String(pg) });
if(type) params.set('type', type);
const data = await apiFetch<{ items: FurniItem[]; total: number; page: number }>(`${ API_BASE }?${ params }`);
setItems(data.items);
setTotal(data.total);
setPage(data.page);
}
catch
catch(e: any)
{
setFurniDataEntry(null);
setError(e.message);
}
setLoading(false);
});
// Listen for interactions results
useMessageEvent(FurniEditorInteractionsMsgEvent, (event: any) =>
{
const parser = event.getParser();
setInteractions(parser.interactions);
});
// Listen for operation results (update/create/delete)
useMessageEvent(FurniEditorResultMsgEvent, (event: any) =>
{
const parser = event.getParser();
setLastResult({ success: parser.success, message: parser.message, id: parser.id });
setLoading(false);
if(!parser.success)
finally
{
setError(parser.message);
setLoading(false);
}
});
}, []);
const searchItems = useCallback((query: string, type: string, pg: number) =>
const loadDetail = useCallback(async (id: number): Promise<boolean> =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorSearchComposer(query, type, pg));
try
{
const data = await apiFetch<{ item: FurniDetail; catalogItems: CatalogRef[]; furniDataEntry: Record<string, unknown> | null }>(`${ API_BASE }/detail?id=${ id }`);
setSelectedItem(data.item);
setCatalogItems(data.catalogItems);
setFurniDataEntry(data.furniDataEntry);
return true;
}
catch(e: any)
{
setError(e.message);
return false;
}
finally
{
setLoading(false);
}
}, []);
const loadDetail = useCallback((id: number) =>
const updateItem = useCallback(async (id: number, fields: Record<string, unknown>) =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorDetailComposer(id));
try
{
await apiFetch(`${ API_BASE }/update?id=${ id }`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fields)
});
return true;
}
catch(e: any)
{
setError(e.message);
return false;
}
finally
{
setLoading(false);
}
}, []);
const loadBySpriteId = useCallback((spriteId: number) =>
const createItem = useCallback(async (fields: Record<string, unknown>) =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorBySpriteComposer(spriteId));
try
{
const data = await apiFetch<{ id: number }>(`${ API_BASE }`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fields)
});
return data.id;
}
catch(e: any)
{
setError(e.message);
return null;
}
finally
{
setLoading(false);
}
}, []);
const updateItem = useCallback((id: number, fields: Record<string, unknown>) =>
const deleteItem = useCallback(async (id: number) =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorUpdateComposer(id, JSON.stringify(fields)));
try
{
await apiFetch(`${ API_BASE }/delete?id=${ id }`, { method: 'POST' });
return true;
}
catch(e: any)
{
setError(e.message);
return false;
}
finally
{
setLoading(false);
}
}, []);
const createItem = useCallback((fields: Record<string, unknown>) =>
const loadInteractions = useCallback(async () =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorCreateComposer(JSON.stringify(fields)));
try
{
const data = await apiFetch<{ interactions: Array<string | { name: string }> }>(`${ API_BASE }/interactions`);
setInteractions(data.interactions.map(i => typeof i === 'string' ? i : i.name));
}
catch {}
}, []);
const deleteItem = useCallback((id: number) =>
const loadBySpriteId = useCallback(async (spriteId: number): Promise<boolean> =>
{
setLoading(true);
setError(null);
SendMessageComposer(new FurniEditorDeleteComposer(id));
}, []);
try
{
const data = await apiFetch<{ id: number }>(`${ API_BASE }/by-sprite?spriteId=${ spriteId }`);
const loadInteractions = useCallback(() =>
{
SendMessageComposer(new FurniEditorInteractionsComposer());
}, []);
return await loadDetail(data.id);
}
catch(e: any)
{
setError(e.message);
return false;
}
}, [ loadDetail ]);
return {
items, total, page, loading, error, clearError,
selectedItem, setSelectedItem, catalogItems, furniDataEntry,
interactions, lastResult,
interactions,
searchItems, loadDetail, loadBySpriteId, updateItem, createItem, deleteItem, loadInteractions
};
};