= props
onClick={ () => setDropdownOpen(!dropdownOpen) }>
{ dropdownOpen ? `${LocalizeText('widget.furni.present.close')} Buildtools` : `${LocalizeText('navigator.roomsettings.doormode.open')} Buildtools` }
-
{ dropdownOpen &&
{ /* Left panel: position + rotation */ }
diff --git a/src/components/toolbar/ToolbarView.tsx b/src/components/toolbar/ToolbarView.tsx
index fbb5ae8..ea9fb16 100644
--- a/src/components/toolbar/ToolbarView.tsx
+++ b/src/components/toolbar/ToolbarView.tsx
@@ -96,8 +96,6 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
CreateLinkEvent('camera/toggle') } /> }
{ isMod &&
CreateLinkEvent('mod-tools/toggle') } /> }
- { isMod &&
- CreateLinkEvent('furni-editor/toggle') } /> }
diff --git a/src/hooks/furni-editor/index.ts b/src/hooks/furni-editor/index.ts
deleted file mode 100644
index 47ce6ef..0000000
--- a/src/hooks/furni-editor/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './useFurniEditor';
diff --git a/src/hooks/furni-editor/useFurniEditor.ts b/src/hooks/furni-editor/useFurniEditor.ts
deleted file mode 100644
index e4258e5..0000000
--- a/src/hooks/furni-editor/useFurniEditor.ts
+++ /dev/null
@@ -1,239 +0,0 @@
-import { useCallback, useState } from 'react';
-
-export interface FurniItem
-{
- id: number;
- spriteId: number;
- itemName: string;
- publicName: string;
- type: string;
- width: number;
- length: number;
- stackHeight: number;
- allowStack: boolean;
- allowWalk: boolean;
- allowSit: boolean;
- allowLay: boolean;
- interactionType: string;
- interactionModesCount: number;
-}
-
-export interface FurniDetail extends FurniItem
-{
- allowGift: boolean;
- allowTrade: boolean;
- allowRecycle: boolean;
- allowMarketplaceSell: boolean;
- allowInventoryStack: boolean;
- vendingIds: string;
- customparams: string;
- effectIdMale: number;
- effectIdFemale: number;
- clothingOnWalk: string;
- multiheight: string;
- description: string;
- usageCount: number;
-}
-
-export interface CatalogRef
-{
- id: number;
- catalogName: string;
- costCredits: number;
- costPoints: number;
- pointsType: number;
- pageId: number;
- pageName: string;
-}
-
-const API_BASE = '/api/admin/furni-editor';
-
-async function apiFetch(url: string, options?: RequestInit): Promise
-{
- 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([]);
- const [ total, setTotal ] = useState(0);
- const [ page, setPage ] = useState(1);
- const [ loading, setLoading ] = useState(false);
- const [ error, setError ] = useState(null);
- const [ selectedItem, setSelectedItem ] = useState(null);
- const [ catalogItems, setCatalogItems ] = useState([]);
- const [ interactions, setInteractions ] = useState([]);
- const [ furniDataEntry, setFurniDataEntry ] = useState | null>(null);
-
- const clearError = useCallback(() => setError(null), []);
-
- const searchItems = useCallback(async (query: string, type: string, pg: number) =>
- {
- setLoading(true);
- setError(null);
-
- try
- {
- 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(e: any)
- {
- setError(e.message);
- }
- finally
- {
- setLoading(false);
- }
- }, []);
-
- const loadDetail = useCallback(async (id: number): Promise =>
- {
- setLoading(true);
- setError(null);
-
- try
- {
- const data = await apiFetch<{ item: FurniDetail; catalogItems: CatalogRef[]; furniDataEntry: Record | 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 updateItem = useCallback(async (id: number, fields: Record) =>
- {
- setLoading(true);
- setError(null);
-
- 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 createItem = useCallback(async (fields: Record) =>
- {
- setLoading(true);
- setError(null);
-
- 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 deleteItem = useCallback(async (id: number) =>
- {
- setLoading(true);
- setError(null);
-
- try
- {
- await apiFetch(`${ API_BASE }/delete?id=${ id }`, { method: 'POST' });
-
- return true;
- }
- catch(e: any)
- {
- setError(e.message);
-
- return false;
- }
- finally
- {
- setLoading(false);
- }
- }, []);
-
- const loadInteractions = useCallback(async () =>
- {
- try
- {
- const data = await apiFetch<{ interactions: Array }>(`${ API_BASE }/interactions`);
-
- setInteractions(data.interactions.map(i => typeof i === 'string' ? i : i.name));
- }
- catch {}
- }, []);
-
- const loadBySpriteId = useCallback(async (spriteId: number): Promise =>
- {
- try
- {
- const data = await apiFetch<{ id: number }>(`${ API_BASE }/by-sprite?spriteId=${ spriteId }`);
-
- 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,
- searchItems, loadDetail, loadBySpriteId, updateItem, createItem, deleteItem, loadInteractions
- };
-};