fix: PHP Fatal Error and attribute input UX

Critical Fixes:

1.  PHP Fatal Error - FIXED
   Problem: call_user_func() error - Permissions::check_admin does not exist
   Cause: Method name mismatch in ProductsController.php
   Solution: Changed all 8 occurrences from:
     'permission_callback' => [Permissions::class, 'check_admin']
   To:
     'permission_callback' => [Permissions::class, 'check_admin_permission']

   Affected routes:
   - GET /products
   - GET /products/:id
   - POST /products
   - PUT /products/:id
   - DELETE /products/:id
   - GET /products/categories
   - GET /products/tags
   - GET /products/attributes

2.  Attribute Options Input - FIXED
   Problem: Cannot type anything after first word (cursor jumps)
   Cause: Controlled input with immediate state update on onChange
   Solution: Changed to uncontrolled input with onBlur

   Changes:
   - value → defaultValue (uncontrolled)
   - onChange → onBlur (update on blur)
   - Added key prop for proper re-rendering
   - Added onKeyDown for Enter key support
   - Updated help text: "press Enter or click away"

   Now you can:
    Type: Red, Blue, Green (naturally!)
    Type: Red | Blue | Green (pipe works too!)
    Press Enter to save
    Click away to save
    No cursor jumping!

Result:
- Products index page loads without PHP error
- Attribute options input works naturally
- Both comma and pipe separators supported
This commit is contained in:
dwindown
2025-11-19 23:04:58 +07:00
parent d13a356331
commit 7bab3d809d
2 changed files with 18 additions and 11 deletions

View File

@@ -136,8 +136,9 @@ export function VariationsTab({
<div>
<Label>{__('Options')}</Label>
<Input
value={attr.options.join(', ')}
onChange={(e) => {
key={`options-${index}-${attr.options.length}`}
defaultValue={attr.options.join(', ')}
onBlur={(e) => {
const input = e.target.value;
// Split by comma or pipe, trim whitespace
const options = input
@@ -146,11 +147,17 @@ export function VariationsTab({
.filter(Boolean);
updateAttribute(index, 'options', options);
}}
onKeyDown={(e) => {
// Update on Enter key
if (e.key === 'Enter') {
e.currentTarget.blur();
}
}}
placeholder={__('Red, Blue, Green (comma or pipe separated)')}
className="mt-1.5"
/>
<p className="text-xs text-muted-foreground mt-1">
{__('Type naturally: Red, Blue, Green (comma or | works)')}
{__('Type naturally: Red, Blue, Green (press Enter or click away)')}
</p>
</div>
</div>