Refactor SystemView to display signatures in categorized, collapsible sections. Implement user preference persistence for category visibility using local storage.
131 lines
3.7 KiB
TypeScript
131 lines
3.7 KiB
TypeScript
|
|
import { useState, useEffect, useMemo } from 'react';
|
|
import { SigviewRecord as Signature } from "@/lib/pbtypes";
|
|
|
|
export interface SignatureCategory {
|
|
id: string;
|
|
name: string;
|
|
signatures: Signature[];
|
|
isVisible: boolean;
|
|
}
|
|
|
|
const CATEGORY_PREFERENCES_KEY = 'signature-category-preferences';
|
|
|
|
export const categorizeSignatures = (signatures: Signature[]): Record<string, Signature[]> => {
|
|
const categories: Record<string, Signature[]> = {
|
|
unknown: [],
|
|
combat: [],
|
|
data_relic: [],
|
|
gas: [],
|
|
ore: [],
|
|
wormhole: []
|
|
};
|
|
|
|
signatures.forEach(signature => {
|
|
const type = signature.type?.toLowerCase() || '';
|
|
const name = signature.signame?.toLowerCase() || '';
|
|
|
|
if (!type || type === '') {
|
|
categories.unknown.push(signature);
|
|
} else if (type.includes('combat') || type.includes('den') || type.includes('rally')) {
|
|
categories.combat.push(signature);
|
|
} else if (type.includes('data') || type.includes('relic') || type.includes('exploration')) {
|
|
categories.data_relic.push(signature);
|
|
} else if (type.includes('gas') || name.includes('gas')) {
|
|
categories.gas.push(signature);
|
|
} else if (type.includes('ore') || type.includes('mining') || name.includes('ore')) {
|
|
categories.ore.push(signature);
|
|
} else if (type.includes('wormhole') || name.includes('wormhole') || type.includes('k162')) {
|
|
categories.wormhole.push(signature);
|
|
} else {
|
|
categories.unknown.push(signature);
|
|
}
|
|
});
|
|
|
|
return categories;
|
|
};
|
|
|
|
export const useSignatureCategories = (signatures: Signature[]) => {
|
|
const [categoryVisibility, setCategoryVisibility] = useState<Record<string, boolean>>({
|
|
unknown: true,
|
|
combat: true,
|
|
data_relic: true,
|
|
gas: true,
|
|
ore: true,
|
|
wormhole: true
|
|
});
|
|
|
|
// Load preferences from localStorage on mount
|
|
useEffect(() => {
|
|
const saved = localStorage.getItem(CATEGORY_PREFERENCES_KEY);
|
|
if (saved) {
|
|
try {
|
|
const preferences = JSON.parse(saved);
|
|
setCategoryVisibility(prev => ({ ...prev, ...preferences }));
|
|
} catch (error) {
|
|
console.error('Failed to parse category preferences:', error);
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
// Save preferences to localStorage when they change
|
|
useEffect(() => {
|
|
localStorage.setItem(CATEGORY_PREFERENCES_KEY, JSON.stringify(categoryVisibility));
|
|
}, [categoryVisibility]);
|
|
|
|
const categories = useMemo(() => {
|
|
const categorized = categorizeSignatures(signatures);
|
|
|
|
return [
|
|
{
|
|
id: 'unknown',
|
|
name: 'Unknown Sites',
|
|
signatures: categorized.unknown,
|
|
isVisible: categoryVisibility.unknown
|
|
},
|
|
{
|
|
id: 'combat',
|
|
name: 'Combat Sites',
|
|
signatures: categorized.combat,
|
|
isVisible: categoryVisibility.combat
|
|
},
|
|
{
|
|
id: 'data_relic',
|
|
name: 'Data/Relic Sites',
|
|
signatures: categorized.data_relic,
|
|
isVisible: categoryVisibility.data_relic
|
|
},
|
|
{
|
|
id: 'gas',
|
|
name: 'Gas Sites',
|
|
signatures: categorized.gas,
|
|
isVisible: categoryVisibility.gas
|
|
},
|
|
{
|
|
id: 'ore',
|
|
name: 'Ore Sites',
|
|
signatures: categorized.ore,
|
|
isVisible: categoryVisibility.ore
|
|
},
|
|
{
|
|
id: 'wormhole',
|
|
name: 'Wormholes',
|
|
signatures: categorized.wormhole,
|
|
isVisible: categoryVisibility.wormhole
|
|
}
|
|
].filter(category => category.signatures.length > 0);
|
|
}, [signatures, categoryVisibility]);
|
|
|
|
const toggleCategoryVisibility = (categoryId: string) => {
|
|
setCategoryVisibility(prev => ({
|
|
...prev,
|
|
[categoryId]: !prev[categoryId]
|
|
}));
|
|
};
|
|
|
|
return {
|
|
categories,
|
|
toggleCategoryVisibility
|
|
};
|
|
};
|