feat(inventory): add list/grid view modes with individual item management
Implemented comprehensive individual item management system with toggleable view modes: - Added item parsing utilities (parseItems/serializeItems) for comma-separated strings - Implemented list view (full-width rows) and grid view (responsive cards) - Added view mode toggle buttons per inventory section (onPerson, stored, assets) - View preferences persist per-section in settings - Replaced text-based editing with add/remove item controls - Added inline forms for adding new items (matching existing UX patterns) - Applied theme accent color (--rpg-highlight) to all outlines and active states - Updated all tabs (desktop/mobile/inventory subtabs) with theme-consistent styling Technical improvements: - Created itemParser.js utility module for item string manipulation - Enhanced inventory rendering with conditional list/grid HTML generation - Added switchViewMode handler with settings persistence - Fixed [object Object] display bug with comprehensive type checking - All buttons and items now use transparent backgrounds with theme accent borders
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Item Parser Module
|
||||
* Utilities for parsing item strings into arrays and vice versa
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses a comma-separated item string into an array of trimmed item names.
|
||||
* Filters out empty strings and handles "None" gracefully.
|
||||
*
|
||||
* @param {string} itemString - Comma-separated items (e.g., "Sword, Shield, 3x Potions")
|
||||
* @returns {string[]} Array of item names, or empty array if none
|
||||
*
|
||||
* @example
|
||||
* parseItems("Sword, Shield, 3x Potions") // ["Sword", "Shield", "3x Potions"]
|
||||
* parseItems("None") // []
|
||||
* parseItems("") // []
|
||||
* parseItems(null) // []
|
||||
*/
|
||||
export function parseItems(itemString) {
|
||||
// Handle null/undefined/non-string
|
||||
if (!itemString || typeof itemString !== 'string') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Trim and check for "None" (case-insensitive)
|
||||
const trimmed = itemString.trim();
|
||||
if (trimmed === '' || trimmed.toLowerCase() === 'none') {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Split by comma, trim each item, filter empties
|
||||
return itemString
|
||||
.split(',')
|
||||
.map(item => item.trim())
|
||||
.filter(item => item !== '' && item.toLowerCase() !== 'none');
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an array of items back into a comma-separated string.
|
||||
* Returns "None" for empty arrays.
|
||||
*
|
||||
* @param {string[]} itemArray - Array of item names
|
||||
* @returns {string} Comma-separated string, or "None" if empty
|
||||
*
|
||||
* @example
|
||||
* serializeItems(["Sword", "Shield", "3x Potions"]) // "Sword, Shield, 3x Potions"
|
||||
* serializeItems([]) // "None"
|
||||
* serializeItems(["Sword"]) // "Sword"
|
||||
*/
|
||||
export function serializeItems(itemArray) {
|
||||
// Handle null/undefined/non-array
|
||||
if (!itemArray || !Array.isArray(itemArray)) {
|
||||
return 'None';
|
||||
}
|
||||
|
||||
// Filter out empty strings and trim
|
||||
const cleaned = itemArray
|
||||
.filter(item => item && typeof item === 'string' && item.trim() !== '')
|
||||
.map(item => item.trim());
|
||||
|
||||
// Return "None" if array is empty after cleaning
|
||||
if (cleaned.length === 0) {
|
||||
return 'None';
|
||||
}
|
||||
|
||||
// Join with comma and space
|
||||
return cleaned.join(', ');
|
||||
}
|
||||
Reference in New Issue
Block a user