From 0c5efa3efc3cad7433c7befb34a3390ac86ba82e Mon Sep 17 00:00:00 2001 From: dwindown Date: Thu, 20 Nov 2025 12:32:06 +0700 Subject: [PATCH] feat: Phase 2 - Frontend meta fields components (Level 1) Implemented: Frontend Components for Level 1 Compatibility Created Components: - MetaFields.tsx - Generic meta field renderer - useMetaFields.ts - Hook for field registry Integrated Into: - Orders/Edit.tsx - Meta fields after OrderForm - Products/Edit.tsx - Meta fields after ProductForm Features: - Supports: text, textarea, number, date, select, checkbox - Groups fields by section - Zero coupling with specific plugins - Renders any registered fields dynamically - Read-only mode support How It Works: 1. Backend exposes meta via API (Phase 1) 2. PHP registers fields via MetaFieldsRegistry (Phase 3 - next) 3. Fields localized to window.WooNooWMetaFields 4. useMetaFields hook reads registry 5. MetaFields component renders fields 6. User edits fields 7. Form submission includes meta 8. Backend saves via update_order_meta_data() Result: - Generic, reusable components - Zero plugin-specific code - Works with any registered fields - Clean separation of concerns Next: Phase 3 - PHP MetaFieldsRegistry system --- admin-spa/src/components/MetaFields.tsx | 157 ++++++++++++++++++++++++ admin-spa/src/hooks/useMetaFields.ts | 70 +++++++++++ admin-spa/src/routes/Orders/Edit.tsx | 28 ++++- admin-spa/src/routes/Products/Edit.tsx | 30 ++++- 4 files changed, 281 insertions(+), 4 deletions(-) create mode 100644 admin-spa/src/components/MetaFields.tsx create mode 100644 admin-spa/src/hooks/useMetaFields.ts diff --git a/admin-spa/src/components/MetaFields.tsx b/admin-spa/src/components/MetaFields.tsx new file mode 100644 index 0000000..b223950 --- /dev/null +++ b/admin-spa/src/components/MetaFields.tsx @@ -0,0 +1,157 @@ +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { Checkbox } from '@/components/ui/checkbox'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select'; + +export interface MetaField { + key: string; + label: string; + type: 'text' | 'textarea' | 'number' | 'select' | 'date' | 'checkbox'; + options?: Array<{ value: string; label: string }>; + section?: string; + description?: string; + placeholder?: string; +} + +interface MetaFieldsProps { + meta: Record; + fields: MetaField[]; + onChange: (key: string, value: any) => void; + readOnly?: boolean; +} + +/** + * MetaFields Component + * + * Generic component to display/edit custom meta fields from plugins. + * Part of Level 1 compatibility - allows plugins using standard WP/WooCommerce + * meta storage to have their fields displayed automatically. + * + * Zero coupling with specific plugins - renders any registered fields. + */ +export function MetaFields({ meta, fields, onChange, readOnly = false }: MetaFieldsProps) { + // Don't render if no fields registered + if (fields.length === 0) { + return null; + } + + // Group fields by section + const sections = fields.reduce((acc, field) => { + const section = field.section || 'Additional Fields'; + if (!acc[section]) acc[section] = []; + acc[section].push(field); + return acc; + }, {} as Record); + + return ( +
+ {Object.entries(sections).map(([section, sectionFields]) => ( + + + {section} + + + {sectionFields.map((field) => ( +
+ + + {field.type === 'text' && ( + onChange(field.key, e.target.value)} + disabled={readOnly} + placeholder={field.placeholder} + /> + )} + + {field.type === 'textarea' && ( +