From ee89ebcd4d81c26a90512e82a83834f72b436550 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Tue, 3 Feb 2026 16:36:37 +0000 Subject: [PATCH] refactor: rename photo pack settings to item settings in modal and styles --- .../options/sections/PhotoPackSettings.jsx | 235 ------------------ .../components/Modals/ItemSettingsModal.jsx | 40 +-- .../components/Modals/ItemSettingsModal.scss | 42 ++-- 3 files changed, 41 insertions(+), 276 deletions(-) delete mode 100644 src/features/background/options/sections/PhotoPackSettings.jsx diff --git a/src/features/background/options/sections/PhotoPackSettings.jsx b/src/features/background/options/sections/PhotoPackSettings.jsx deleted file mode 100644 index bf26b08f..00000000 --- a/src/features/background/options/sections/PhotoPackSettings.jsx +++ /dev/null @@ -1,235 +0,0 @@ -import { useState, useEffect, useCallback } from 'react'; -import variables from 'config/variables'; -import EventBus from 'utils/eventbus'; -import { Dropdown, Text, Switch, Slider, ChipSelect } from 'components/Form/Settings'; -import { Row, Content, Action } from 'components/Layout/Settings/Item'; -import { Button } from 'components/Elements'; -import { Section } from 'components/Layout/Settings'; -import { refreshAPIPackCache } from 'features/background/api/photoPackAPI'; -import { MdRefresh, MdWarning, MdExpandMore, MdExpandLess } from 'react-icons/md'; - -const PhotoPackSettings = ({ pack }) => { - const [settings, setSettings] = useState(() => { - const saved = localStorage.getItem(`photopack_settings_${pack.id}`); - return saved ? JSON.parse(saved) : {}; - }); - - const [dynamicOptions, setDynamicOptions] = useState({}); - const [isRefreshing, setIsRefreshing] = useState(false); - const [validationErrors, setValidationErrors] = useState([]); - const [isExpanded, setIsExpanded] = useState(false); - - const validateSettings = useCallback(() => { - const errors = []; - pack.settings_schema.forEach((field) => { - if (field.required && !settings[field.key]) { - errors.push(`${field.label} is required`); - } - }); - setValidationErrors(errors); - - // Update api_packs_ready list - const apiPacksReady = JSON.parse(localStorage.getItem('api_packs_ready') || '[]'); - const isReady = errors.length === 0; - const isInList = apiPacksReady.includes(pack.id); - - if (isReady && !isInList) { - apiPacksReady.push(pack.id); - localStorage.setItem('api_packs_ready', JSON.stringify(apiPacksReady)); - } else if (!isReady && isInList) { - const filtered = apiPacksReady.filter((id) => id !== pack.id); - localStorage.setItem('api_packs_ready', JSON.stringify(filtered)); - } - }, [pack.id, pack.settings_schema, settings]); - - const loadDynamicOptions = async (field) => { - if (field.options_source === 'api:categories') { - try { - const response = await fetch(`${variables.constants.API_URL}/images/categories`); - const categories = await response.json(); - setDynamicOptions((prev) => ({ - ...prev, - [field.key]: categories, - })); - } catch (error) { - console.error('Failed to load categories:', error); - } - } - }; - - // Load dynamic options (e.g., categories from API) - useEffect(() => { - if (!pack.settings_schema || pack.settings_schema.length === 0) { - return; - } - pack.settings_schema.forEach((field) => { - if (field.dynamic && field.options_source) { - loadDynamicOptions(field); - } - }); - }, [pack.id, pack.settings_schema]); - - // Validate settings - useEffect(() => { - if (!pack.settings_schema || pack.settings_schema.length === 0) { - return; - } - validateSettings(); - }, [settings, validateSettings, pack.settings_schema]); - - const handleSettingChange = (key, value, secure = false) => { - const processedValue = secure ? btoa(value) : value; - const newSettings = { ...settings, [key]: processedValue }; - setSettings(newSettings); - localStorage.setItem(`photopack_settings_${pack.id}`, JSON.stringify(newSettings)); - }; - - const handleManualRefresh = async () => { - setIsRefreshing(true); - await refreshAPIPackCache(pack.id); - setIsRefreshing(false); - // Trigger background refresh - EventBus.emit('refresh', 'background'); - }; - - const renderField = (field) => { - const value = - field.secure && settings[field.key] - ? atob(settings[field.key]) - : settings[field.key] || field.default; - - switch (field.type) { - case 'dropdown': { - const dropdownItems = field.options.map((opt) => ({ - value: opt.value, - text: opt.label, - })); - return ( - handleSettingChange(field.key, newValue)} - /> - ); - } - - case 'chipselect': { - const options = field.dynamic ? dynamicOptions[field.key] || [] : field.options; - return ( - handleSettingChange(field.key, newValue)} - /> - ); - } - - case 'text': - return ( - handleSettingChange(field.key, e.target.value, field.secure)} - subtitle={field.help_text} - /> - ); - - case 'switch': - return ( - handleSettingChange(field.key, newValue)} - /> - ); - - case 'slider': - return ( - handleSettingChange(field.key, newValue)} - /> - ); - - default: - return null; - } - }; - - if (!pack.settings_schema || pack.settings_schema.length === 0) { - return null; - } - - return ( - <> -
setIsExpanded(!isExpanded)} - > - {isExpanded ? : } -
- - {isExpanded && ( - <> - - - - -
+
{hasSettings && ( <> {validationErrors.length > 0 && ( -
+
Configuration incomplete: {validationErrors.join(', ')}
)} -
+
{pack.settings_schema.map((field) => ( -
+
{renderField(field)}
))}
{isPhotoPack && ( -
+