feat: Stock infinity symbol, sale price display, rich text editor, inline create categories/tags

Fixed 4 major UX issues:

1. Stock Column - Show Infinity Symbol
   Problem: Stock shows badge even when not managed
   Solution:
   - Check manage_stock flag
   - If true: Show StockBadge with quantity
   - If false: Show ∞ (infinity symbol) for unlimited

   Result: Clear visual for unlimited stock

2. Type Column & Price Display
   Problem: Type column empty, price ignores sale price
   Solution:
   - Type: Show badge with product.type (simple, variable, etc.)
   - Price: Respect sale price hierarchy:
     1. price_html (WooCommerce formatted)
     2. sale_price (show strikethrough regular + green sale)
     3. regular_price (normal display)
     4. — (dash for no price)

   Result:
   - Type visible with badge styling
   - Sale prices show with strikethrough
   - Clear visual hierarchy

3. Rich Text Editor for Description
   Problem: Description shows raw HTML in textarea
   Solution:
   - Created RichTextEditor component with Tiptap
   - Toolbar: Bold, Italic, H2, Lists, Quote, Undo/Redo
   - Integrated into GeneralTab

   Features:
   - WYSIWYG editing
   - Keyboard shortcuts
   - Clean toolbar UI
   - Saves as HTML

   Result: Professional rich text editing experience

4. Inline Create Categories & Tags
   Problem: Cannot create new categories/tags in product form
   Solution:
   - Added input + "Add" button above each list
   - Press Enter or click Add to create
   - Auto-selects newly created item
   - Shows loading state
   - Toast notifications

   Result:
   - No need to leave product form
   - Seamless workflow
   - Better UX

Files Changed:
- index.tsx: Stock ∞, sale price display, type badge
- GeneralTab.tsx: RichTextEditor integration
- OrganizationTab.tsx: Inline create UI
- RichTextEditor.tsx: New reusable component

Note: Variation attribute value issue (screenshot 1) needs API data format investigation
This commit is contained in:
dwindown
2025-11-20 00:00:06 +07:00
parent 875213f7ec
commit c686777c7c
4 changed files with 252 additions and 15 deletions

View File

@@ -381,18 +381,31 @@ export default function Products() {
</td>
<td className="p-3 font-mono text-sm">{product.sku || '—'}</td>
<td className="p-3">
<StockBadge value={product.stock_status} quantity={product.manage_stock ? product.stock_quantity : undefined} />
{product.manage_stock ? (
<StockBadge value={product.stock_status} quantity={product.stock_quantity} />
) : (
<span className="text-sm text-muted-foreground"></span>
)}
</td>
<td className="p-3">
{product.price_html ? (
<span dangerouslySetInnerHTML={{ __html: product.price_html }} />
) : product.sale_price ? (
<span className="space-x-1">
<span className="line-through text-muted-foreground text-sm">{formatMoney(product.regular_price)}</span>
<span className="text-emerald-600 font-medium">{formatMoney(product.sale_price)}</span>
</span>
) : product.regular_price ? (
<span>{formatMoney(product.regular_price)}</span>
) : (
<span className="text-muted-foreground"></span>
)}
</td>
<td className="p-3 text-sm capitalize">{product.type || '—'}</td>
<td className="p-3 text-sm">
<span className="capitalize px-2 py-1 rounded-md bg-muted text-muted-foreground text-xs">
{product.type || 'simple'}
</span>
</td>
<td className="p-3 text-right">
<Link to={`/products/${product.id}/edit`} className="text-sm text-primary hover:underline">
{__('Edit')}