From a5200bbc945caebb866ae5a0a5779258f5208e97 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 14 Nov 2025 06:34:23 +0000 Subject: [PATCH] feat: Redesign bakery and user settings pages with improved UX Implemented a comprehensive redesign of the settings pages using Jobs To Be Done (JTBD) methodology to improve user experience, visual appeal, and discoverability. ## New Components - **SettingRow**: Reusable component for consistent setting layouts with support for toggles, inputs, selects, and custom content - **SettingSection**: Collapsible section component for grouping related settings with consistent styling ## Page Redesigns ### BakerySettingsPage - Redesigned information tab with better visual hierarchy using SettingSection components - Improved business hours UI with clearer day-by-day layout - Enhanced header with gradient bakery icon and status indicators - Consistent spacing and responsive design improvements - Better visual feedback for unsaved changes ### NewProfileSettingsPage - Unified design with bakery settings page - Improved personal information section with SettingSection - Better security section layout with collapsible password change form - Enhanced privacy & data management UI - Consistent icon usage and visual hierarchy ### InventorySettingsCard - Replaced checkbox with toggle switch for temperature monitoring - Progressive disclosure: temperature settings only shown when enabled - Better visual separation between setting groups - Improved responsive grid layouts - Added helpful descriptions and tooltips ## Key Improvements 1. **Visual Consistency**: Both bakery and user settings now use the same design patterns and components 2. **Scannability**: Icons, badges, and clear visual hierarchy make settings easier to scan 3. **Progressive Disclosure**: Complex settings (like temperature monitoring) only show when relevant 4. **Toggle Switches**: Binary settings use toggles instead of checkboxes for better visual feedback 5. **Responsive Design**: Improved mobile and desktop layouts with better touch targets 6. **Accessibility**: Proper ARIA labels, help text, and keyboard navigation support ## JTBD Analysis Applied - Main job: "Quickly find, understand, and change settings without mistakes" - Sub-jobs addressed: - Discovery & navigation (visual grouping, icons, clear labels) - Configuration & adjustment (toggles, inline editing, validation) - Validation & confidence (help text, descriptions, visual feedback) This redesign maintains backward compatibility while significantly improving the user experience for managing bakery and personal settings. --- .../components/ui/SettingRow/SettingRow.tsx | 180 ++++++++ .../src/components/ui/SettingRow/index.ts | 2 + .../ui/SettingSection/SettingSection.tsx | 108 +++++ .../src/components/ui/SettingSection/index.ts | 2 + frontend/src/components/ui/index.ts | 6 +- .../ajustes/cards/InventorySettingsCard.tsx | 308 +++++++------ .../settings/bakery/BakerySettingsPage.tsx | 412 +++++++++-------- .../profile/NewProfileSettingsPage.tsx | 421 +++++++++--------- 8 files changed, 868 insertions(+), 571 deletions(-) create mode 100644 frontend/src/components/ui/SettingRow/SettingRow.tsx create mode 100644 frontend/src/components/ui/SettingRow/index.ts create mode 100644 frontend/src/components/ui/SettingSection/SettingSection.tsx create mode 100644 frontend/src/components/ui/SettingSection/index.ts diff --git a/frontend/src/components/ui/SettingRow/SettingRow.tsx b/frontend/src/components/ui/SettingRow/SettingRow.tsx new file mode 100644 index 00000000..21c6889c --- /dev/null +++ b/frontend/src/components/ui/SettingRow/SettingRow.tsx @@ -0,0 +1,180 @@ +import React from 'react'; +import { HelpCircle } from 'lucide-react'; +import { Tooltip } from '../Tooltip'; +import { Toggle } from '../Toggle'; +import { Input } from '../Input'; +import { Select } from '../Select'; +import { Badge } from '../Badge'; + +export interface SettingRowProps { + label: string; + description?: string; + helpText?: string; + icon?: React.ReactNode; + badge?: { + text: string; + variant?: 'default' | 'success' | 'warning' | 'danger' | 'info'; + }; + + // For toggle type + type?: 'toggle' | 'input' | 'select' | 'custom'; + checked?: boolean; + onToggle?: (checked: boolean) => void; + + // For input type + inputType?: 'text' | 'number' | 'email' | 'tel' | 'password'; + value?: string | number; + onChange?: (e: React.ChangeEvent) => void; + placeholder?: string; + min?: number; + max?: number; + step?: number; + error?: string; + + // For select type + options?: Array<{ value: string; label: string }>; + selectValue?: string; + onSelectChange?: (value: string) => void; + + // For custom content + children?: React.ReactNode; + + // Common props + disabled?: boolean; + className?: string; + required?: boolean; +} + +const SettingRow: React.FC = ({ + label, + description, + helpText, + icon, + badge, + type = 'toggle', + checked, + onToggle, + inputType = 'text', + value, + onChange, + placeholder, + min, + max, + step, + error, + options = [], + selectValue, + onSelectChange, + children, + disabled = false, + className = '', + required = false, +}) => { + const renderControl = () => { + switch (type) { + case 'toggle': + return ( + {})} + disabled={disabled} + size="md" + /> + ); + + case 'input': + return ( +
+ +
+ ); + + case 'select': + return ( +
+ = ({
- {/* Expiration Management */} -
+ {/* Expiration Management Section */} +

Gestión de Caducidad

-
+
= ({
- {/* Temperature Monitoring */} -
-

- - Monitorización de Temperatura -

-
-
- - -
+ {/* Temperature Monitoring Section */} +
+ } + type="toggle" + checked={settings.temperature_monitoring_enabled} + onToggle={handleToggleChange('temperature_monitoring_enabled')} + disabled={disabled} + helpText="When enabled, system will monitor and alert on temperature deviations" + /> - {settings.temperature_monitoring_enabled && ( - <> - {/* Refrigeration */} -
- -
- - -
+ {settings.temperature_monitoring_enabled && ( + <> + {/* Refrigeration Settings */} +
+
+ Refrigeración (°C) +
+
+ +
+
- {/* Freezer */} -
- -
- - -
+ {/* Freezer Settings */} +
+
+ Congelador (°C) +
+
+ +
+
- {/* Room Temperature */} -
- -
- - -
+ {/* Room Temperature Settings */} +
+
+ Temperatura Ambiente (°C) +
+
+ +
+
- {/* Alert Timing */} -
-
- - Alertas de Desviación -
-
- - -
+ {/* Alert Timing */} +
+
+ + Alertas de Desviación +
+
+ +
- - )} -
+
+ + )}
- + ); }; diff --git a/frontend/src/pages/app/settings/bakery/BakerySettingsPage.tsx b/frontend/src/pages/app/settings/bakery/BakerySettingsPage.tsx index 44ff7ba2..671b7c52 100644 --- a/frontend/src/pages/app/settings/bakery/BakerySettingsPage.tsx +++ b/frontend/src/pages/app/settings/bakery/BakerySettingsPage.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { Store, MapPin, Clock, Settings as SettingsIcon, Save, X, AlertCircle, Loader, Bell } from 'lucide-react'; -import { Button, Card, Input, Select } from '../../../../components/ui'; +import { Store, MapPin, Clock, Settings as SettingsIcon, Save, X, AlertCircle, Loader, Bell, Globe, Mail, Phone, Building2, CreditCard } from 'lucide-react'; +import { Button, Card, Input, Select, SettingSection, SettingRow } from '../../../../components/ui'; import { Tabs, TabsList, TabsTrigger, TabsContent } from '../../../../components/ui/Tabs'; import { PageHeader } from '../../../../components/layout'; import { showToast } from '../../../../utils/toast'; @@ -51,7 +51,7 @@ interface BusinessHours { const BakerySettingsPage: React.FC = () => { const { t } = useTranslation('settings'); - + const currentTenant = useCurrentTenant(); const { loadUserTenants, setCurrentTenant } = useTenantActions(); const tenantId = currentTenant?.id || ''; @@ -359,18 +359,24 @@ const BakerySettingsPage: React.FC = () => { {/* Bakery Header Card */}
-
+
{config.name.charAt(0) || 'B'}

{config.name || t('bakery.information.fields.name')}

-

{config.email}

-

{config.address}, {config.city}

+

+ + {config.email} +

+

+ + {config.address}, {config.city} +

{hasUnsavedChanges && ( -
+
{t('bakery.unsaved_changes')}
@@ -403,230 +409,222 @@ const BakerySettingsPage: React.FC = () => {
{/* General Information */} - -

- - {t('bakery.information.general_section')} -

+ } + > +
+
+ } + required + /> -
- } - /> + } + required + /> - } - /> + } + /> - } - /> + } + /> +
- +
+ +