@happyvertical/smrt-products 0.34.4 → 0.34.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/chunks/{ProductForm-p4-xbubZ.js → ProductForm-CukMCDEN.js} +73 -39
- package/dist/lib/chunks/ProductForm-CukMCDEN.js.map +1 -0
- package/dist/lib/components.js +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/lib/components/ProductCard.svelte +6 -35
- package/dist/lib/lib/components/ProductCard.svelte.d.ts.map +1 -1
- package/dist/lib/lib/components/ProductForm.svelte +6 -40
- package/dist/lib/lib/components/ProductForm.svelte.d.ts.map +1 -1
- package/dist/lib/lib/components/auto-generated/AutoForm.svelte +5 -34
- package/dist/lib/lib/components/auto-generated/AutoForm.svelte.d.ts.map +1 -1
- package/dist/lib/lib/features/ProductCatalog.svelte +14 -30
- package/dist/lib/lib/features/ProductCatalog.svelte.d.ts.map +1 -1
- package/dist/lib/manifest.json +2 -2
- package/dist/lib/smrt-knowledge.json +4 -4
- package/dist/lib/smrt-products.css +0 -65
- package/package.json +8 -7
- package/dist/lib/chunks/ProductForm-p4-xbubZ.js.map +0 -1
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import "svelte/internal/disclose-version";
|
|
2
2
|
import * as $ from "svelte/internal/client";
|
|
3
|
+
import { Button } from "@happyvertical/smrt-ui/ui";
|
|
3
4
|
import { defineMessages, useI18n } from "@happyvertical/smrt-ui/i18n";
|
|
4
5
|
var root_1$1 = $.from_html(`<div class="product-manufacturer svelte-11ja2cl"> </div>`);
|
|
5
6
|
var root_2$1 = $.from_html(`<div class="product-model svelte-11ja2cl"> </div>`);
|
|
6
|
-
var root_3
|
|
7
|
+
var root_3 = $.from_html(`<p class="product-description svelte-11ja2cl"> </p>`);
|
|
7
8
|
var root_4 = $.from_html(`<div class="product-category svelte-11ja2cl"> </div>`);
|
|
8
9
|
var root_6 = $.from_html(`<span class="tag svelte-11ja2cl"> </span>`);
|
|
9
10
|
var root_5 = $.from_html(`<div class="product-tags svelte-11ja2cl"></div>`);
|
|
10
|
-
var root_7 = $.from_html(`<button type="button" class="edit-btn svelte-11ja2cl">Edit</button>`);
|
|
11
|
-
var root_8 = $.from_html(`<button type="button" class="delete-btn svelte-11ja2cl">Delete</button>`);
|
|
12
11
|
var root$1 = $.from_html(`<div class="product-card svelte-11ja2cl"><div class="product-header svelte-11ja2cl"><h3 class="product-name svelte-11ja2cl"> </h3> <!></div> <!> <!> <div class="product-meta svelte-11ja2cl"><!> <!></div> <div class="product-actions svelte-11ja2cl"><!> <!></div></div>`);
|
|
13
12
|
function ProductCard($$anchor, $$props) {
|
|
14
13
|
$.push($$props, true);
|
|
@@ -47,7 +46,7 @@ function ProductCard($$anchor, $$props) {
|
|
|
47
46
|
var node_2 = $.sibling(node_1, 2);
|
|
48
47
|
{
|
|
49
48
|
var consequent_2 = ($$anchor2) => {
|
|
50
|
-
var p = root_3
|
|
49
|
+
var p = root_3();
|
|
51
50
|
var text_3 = $.child(p, true);
|
|
52
51
|
$.reset(p);
|
|
53
52
|
$.template_effect(() => $.set_text(text_3, $$props.product.description));
|
|
@@ -94,9 +93,18 @@ function ProductCard($$anchor, $$props) {
|
|
|
94
93
|
var node_5 = $.child(div_7);
|
|
95
94
|
{
|
|
96
95
|
var consequent_5 = ($$anchor2) => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
Button($$anchor2, {
|
|
97
|
+
type: "button",
|
|
98
|
+
variant: "secondary",
|
|
99
|
+
size: "sm",
|
|
100
|
+
onclick: () => $$props.onEdit?.($$props.product),
|
|
101
|
+
children: ($$anchor3, $$slotProps) => {
|
|
102
|
+
$.next();
|
|
103
|
+
var text_6 = $.text("Edit");
|
|
104
|
+
$.append($$anchor3, text_6);
|
|
105
|
+
},
|
|
106
|
+
$$slots: { default: true }
|
|
107
|
+
});
|
|
100
108
|
};
|
|
101
109
|
$.if(node_5, ($$render) => {
|
|
102
110
|
if ($$props.onEdit) $$render(consequent_5);
|
|
@@ -105,9 +113,18 @@ function ProductCard($$anchor, $$props) {
|
|
|
105
113
|
var node_6 = $.sibling(node_5, 2);
|
|
106
114
|
{
|
|
107
115
|
var consequent_6 = ($$anchor2) => {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
Button($$anchor2, {
|
|
117
|
+
type: "button",
|
|
118
|
+
variant: "danger",
|
|
119
|
+
size: "sm",
|
|
120
|
+
onclick: () => $$props.onDelete?.($$props.product.id),
|
|
121
|
+
children: ($$anchor3, $$slotProps) => {
|
|
122
|
+
$.next();
|
|
123
|
+
var text_7 = $.text("Delete");
|
|
124
|
+
$.append($$anchor3, text_7);
|
|
125
|
+
},
|
|
126
|
+
$$slots: { default: true }
|
|
127
|
+
});
|
|
111
128
|
};
|
|
112
129
|
$.if(node_6, ($$render) => {
|
|
113
130
|
if ($$props.onDelete) $$render(consequent_6);
|
|
@@ -119,7 +136,6 @@ function ProductCard($$anchor, $$props) {
|
|
|
119
136
|
$.append($$anchor, div);
|
|
120
137
|
$.pop();
|
|
121
138
|
}
|
|
122
|
-
$.delegate(["click"]);
|
|
123
139
|
const M = defineMessages({
|
|
124
140
|
// App
|
|
125
141
|
"products.app.categories_coming_soon": "Category management coming soon...",
|
|
@@ -210,8 +226,7 @@ const M = defineMessages({
|
|
|
210
226
|
});
|
|
211
227
|
var root_1 = $.from_html(`<span class="error-message svelte-1hh5ovx"> </span>`);
|
|
212
228
|
var root_2 = $.from_html(`<span class="error-message svelte-1hh5ovx"> </span>`);
|
|
213
|
-
var
|
|
214
|
-
var root = $.from_html(`<form class="product-form svelte-1hh5ovx"><div class="form-group svelte-1hh5ovx"><label for="name" class="svelte-1hh5ovx"> </label> <input id="name" type="text"/> <!></div> <div class="form-group svelte-1hh5ovx"><label for="description" class="svelte-1hh5ovx">Description</label> <textarea id="description" class="form-textarea svelte-1hh5ovx" rows="3"></textarea></div> <div class="form-row svelte-1hh5ovx"><div class="form-group svelte-1hh5ovx"><label for="price" class="svelte-1hh5ovx">Price *</label> <input id="price" type="number" step="0.01" min="0" placeholder="0.00"/> <!></div> <div class="form-group svelte-1hh5ovx"><label for="category" class="svelte-1hh5ovx">Category</label> <input id="category" type="text" class="form-input svelte-1hh5ovx"/></div></div> <div class="form-group svelte-1hh5ovx"><label for="tags" class="svelte-1hh5ovx">Tags</label> <input id="tags" type="text" class="form-input svelte-1hh5ovx"/> <small class="form-hint svelte-1hh5ovx"> </small></div> <div class="form-group svelte-1hh5ovx"><label class="checkbox-label svelte-1hh5ovx"><input type="checkbox" class="form-checkbox svelte-1hh5ovx"/> </label></div> <div class="form-actions svelte-1hh5ovx"><!> <button type="submit" class="submit-btn svelte-1hh5ovx"><!></button></div></form>`);
|
|
229
|
+
var root = $.from_html(`<form class="product-form svelte-1hh5ovx"><div class="form-group svelte-1hh5ovx"><label for="name" class="svelte-1hh5ovx"> </label> <input id="name" type="text"/> <!></div> <div class="form-group svelte-1hh5ovx"><label for="description" class="svelte-1hh5ovx">Description</label> <textarea id="description" class="form-textarea svelte-1hh5ovx" rows="3"></textarea></div> <div class="form-row svelte-1hh5ovx"><div class="form-group svelte-1hh5ovx"><label for="price" class="svelte-1hh5ovx">Price *</label> <input id="price" type="number" step="0.01" min="0" placeholder="0.00"/> <!></div> <div class="form-group svelte-1hh5ovx"><label for="category" class="svelte-1hh5ovx">Category</label> <input id="category" type="text" class="form-input svelte-1hh5ovx"/></div></div> <div class="form-group svelte-1hh5ovx"><label for="tags" class="svelte-1hh5ovx">Tags</label> <input id="tags" type="text" class="form-input svelte-1hh5ovx"/> <small class="form-hint svelte-1hh5ovx"> </small></div> <div class="form-group svelte-1hh5ovx"><label class="checkbox-label svelte-1hh5ovx"><input type="checkbox" class="form-checkbox svelte-1hh5ovx"/> </label></div> <div class="form-actions svelte-1hh5ovx"><!> <!></div></form>`);
|
|
215
230
|
function ProductForm($$anchor, $$props) {
|
|
216
231
|
$.push($$props, true);
|
|
217
232
|
const { t } = useI18n();
|
|
@@ -319,35 +334,56 @@ function ProductForm($$anchor, $$props) {
|
|
|
319
334
|
var node_2 = $.child(div_7);
|
|
320
335
|
{
|
|
321
336
|
var consequent_2 = ($$anchor2) => {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
337
|
+
Button($$anchor2, {
|
|
338
|
+
type: "button",
|
|
339
|
+
variant: "secondary",
|
|
340
|
+
get onclick() {
|
|
341
|
+
return $$props.onCancel;
|
|
342
|
+
},
|
|
343
|
+
get disabled() {
|
|
344
|
+
return loading();
|
|
345
|
+
},
|
|
346
|
+
children: ($$anchor3, $$slotProps) => {
|
|
347
|
+
$.next();
|
|
348
|
+
var text_5 = $.text("Cancel");
|
|
349
|
+
$.append($$anchor3, text_5);
|
|
350
|
+
},
|
|
351
|
+
$$slots: { default: true }
|
|
326
352
|
});
|
|
327
|
-
$.append($$anchor2, button);
|
|
328
353
|
};
|
|
329
354
|
$.if(node_2, ($$render) => {
|
|
330
355
|
if ($$props.onCancel) $$render(consequent_2);
|
|
331
356
|
});
|
|
332
357
|
}
|
|
333
|
-
var
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
var
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
358
|
+
var node_3 = $.sibling(node_2, 2);
|
|
359
|
+
Button(node_3, {
|
|
360
|
+
type: "submit",
|
|
361
|
+
variant: "primary",
|
|
362
|
+
get disabled() {
|
|
363
|
+
return loading();
|
|
364
|
+
},
|
|
365
|
+
children: ($$anchor2, $$slotProps) => {
|
|
366
|
+
var fragment_1 = $.comment();
|
|
367
|
+
var node_4 = $.first_child(fragment_1);
|
|
368
|
+
{
|
|
369
|
+
var consequent_3 = ($$anchor3) => {
|
|
370
|
+
var text_6 = $.text("Saving...");
|
|
371
|
+
$.append($$anchor3, text_6);
|
|
372
|
+
};
|
|
373
|
+
var alternate = ($$anchor3) => {
|
|
374
|
+
var text_7 = $.text();
|
|
375
|
+
$.template_effect(() => $.set_text(text_7, product().id ? "Update Product" : "Create Product"));
|
|
376
|
+
$.append($$anchor3, text_7);
|
|
377
|
+
};
|
|
378
|
+
$.if(node_4, ($$render) => {
|
|
379
|
+
if (loading()) $$render(consequent_3);
|
|
380
|
+
else $$render(alternate, -1);
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
$.append($$anchor2, fragment_1);
|
|
384
|
+
},
|
|
385
|
+
$$slots: { default: true }
|
|
386
|
+
});
|
|
351
387
|
$.reset(div_7);
|
|
352
388
|
$.reset(form);
|
|
353
389
|
$.template_effect(
|
|
@@ -367,7 +403,6 @@ function ProductForm($$anchor, $$props) {
|
|
|
367
403
|
$.set_text(text_3, $5);
|
|
368
404
|
input_4.disabled = loading();
|
|
369
405
|
$.set_text(text_4, ` ${$6 ?? ""}`);
|
|
370
|
-
button_1.disabled = loading();
|
|
371
406
|
},
|
|
372
407
|
[
|
|
373
408
|
() => t(M["products.product_form.name_label"]),
|
|
@@ -389,9 +424,8 @@ function ProductForm($$anchor, $$props) {
|
|
|
389
424
|
$.append($$anchor, form);
|
|
390
425
|
$.pop();
|
|
391
426
|
}
|
|
392
|
-
$.delegate(["click"]);
|
|
393
427
|
export {
|
|
394
428
|
ProductCard as P,
|
|
395
429
|
ProductForm as a
|
|
396
430
|
};
|
|
397
|
-
//# sourceMappingURL=ProductForm-
|
|
431
|
+
//# sourceMappingURL=ProductForm-CukMCDEN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductForm-CukMCDEN.js","sources":["../../../src/lib/components/ProductCard.svelte","../../../src/lib/i18n.ts","../../../src/lib/components/ProductForm.svelte"],"sourcesContent":["<script lang=\"ts\">\nimport { Button } from '@happyvertical/smrt-ui/ui';\nimport type { ProductData } from '../types';\n\ninterface Props {\n product: ProductData;\n onEdit?: (product: ProductData) => void;\n onDelete?: (id: string) => void;\n}\n\nconst { product, onEdit, onDelete }: Props = $props();\n</script>\n\n<div class=\"product-card\">\n <div class=\"product-header\">\n <h3 class=\"product-name\">{product.name}</h3>\n {#if product.manufacturer}\n <div class=\"product-manufacturer\">{product.manufacturer}</div>\n {/if}\n </div>\n\n {#if product.model}\n <div class=\"product-model\">Model: {product.model}</div>\n {/if}\n\n {#if product.description}\n <p class=\"product-description\">{product.description}</p>\n {/if}\n\n <div class=\"product-meta\">\n {#if product.category}\n <div class=\"product-category\">Category: {product.category}</div>\n {/if}\n \n {#if product.tags && product.tags.length > 0}\n <div class=\"product-tags\">\n {#each product.tags as tag}\n <span class=\"tag\">{tag}</span>\n {/each}\n </div>\n {/if}\n </div>\n \n <div class=\"product-actions\">\n {#if onEdit}\n <Button type=\"button\" variant=\"secondary\" size=\"sm\" onclick={() => onEdit?.(product)}>\n Edit\n </Button>\n {/if}\n\n {#if onDelete}\n <Button type=\"button\" variant=\"danger\" size=\"sm\" onclick={() => onDelete?.(product.id)}>\n Delete\n </Button>\n {/if}\n </div>\n</div>\n\n<style>\n .product-card {\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n border-radius: var(--smrt-radius-md, 8px);\n padding: 1rem;\n background: var(--smrt-color-surface, #fff);\n box-shadow: var(--smrt-elevation-1, 0 1px 3px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n transition: box-shadow 0.2s;\n }\n\n .product-card:hover {\n box-shadow: var(--smrt-elevation-2, 0 4px 6px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n }\n \n .product-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.5rem;\n }\n \n .product-name {\n margin: 0;\n font-size: var(--smrt-typography-title-medium-size, 1.125rem);\n font-weight: var(--smrt-typography-weight-semibold, 600);\n color: var(--smrt-color-on-surface, #1f2937);\n }\n\n .product-manufacturer {\n font-size: var(--smrt-typography-title-small-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n }\n\n .product-model {\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n margin-bottom: 0.5rem;\n }\n\n .product-category {\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n background: var(--smrt-color-surface-container, #f3f4f6);\n padding: 0.25rem 0.5rem;\n border-radius: var(--smrt-radius-sm, 4px);\n display: inline-block;\n margin-bottom: 0.5rem;\n }\n \n .product-description {\n margin: 0.5rem 0;\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n line-height: var(--smrt-typography-body-medium-line-height, 1.4);\n }\n \n .product-meta {\n margin: 0.75rem 0;\n }\n \n \n .product-tags {\n margin-top: 0.5rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n }\n \n .tag {\n background: var(--smrt-color-surface-container, #f3f4f6);\n color: var(--smrt-color-on-surface, #374151);\n padding: 0.125rem 0.5rem;\n border-radius: var(--smrt-radius-full, 9999px);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n }\n\n .product-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n</style>","import { defineMessages } from '@happyvertical/smrt-ui/i18n';\n\nexport const M = defineMessages({\n // App\n 'products.app.categories_coming_soon': 'Category management coming soon...',\n 'products.app.analytics_coming_soon': 'Analytics dashboard coming soon...',\n\n // AppLayout\n 'products.app_layout.service_title': 'Product Service',\n 'products.app_layout.footer_copyright':\n '2024 SMRT Product Service - Auto-generated with ❤️',\n 'products.app_layout.api_docs': 'API Docs',\n 'products.app_layout.mcp_tools': 'MCP Tools',\n\n // DemoPage\n 'products.demo_page.title': 'SMRT Framework Demo',\n 'products.demo_page.subtitle':\n 'Define Once, Consume Everywhere - Progressive Customization',\n 'products.demo_page.custom_components_tab': 'Custom Components',\n 'products.demo_page.auto_generated_heading':\n 'Auto-Generated UI from SMRT Object',\n 'products.demo_page.auto_generated_description':\n 'This form is automatically generated from the Product class definition.\\n The field types, labels, and validation rules are inferred from the TypeScript schema.',\n 'products.demo_page.generated_form_heading': 'Generated Form',\n 'products.demo_page.auto_form_title': 'Auto-Generated Product Form',\n 'products.demo_page.generated_display_heading': 'Generated Display',\n 'products.demo_page.custom_components_heading':\n 'Custom Components with SMRT Integration',\n 'products.demo_page.custom_components_description':\n 'These are hand-crafted components that still leverage the SMRT data structure\\n but provide custom UI/UX for specific business requirements.',\n 'products.demo_page.custom_form_heading': 'Custom Form',\n 'products.demo_page.custom_display_heading': 'Custom Display',\n 'products.demo_page.progressive_heading': 'Progressive Customization',\n 'products.demo_page.progressive_description':\n 'Start with auto-generated components, then progressively customize as needed.\\n Both approaches use the same underlying SMRT Product model.',\n 'products.demo_page.feature_zero_config': '✅ Zero configuration',\n 'products.demo_page.feature_instant_ui': '✅ Instant UI from schema',\n 'products.demo_page.feature_type_safe': '✅ Type-safe by default',\n 'products.demo_page.feature_prototyping': '⚡ Perfect for prototyping',\n 'products.demo_page.custom_components_label': '🎨 Custom Components',\n 'products.demo_page.feature_tailored_ux': '✅ Tailored UX',\n 'products.demo_page.feature_business_workflows':\n '✅ Business-specific workflows',\n 'products.demo_page.feature_advanced_interactions':\n '✅ Advanced interactions',\n 'products.demo_page.simple_auto_form_title': 'Auto Form',\n 'products.demo_page.benefits_heading': 'SMRT Framework Benefits',\n 'products.demo_page.benefit_define_once_label': 'Define Once:',\n 'products.demo_page.benefit_define_once_text':\n 'Product class with @smrt decorator',\n 'products.demo_page.benefit_auto_generate_label': 'Auto-Generate:',\n 'products.demo_page.benefit_auto_generate_text':\n 'REST APIs, MCP tools, TypeScript clients, default UI',\n 'products.demo_page.benefit_progressive_label': 'Progressive Enhancement:',\n 'products.demo_page.benefit_progressive_text':\n 'Start with defaults, customize as needed',\n 'products.demo_page.benefit_type_safety_label': 'Type Safety:',\n 'products.demo_page.benefit_type_safety_text':\n 'End-to-end TypeScript integration',\n 'products.demo_page.benefit_multiple_consumption_label':\n 'Multiple Consumption:',\n 'products.demo_page.benefit_multiple_consumption_text':\n 'Library, federation, standalone',\n\n // ProductsPage\n 'products.products_page.description':\n 'Manage your product catalog with auto-generated CRUD operations, \\n real-time updates, and AI-powered tools via MCP.',\n 'products.products_page.auto_generated_text':\n 'REST API endpoints automatically created from @smrt() decorated Product class',\n 'products.products_page.ai_ready_heading': '🤖 AI Ready',\n 'products.products_page.ai_ready_text':\n 'MCP tools available for Claude and other AI models to interact with products',\n 'products.products_page.federatable_text':\n 'Components can be consumed by other applications via module federation',\n 'products.products_page.library_text':\n 'Install as NPM package: npm install @have/smrt-template',\n\n // ProductForm\n 'products.product_form.name_label': 'Product Name *',\n 'products.product_form.name_placeholder': 'Enter product name',\n 'products.product_form.description_placeholder':\n 'Product description (optional)',\n 'products.product_form.category_placeholder': 'Product category',\n 'products.product_form.tags_placeholder': 'tag1, tag2, tag3',\n 'products.product_form.tags_hint': 'Separate tags with commas',\n 'products.product_form.in_stock_label': 'In Stock',\n\n // TestComponent\n 'products.test_component.title': 'Test Component',\n\n // AutoForm\n 'products.auto_form.subtitle': 'Auto-generated from SMRT Product model',\n 'products.auto_form.debug_summary': 'Form Data (Debug)',\n\n // FieldRenderer\n 'products.field_renderer.array_hint': 'Enter values separated by commas',\n 'products.field_renderer.object_hint': 'Enter valid JSON',\n\n // CategoryManager\n 'products.category_manager.title': 'Category Manager',\n 'products.category_manager.subtitle': 'Manage product categories',\n 'products.category_manager.coming_soon':\n 'Category management feature coming soon...',\n 'products.category_manager.will_include': 'This will include:',\n 'products.category_manager.create_edit': 'Create and edit categories',\n 'products.category_manager.organize_hierarchy': 'Organize category hierarchy',\n 'products.category_manager.manage_permissions': 'Manage category permissions',\n 'products.category_manager.analytics': 'Category analytics',\n\n // ProductCatalog\n 'products.product_catalog.title': 'Product Catalog',\n 'products.product_catalog.in_stock': 'in stock',\n 'products.product_catalog.total_value': 'Total value:',\n 'products.product_catalog.search_placeholder': 'Search products...',\n 'products.product_catalog.all_categories': 'All Categories',\n 'products.product_catalog.add_product': 'Add Product',\n 'products.product_catalog.loading': 'Loading products...',\n 'products.product_catalog.empty':\n 'No products yet. Create your first product to get started!',\n 'products.product_catalog.create_first': 'Create First Product',\n 'products.product_catalog.no_match':\n 'No products match your search criteria.',\n});\n","<script lang=\"ts\">\nimport { useI18n } from '@happyvertical/smrt-ui/i18n';\nimport { Button } from '@happyvertical/smrt-ui/ui';\nimport { M } from '../i18n.js';\nimport type { ProductData } from '../types';\n\nconst { t } = useI18n();\n\ninterface Props {\n product?: Partial<ProductData>;\n onSubmit: (product: Partial<ProductData>) => void;\n onCancel?: () => void;\n loading?: boolean;\n}\n\nconst { product = {}, onSubmit, onCancel, loading = false }: Props = $props();\n\nconst formData = $state({\n name: product.name || '',\n description: product.description || '',\n price: product.price || 0,\n inStock: product.inStock ?? true,\n category: product.category || '',\n tags: product.tags?.join(', ') || '',\n});\n\nlet errors = $state<Record<string, string>>({});\n\nfunction validateForm() {\n errors = {};\n\n if (!formData.name.trim()) {\n errors.name = 'Product name is required';\n }\n\n if (formData.price < 0) {\n errors.price = 'Price must be non-negative';\n }\n\n return Object.keys(errors).length === 0;\n}\n\nfunction handleSubmit(event: Event) {\n event.preventDefault();\n\n if (!validateForm()) {\n return;\n }\n\n const productData: Partial<ProductData> = {\n ...product,\n name: formData.name.trim(),\n description: formData.description.trim() || undefined,\n price: formData.price,\n inStock: formData.inStock,\n category: formData.category.trim(),\n tags: formData.tags\n ? formData.tags\n .split(',')\n .map((tag) => tag.trim())\n .filter(Boolean)\n : [],\n };\n\n onSubmit(productData);\n}\n</script>\n\n<form onsubmit={handleSubmit} class=\"product-form\">\n <div class=\"form-group\">\n <label for=\"name\">{t(M['products.product_form.name_label'])}</label>\n <input\n id=\"name\"\n type=\"text\"\n bind:value={formData.name}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.name}\n placeholder={t(M['products.product_form.name_placeholder'])}\n />\n {#if errors.name}\n <span class=\"error-message\">{errors.name}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"description\">Description</label>\n <textarea\n id=\"description\"\n bind:value={formData.description}\n disabled={loading}\n class=\"form-textarea\"\n placeholder={t(M['products.product_form.description_placeholder'])}\n rows=\"3\"\n ></textarea>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"price\">Price *</label>\n <input\n id=\"price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n bind:value={formData.price}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.price}\n placeholder=\"0.00\"\n />\n {#if errors.price}\n <span class=\"error-message\">{errors.price}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"category\">Category</label>\n <input\n id=\"category\"\n type=\"text\"\n bind:value={formData.category}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.category_placeholder'])}\n />\n </div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"tags\">Tags</label>\n <input\n id=\"tags\"\n type=\"text\"\n bind:value={formData.tags}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.tags_placeholder'])}\n />\n <small class=\"form-hint\">{t(M['products.product_form.tags_hint'])}</small>\n </div>\n\n <div class=\"form-group\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n bind:checked={formData.inStock}\n disabled={loading}\n class=\"form-checkbox\"\n />\n {t(M['products.product_form.in_stock_label'])}\n </label>\n </div>\n\n <div class=\"form-actions\">\n {#if onCancel}\n <Button type=\"button\" variant=\"secondary\" onclick={onCancel} disabled={loading}>\n Cancel\n </Button>\n {/if}\n\n <Button type=\"submit\" variant=\"primary\" disabled={loading}>\n {#if loading}\n Saving...\n {:else}\n {product.id ? 'Update Product' : 'Create Product'}\n {/if}\n </Button>\n </div>\n</form>\n\n<style>\n .product-form {\n max-width: 500px;\n padding: 1.5rem;\n background: var(--smrt-color-surface, #fff);\n border-radius: var(--smrt-radius-md, 8px);\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n }\n \n .form-group {\n margin-bottom: 1rem;\n }\n \n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n }\n \n label {\n display: block;\n margin-bottom: 0.25rem;\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n }\n\n .form-input, .form-textarea {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid var(--smrt-color-outline-variant, #d1d5db);\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n transition: border-color 0.2s;\n }\n\n .form-input:focus, .form-textarea:focus {\n outline: none;\n border-color: var(--smrt-color-primary, #3b82f6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary, #3b82f6) 10%, transparent);\n }\n\n .form-input.error {\n border-color: var(--smrt-color-error, #dc2626);\n }\n \n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n \n .checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n }\n \n .form-checkbox {\n width: auto;\n }\n \n .form-hint {\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-small-size, 0.75rem);\n margin-top: 0.25rem;\n }\n\n .error-message {\n color: var(--smrt-color-error, #dc2626);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n margin-top: 0.25rem;\n display: block;\n }\n\n .form-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-top: 1.5rem;\n padding-top: 1rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n</style>"],"names":["root","root_1","root_2","$$anchor"],"mappings":"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"}
|
package/dist/lib/components.js
CHANGED
package/dist/lib/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { default as default3 } from "@smrt/mcp";
|
|
|
6
6
|
import { default as default4 } from "@smrt/routes";
|
|
7
7
|
import { C, M, P, a, S } from "./chunks/SkuCollection-f_a3k93c.js";
|
|
8
8
|
import { ProductAssetCollection } from "./chunks/ProductAssetCollection-B93HdSlX.js";
|
|
9
|
-
import { P as P2, a as a2 } from "./chunks/ProductForm-
|
|
9
|
+
import { P as P2, a as a2 } from "./chunks/ProductForm-CukMCDEN.js";
|
|
10
10
|
import { a as a3 } from "./chunks/index-i3-ci1FB.js";
|
|
11
11
|
import { P as Product, C as Category } from "./chunks/Sku-sl6xf1PR.js";
|
|
12
12
|
import { M as M2, a as a4, b, c, S as S2 } from "./chunks/Sku-sl6xf1PR.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
2
3
|
import type { ProductData } from '../types';
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
@@ -42,15 +43,15 @@ const { product, onEdit, onDelete }: Props = $props();
|
|
|
42
43
|
|
|
43
44
|
<div class="product-actions">
|
|
44
45
|
{#if onEdit}
|
|
45
|
-
<
|
|
46
|
+
<Button type="button" variant="secondary" size="sm" onclick={() => onEdit?.(product)}>
|
|
46
47
|
Edit
|
|
47
|
-
</
|
|
48
|
+
</Button>
|
|
48
49
|
{/if}
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
{#if onDelete}
|
|
51
|
-
<
|
|
52
|
+
<Button type="button" variant="danger" size="sm" onclick={() => onDelete?.(product.id)}>
|
|
52
53
|
Delete
|
|
53
|
-
</
|
|
54
|
+
</Button>
|
|
54
55
|
{/if}
|
|
55
56
|
</div>
|
|
56
57
|
</div>
|
|
@@ -140,34 +141,4 @@ const { product, onEdit, onDelete }: Props = $props();
|
|
|
140
141
|
padding-top: 0.75rem;
|
|
141
142
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
142
143
|
}
|
|
143
|
-
|
|
144
|
-
.edit-btn, .delete-btn {
|
|
145
|
-
padding: 0.375rem 0.75rem;
|
|
146
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
147
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
148
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
149
|
-
border: 1px solid;
|
|
150
|
-
cursor: pointer;
|
|
151
|
-
transition: all 0.2s;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.edit-btn {
|
|
155
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
156
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
157
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.edit-btn:hover {
|
|
161
|
-
background: var(--smrt-color-surface-container, #f3f4f6);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.delete-btn {
|
|
165
|
-
background: var(--smrt-color-error-container, #fef2f2);
|
|
166
|
-
border-color: var(--smrt-color-error, #fecaca);
|
|
167
|
-
color: var(--smrt-color-error, #dc2626);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.delete-btn:hover {
|
|
171
|
-
background: var(--smrt-color-error-container, #fee2e2);
|
|
172
|
-
}
|
|
173
144
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductCard.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/ProductCard.svelte"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductCard.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/ProductCard.svelte"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,UAAU,KAAK;IACb,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAyDD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
3
4
|
import { M } from '../i18n.js';
|
|
4
5
|
import type { ProductData } from '../types';
|
|
5
6
|
|
|
@@ -153,18 +154,18 @@ function handleSubmit(event: Event) {
|
|
|
153
154
|
|
|
154
155
|
<div class="form-actions">
|
|
155
156
|
{#if onCancel}
|
|
156
|
-
<
|
|
157
|
+
<Button type="button" variant="secondary" onclick={onCancel} disabled={loading}>
|
|
157
158
|
Cancel
|
|
158
|
-
</
|
|
159
|
+
</Button>
|
|
159
160
|
{/if}
|
|
160
|
-
|
|
161
|
-
<
|
|
161
|
+
|
|
162
|
+
<Button type="submit" variant="primary" disabled={loading}>
|
|
162
163
|
{#if loading}
|
|
163
164
|
Saving...
|
|
164
165
|
{:else}
|
|
165
166
|
{product.id ? 'Update Product' : 'Create Product'}
|
|
166
167
|
{/if}
|
|
167
|
-
</
|
|
168
|
+
</Button>
|
|
168
169
|
</div>
|
|
169
170
|
</form>
|
|
170
171
|
|
|
@@ -251,39 +252,4 @@ function handleSubmit(event: Event) {
|
|
|
251
252
|
padding-top: 1rem;
|
|
252
253
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
253
254
|
}
|
|
254
|
-
|
|
255
|
-
.cancel-btn, .submit-btn {
|
|
256
|
-
padding: 0.5rem 1rem;
|
|
257
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
258
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
259
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
260
|
-
cursor: pointer;
|
|
261
|
-
border: 1px solid;
|
|
262
|
-
transition: all 0.2s;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.cancel-btn {
|
|
266
|
-
background: var(--smrt-color-surface, #fff);
|
|
267
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
268
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.cancel-btn:hover:not(:disabled) {
|
|
272
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.submit-btn {
|
|
276
|
-
background: var(--smrt-color-primary, #3b82f6);
|
|
277
|
-
border-color: var(--smrt-color-primary, #3b82f6);
|
|
278
|
-
color: var(--smrt-color-on-primary, white);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
.submit-btn:hover:not(:disabled) {
|
|
282
|
-
background: var(--smrt-color-primary, #2563eb);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.submit-btn:disabled, .cancel-btn:disabled {
|
|
286
|
-
opacity: 0.5;
|
|
287
|
-
cursor: not-allowed;
|
|
288
|
-
}
|
|
289
255
|
</style>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductForm.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/ProductForm.svelte"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductForm.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/ProductForm.svelte"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAClD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA2HD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
8
|
+
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
8
9
|
import { M } from '../../i18n.js';
|
|
9
10
|
import type { ProductData } from '../../types';
|
|
10
11
|
import FieldRenderer from './FieldRenderer.svelte';
|
|
@@ -128,12 +129,12 @@ function _getFieldType(
|
|
|
128
129
|
|
|
129
130
|
{#if !readonly}
|
|
130
131
|
<div class="form-actions">
|
|
131
|
-
<
|
|
132
|
+
<Button type="submit" variant="primary">
|
|
132
133
|
{submitLabel}
|
|
133
|
-
</
|
|
134
|
-
<
|
|
134
|
+
</Button>
|
|
135
|
+
<Button type="button" variant="secondary" onclick={() => formData = {}}>
|
|
135
136
|
Reset
|
|
136
|
-
</
|
|
137
|
+
</Button>
|
|
137
138
|
</div>
|
|
138
139
|
{/if}
|
|
139
140
|
</form>
|
|
@@ -187,36 +188,6 @@ function _getFieldType(
|
|
|
187
188
|
border-top: 1px solid var(--smrt-color-outline-variant, #e5e7eb);
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
.submit-btn {
|
|
191
|
-
background: var(--smrt-color-primary, #3b82f6);
|
|
192
|
-
color: var(--smrt-color-on-primary, white);
|
|
193
|
-
border: none;
|
|
194
|
-
padding: 0.75rem 1.5rem;
|
|
195
|
-
border-radius: var(--smrt-radius-sm, 0.375rem);
|
|
196
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
197
|
-
cursor: pointer;
|
|
198
|
-
transition: background-color 0.2s;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
.submit-btn:hover {
|
|
202
|
-
background: var(--smrt-color-primary, #2563eb);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.reset-btn {
|
|
206
|
-
background: var(--smrt-color-surface-container, #f3f4f6);
|
|
207
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
208
|
-
border: 1px solid var(--smrt-color-outline-variant, #d1d5db);
|
|
209
|
-
padding: 0.75rem 1.5rem;
|
|
210
|
-
border-radius: var(--smrt-radius-sm, 0.375rem);
|
|
211
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
212
|
-
cursor: pointer;
|
|
213
|
-
transition: background-color 0.2s;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.reset-btn:hover {
|
|
217
|
-
background: var(--smrt-color-surface-container-high, #e5e7eb);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
191
|
.form-debug {
|
|
221
192
|
margin-top: 2rem;
|
|
222
193
|
padding: 1rem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoForm.svelte.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/auto-generated/AutoForm.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AutoForm.svelte.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/auto-generated/AutoForm.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI/C,UAAU,KAAK;IACb,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC;AAoID,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import { Button } from '@happyvertical/smrt-ui/ui';
|
|
3
4
|
import { onMount } from 'svelte';
|
|
4
5
|
import ProductCard from '../components/ProductCard.svelte';
|
|
5
6
|
import ProductForm from '../components/ProductForm.svelte';
|
|
@@ -119,13 +120,13 @@ function handleCancelForm() {
|
|
|
119
120
|
</div>
|
|
120
121
|
|
|
121
122
|
{#if !readonly && (showCreateForm || productStore.items.length === 0)}
|
|
122
|
-
<
|
|
123
|
-
type="button"
|
|
123
|
+
<Button
|
|
124
|
+
type="button"
|
|
125
|
+
variant="primary"
|
|
124
126
|
onclick={handleCreateProduct}
|
|
125
|
-
class="create-btn"
|
|
126
127
|
>
|
|
127
128
|
{t(M['products.product_catalog.add_product'])}
|
|
128
|
-
</
|
|
129
|
+
</Button>
|
|
129
130
|
{/if}
|
|
130
131
|
</div>
|
|
131
132
|
|
|
@@ -136,18 +137,18 @@ function handleCancelForm() {
|
|
|
136
137
|
{:else if productStore.error}
|
|
137
138
|
<div class="error-state" role="alert" aria-live="assertive">
|
|
138
139
|
<p>Error: {productStore.error}</p>
|
|
139
|
-
<
|
|
140
|
+
<Button type="button" variant="danger" onclick={() => productStore.loadProducts()}>
|
|
140
141
|
Retry
|
|
141
|
-
</
|
|
142
|
+
</Button>
|
|
142
143
|
</div>
|
|
143
144
|
{:else if filteredProducts.length === 0}
|
|
144
145
|
<div class="empty-state" role="status" aria-live="polite">
|
|
145
146
|
{#if productStore.items.length === 0}
|
|
146
147
|
<p>{t(M['products.product_catalog.empty'])}</p>
|
|
147
148
|
{#if !readonly}
|
|
148
|
-
<
|
|
149
|
+
<Button type="button" variant="primary" onclick={handleCreateProduct}>
|
|
149
150
|
{t(M['products.product_catalog.create_first'])}
|
|
150
|
-
</
|
|
151
|
+
</Button>
|
|
151
152
|
{/if}
|
|
152
153
|
{:else}
|
|
153
154
|
<p>{t(M['products.product_catalog.no_match'])}</p>
|
|
@@ -240,21 +241,6 @@ function handleCancelForm() {
|
|
|
240
241
|
min-width: 150px;
|
|
241
242
|
}
|
|
242
243
|
|
|
243
|
-
.create-btn {
|
|
244
|
-
background: var(--smrt-color-primary, #3b82f6);
|
|
245
|
-
color: var(--smrt-color-on-primary, white);
|
|
246
|
-
border: none;
|
|
247
|
-
padding: 0.5rem 1rem;
|
|
248
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
249
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
250
|
-
cursor: pointer;
|
|
251
|
-
transition: background-color 0.2s;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.create-btn:hover {
|
|
255
|
-
background: var(--smrt-color-primary, #2563eb);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
244
|
.products-grid {
|
|
259
245
|
display: grid;
|
|
260
246
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
@@ -267,14 +253,12 @@ function handleCancelForm() {
|
|
|
267
253
|
color: var(--smrt-color-on-surface-variant, #6b7280);
|
|
268
254
|
}
|
|
269
255
|
|
|
270
|
-
|
|
256
|
+
/* Restore the retry button's spacing from the error message. The old
|
|
257
|
+
`.error-state button` rule can't reach the <button> rendered inside the
|
|
258
|
+
smrt-ui <Button>, so pierce into it with `:global` (#1589); the danger
|
|
259
|
+
variant already supplies the background/color the old rule set. */
|
|
260
|
+
.error-state :global(.button) {
|
|
271
261
|
margin-top: 0.5rem;
|
|
272
|
-
background: var(--smrt-color-error, #dc2626);
|
|
273
|
-
color: var(--smrt-color-on-error, white);
|
|
274
|
-
border: none;
|
|
275
|
-
padding: 0.5rem 1rem;
|
|
276
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
277
|
-
cursor: pointer;
|
|
278
262
|
}
|
|
279
263
|
|
|
280
264
|
.form-overlay {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductCatalog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/features/ProductCatalog.svelte"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ProductCatalog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/features/ProductCatalog.svelte"],"names":[],"mappings":"AAaA,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAoKD,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
package/dist/lib/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
|
-
"timestamp":
|
|
3
|
+
"timestamp": 1782278452967,
|
|
4
4
|
"packageName": "@happyvertical/smrt-products",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.6",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-products:CategoryCollection": {
|
|
8
8
|
"name": "categorycollection",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-06-
|
|
3
|
+
"generatedAt": "2026-06-24T05:20:53.581Z",
|
|
4
4
|
"packageName": "@happyvertical/smrt-products",
|
|
5
|
-
"packageVersion": "0.34.
|
|
5
|
+
"packageVersion": "0.34.6",
|
|
6
6
|
"sourceManifestPath": "dist/lib/manifest.json",
|
|
7
7
|
"agentDocPath": "AGENTS.md",
|
|
8
8
|
"sourceHashes": {
|
|
9
|
-
"manifest": "
|
|
10
|
-
"packageJson": "
|
|
9
|
+
"manifest": "584ad2da857b7180b8a585c41e0975b7743a07f6ad3ffc172186e396cd814cb7",
|
|
10
|
+
"packageJson": "5a90519cc03f1b0745852b4c8b691d0a03199722ab64cdf53425665e20be1ec5",
|
|
11
11
|
"agents": "4ca8837df73cf8b966b65cea639a058baa8f92ae536f3cd5036546fcbfeb37c8"
|
|
12
12
|
},
|
|
13
13
|
"exports": [
|
|
@@ -83,36 +83,6 @@
|
|
|
83
83
|
padding-top: 0.75rem;
|
|
84
84
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
.edit-btn.svelte-11ja2cl, .delete-btn.svelte-11ja2cl {
|
|
88
|
-
padding: 0.375rem 0.75rem;
|
|
89
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
90
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
91
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
92
|
-
border: 1px solid;
|
|
93
|
-
cursor: pointer;
|
|
94
|
-
transition: all 0.2s;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.edit-btn.svelte-11ja2cl {
|
|
98
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
99
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
100
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.edit-btn.svelte-11ja2cl:hover {
|
|
104
|
-
background: var(--smrt-color-surface-container, #f3f4f6);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.delete-btn.svelte-11ja2cl {
|
|
108
|
-
background: var(--smrt-color-error-container, #fef2f2);
|
|
109
|
-
border-color: var(--smrt-color-error, #fecaca);
|
|
110
|
-
color: var(--smrt-color-error, #dc2626);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.delete-btn.svelte-11ja2cl:hover {
|
|
114
|
-
background: var(--smrt-color-error-container, #fee2e2);
|
|
115
|
-
}
|
|
116
86
|
|
|
117
87
|
.product-form.svelte-1hh5ovx {
|
|
118
88
|
max-width: 500px;
|
|
@@ -196,38 +166,3 @@
|
|
|
196
166
|
padding-top: 1rem;
|
|
197
167
|
border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);
|
|
198
168
|
}
|
|
199
|
-
|
|
200
|
-
.cancel-btn.svelte-1hh5ovx, .submit-btn.svelte-1hh5ovx {
|
|
201
|
-
padding: 0.5rem 1rem;
|
|
202
|
-
border-radius: var(--smrt-radius-sm, 4px);
|
|
203
|
-
font-size: var(--smrt-typography-label-large-size, 0.875rem);
|
|
204
|
-
font-weight: var(--smrt-typography-weight-medium, 500);
|
|
205
|
-
cursor: pointer;
|
|
206
|
-
border: 1px solid;
|
|
207
|
-
transition: all 0.2s;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
.cancel-btn.svelte-1hh5ovx {
|
|
211
|
-
background: var(--smrt-color-surface, #fff);
|
|
212
|
-
border-color: var(--smrt-color-outline-variant, #d1d5db);
|
|
213
|
-
color: var(--smrt-color-on-surface, #374151);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.cancel-btn.svelte-1hh5ovx:hover:not(:disabled) {
|
|
217
|
-
background: var(--smrt-color-surface-container-low, #f9fafb);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.submit-btn.svelte-1hh5ovx {
|
|
221
|
-
background: var(--smrt-color-primary, #3b82f6);
|
|
222
|
-
border-color: var(--smrt-color-primary, #3b82f6);
|
|
223
|
-
color: var(--smrt-color-on-primary, white);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
.submit-btn.svelte-1hh5ovx:hover:not(:disabled) {
|
|
227
|
-
background: var(--smrt-color-primary, #2563eb);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
.submit-btn.svelte-1hh5ovx:disabled, .cancel-btn.svelte-1hh5ovx:disabled {
|
|
231
|
-
opacity: 0.5;
|
|
232
|
-
cursor: not-allowed;
|
|
233
|
-
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-products",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.6",
|
|
4
4
|
"description": "SMRT products module: triple-purpose microservice template for standalone apps, federated modules, and NPM libraries",
|
|
5
5
|
"author": "HappyVertical",
|
|
6
6
|
"type": "module",
|
|
7
|
+
"smrtRawPrimitives": "strict-buttons",
|
|
7
8
|
"main": "dist/lib/index.js",
|
|
8
9
|
"types": "dist/lib/index.d.ts",
|
|
9
10
|
"files": [
|
|
@@ -54,11 +55,11 @@
|
|
|
54
55
|
"@happyvertical/utils": "^0.74.7",
|
|
55
56
|
"cors": "^2.8.5",
|
|
56
57
|
"express": "^5.2.1",
|
|
57
|
-
"@happyvertical/smrt-
|
|
58
|
-
"@happyvertical/smrt-
|
|
59
|
-
"@happyvertical/smrt-
|
|
60
|
-
"@happyvertical/smrt-
|
|
61
|
-
"@happyvertical/smrt-
|
|
58
|
+
"@happyvertical/smrt-assets": "0.34.6",
|
|
59
|
+
"@happyvertical/smrt-core": "0.34.6",
|
|
60
|
+
"@happyvertical/smrt-scanner": "0.34.6",
|
|
61
|
+
"@happyvertical/smrt-tenancy": "0.34.6",
|
|
62
|
+
"@happyvertical/smrt-ui": "0.34.6"
|
|
62
63
|
},
|
|
63
64
|
"peerDependencies": {
|
|
64
65
|
"svelte": "^5.46.4"
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
"typescript": "^5.9.3",
|
|
82
83
|
"vite": "^7.3.1",
|
|
83
84
|
"vitest": "^4.0.17",
|
|
84
|
-
"@happyvertical/smrt-vitest": "0.34.
|
|
85
|
+
"@happyvertical/smrt-vitest": "0.34.6"
|
|
85
86
|
},
|
|
86
87
|
"keywords": [
|
|
87
88
|
"smrt",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProductForm-p4-xbubZ.js","sources":["../../../src/lib/components/ProductCard.svelte","../../../src/lib/i18n.ts","../../../src/lib/components/ProductForm.svelte"],"sourcesContent":["<script lang=\"ts\">\nimport type { ProductData } from '../types';\n\ninterface Props {\n product: ProductData;\n onEdit?: (product: ProductData) => void;\n onDelete?: (id: string) => void;\n}\n\nconst { product, onEdit, onDelete }: Props = $props();\n</script>\n\n<div class=\"product-card\">\n <div class=\"product-header\">\n <h3 class=\"product-name\">{product.name}</h3>\n {#if product.manufacturer}\n <div class=\"product-manufacturer\">{product.manufacturer}</div>\n {/if}\n </div>\n\n {#if product.model}\n <div class=\"product-model\">Model: {product.model}</div>\n {/if}\n\n {#if product.description}\n <p class=\"product-description\">{product.description}</p>\n {/if}\n\n <div class=\"product-meta\">\n {#if product.category}\n <div class=\"product-category\">Category: {product.category}</div>\n {/if}\n \n {#if product.tags && product.tags.length > 0}\n <div class=\"product-tags\">\n {#each product.tags as tag}\n <span class=\"tag\">{tag}</span>\n {/each}\n </div>\n {/if}\n </div>\n \n <div class=\"product-actions\">\n {#if onEdit}\n <button type=\"button\" onclick={() => onEdit?.(product)} class=\"edit-btn\">\n Edit\n </button>\n {/if}\n \n {#if onDelete}\n <button type=\"button\" onclick={() => onDelete?.(product.id)} class=\"delete-btn\">\n Delete\n </button>\n {/if}\n </div>\n</div>\n\n<style>\n .product-card {\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n border-radius: var(--smrt-radius-md, 8px);\n padding: 1rem;\n background: var(--smrt-color-surface, #fff);\n box-shadow: var(--smrt-elevation-1, 0 1px 3px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n transition: box-shadow 0.2s;\n }\n\n .product-card:hover {\n box-shadow: var(--smrt-elevation-2, 0 4px 6px color-mix(in srgb, var(--smrt-color-shadow, #000) 10%, transparent));\n }\n \n .product-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 0.5rem;\n }\n \n .product-name {\n margin: 0;\n font-size: var(--smrt-typography-title-medium-size, 1.125rem);\n font-weight: var(--smrt-typography-weight-semibold, 600);\n color: var(--smrt-color-on-surface, #1f2937);\n }\n\n .product-manufacturer {\n font-size: var(--smrt-typography-title-small-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n }\n\n .product-model {\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n color: var(--smrt-color-on-surface-variant, #6b7280);\n margin-bottom: 0.5rem;\n }\n\n .product-category {\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n background: var(--smrt-color-surface-container, #f3f4f6);\n padding: 0.25rem 0.5rem;\n border-radius: var(--smrt-radius-sm, 4px);\n display: inline-block;\n margin-bottom: 0.5rem;\n }\n \n .product-description {\n margin: 0.5rem 0;\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n line-height: var(--smrt-typography-body-medium-line-height, 1.4);\n }\n \n .product-meta {\n margin: 0.75rem 0;\n }\n \n \n .product-tags {\n margin-top: 0.5rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.25rem;\n }\n \n .tag {\n background: var(--smrt-color-surface-container, #f3f4f6);\n color: var(--smrt-color-on-surface, #374151);\n padding: 0.125rem 0.5rem;\n border-radius: var(--smrt-radius-full, 9999px);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n }\n\n .product-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 1rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n \n .edit-btn, .delete-btn {\n padding: 0.375rem 0.75rem;\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n border: 1px solid;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n .edit-btn {\n background: var(--smrt-color-surface-container-low, #f9fafb);\n border-color: var(--smrt-color-outline-variant, #d1d5db);\n color: var(--smrt-color-on-surface, #374151);\n }\n\n .edit-btn:hover {\n background: var(--smrt-color-surface-container, #f3f4f6);\n }\n\n .delete-btn {\n background: var(--smrt-color-error-container, #fef2f2);\n border-color: var(--smrt-color-error, #fecaca);\n color: var(--smrt-color-error, #dc2626);\n }\n\n .delete-btn:hover {\n background: var(--smrt-color-error-container, #fee2e2);\n }\n</style>","import { defineMessages } from '@happyvertical/smrt-ui/i18n';\n\nexport const M = defineMessages({\n // App\n 'products.app.categories_coming_soon': 'Category management coming soon...',\n 'products.app.analytics_coming_soon': 'Analytics dashboard coming soon...',\n\n // AppLayout\n 'products.app_layout.service_title': 'Product Service',\n 'products.app_layout.footer_copyright':\n '2024 SMRT Product Service - Auto-generated with ❤️',\n 'products.app_layout.api_docs': 'API Docs',\n 'products.app_layout.mcp_tools': 'MCP Tools',\n\n // DemoPage\n 'products.demo_page.title': 'SMRT Framework Demo',\n 'products.demo_page.subtitle':\n 'Define Once, Consume Everywhere - Progressive Customization',\n 'products.demo_page.custom_components_tab': 'Custom Components',\n 'products.demo_page.auto_generated_heading':\n 'Auto-Generated UI from SMRT Object',\n 'products.demo_page.auto_generated_description':\n 'This form is automatically generated from the Product class definition.\\n The field types, labels, and validation rules are inferred from the TypeScript schema.',\n 'products.demo_page.generated_form_heading': 'Generated Form',\n 'products.demo_page.auto_form_title': 'Auto-Generated Product Form',\n 'products.demo_page.generated_display_heading': 'Generated Display',\n 'products.demo_page.custom_components_heading':\n 'Custom Components with SMRT Integration',\n 'products.demo_page.custom_components_description':\n 'These are hand-crafted components that still leverage the SMRT data structure\\n but provide custom UI/UX for specific business requirements.',\n 'products.demo_page.custom_form_heading': 'Custom Form',\n 'products.demo_page.custom_display_heading': 'Custom Display',\n 'products.demo_page.progressive_heading': 'Progressive Customization',\n 'products.demo_page.progressive_description':\n 'Start with auto-generated components, then progressively customize as needed.\\n Both approaches use the same underlying SMRT Product model.',\n 'products.demo_page.feature_zero_config': '✅ Zero configuration',\n 'products.demo_page.feature_instant_ui': '✅ Instant UI from schema',\n 'products.demo_page.feature_type_safe': '✅ Type-safe by default',\n 'products.demo_page.feature_prototyping': '⚡ Perfect for prototyping',\n 'products.demo_page.custom_components_label': '🎨 Custom Components',\n 'products.demo_page.feature_tailored_ux': '✅ Tailored UX',\n 'products.demo_page.feature_business_workflows':\n '✅ Business-specific workflows',\n 'products.demo_page.feature_advanced_interactions':\n '✅ Advanced interactions',\n 'products.demo_page.simple_auto_form_title': 'Auto Form',\n 'products.demo_page.benefits_heading': 'SMRT Framework Benefits',\n 'products.demo_page.benefit_define_once_label': 'Define Once:',\n 'products.demo_page.benefit_define_once_text':\n 'Product class with @smrt decorator',\n 'products.demo_page.benefit_auto_generate_label': 'Auto-Generate:',\n 'products.demo_page.benefit_auto_generate_text':\n 'REST APIs, MCP tools, TypeScript clients, default UI',\n 'products.demo_page.benefit_progressive_label': 'Progressive Enhancement:',\n 'products.demo_page.benefit_progressive_text':\n 'Start with defaults, customize as needed',\n 'products.demo_page.benefit_type_safety_label': 'Type Safety:',\n 'products.demo_page.benefit_type_safety_text':\n 'End-to-end TypeScript integration',\n 'products.demo_page.benefit_multiple_consumption_label':\n 'Multiple Consumption:',\n 'products.demo_page.benefit_multiple_consumption_text':\n 'Library, federation, standalone',\n\n // ProductsPage\n 'products.products_page.description':\n 'Manage your product catalog with auto-generated CRUD operations, \\n real-time updates, and AI-powered tools via MCP.',\n 'products.products_page.auto_generated_text':\n 'REST API endpoints automatically created from @smrt() decorated Product class',\n 'products.products_page.ai_ready_heading': '🤖 AI Ready',\n 'products.products_page.ai_ready_text':\n 'MCP tools available for Claude and other AI models to interact with products',\n 'products.products_page.federatable_text':\n 'Components can be consumed by other applications via module federation',\n 'products.products_page.library_text':\n 'Install as NPM package: npm install @have/smrt-template',\n\n // ProductForm\n 'products.product_form.name_label': 'Product Name *',\n 'products.product_form.name_placeholder': 'Enter product name',\n 'products.product_form.description_placeholder':\n 'Product description (optional)',\n 'products.product_form.category_placeholder': 'Product category',\n 'products.product_form.tags_placeholder': 'tag1, tag2, tag3',\n 'products.product_form.tags_hint': 'Separate tags with commas',\n 'products.product_form.in_stock_label': 'In Stock',\n\n // TestComponent\n 'products.test_component.title': 'Test Component',\n\n // AutoForm\n 'products.auto_form.subtitle': 'Auto-generated from SMRT Product model',\n 'products.auto_form.debug_summary': 'Form Data (Debug)',\n\n // FieldRenderer\n 'products.field_renderer.array_hint': 'Enter values separated by commas',\n 'products.field_renderer.object_hint': 'Enter valid JSON',\n\n // CategoryManager\n 'products.category_manager.title': 'Category Manager',\n 'products.category_manager.subtitle': 'Manage product categories',\n 'products.category_manager.coming_soon':\n 'Category management feature coming soon...',\n 'products.category_manager.will_include': 'This will include:',\n 'products.category_manager.create_edit': 'Create and edit categories',\n 'products.category_manager.organize_hierarchy': 'Organize category hierarchy',\n 'products.category_manager.manage_permissions': 'Manage category permissions',\n 'products.category_manager.analytics': 'Category analytics',\n\n // ProductCatalog\n 'products.product_catalog.title': 'Product Catalog',\n 'products.product_catalog.in_stock': 'in stock',\n 'products.product_catalog.total_value': 'Total value:',\n 'products.product_catalog.search_placeholder': 'Search products...',\n 'products.product_catalog.all_categories': 'All Categories',\n 'products.product_catalog.add_product': 'Add Product',\n 'products.product_catalog.loading': 'Loading products...',\n 'products.product_catalog.empty':\n 'No products yet. Create your first product to get started!',\n 'products.product_catalog.create_first': 'Create First Product',\n 'products.product_catalog.no_match':\n 'No products match your search criteria.',\n});\n","<script lang=\"ts\">\nimport { useI18n } from '@happyvertical/smrt-ui/i18n';\nimport { M } from '../i18n.js';\nimport type { ProductData } from '../types';\n\nconst { t } = useI18n();\n\ninterface Props {\n product?: Partial<ProductData>;\n onSubmit: (product: Partial<ProductData>) => void;\n onCancel?: () => void;\n loading?: boolean;\n}\n\nconst { product = {}, onSubmit, onCancel, loading = false }: Props = $props();\n\nconst formData = $state({\n name: product.name || '',\n description: product.description || '',\n price: product.price || 0,\n inStock: product.inStock ?? true,\n category: product.category || '',\n tags: product.tags?.join(', ') || '',\n});\n\nlet errors = $state<Record<string, string>>({});\n\nfunction validateForm() {\n errors = {};\n\n if (!formData.name.trim()) {\n errors.name = 'Product name is required';\n }\n\n if (formData.price < 0) {\n errors.price = 'Price must be non-negative';\n }\n\n return Object.keys(errors).length === 0;\n}\n\nfunction handleSubmit(event: Event) {\n event.preventDefault();\n\n if (!validateForm()) {\n return;\n }\n\n const productData: Partial<ProductData> = {\n ...product,\n name: formData.name.trim(),\n description: formData.description.trim() || undefined,\n price: formData.price,\n inStock: formData.inStock,\n category: formData.category.trim(),\n tags: formData.tags\n ? formData.tags\n .split(',')\n .map((tag) => tag.trim())\n .filter(Boolean)\n : [],\n };\n\n onSubmit(productData);\n}\n</script>\n\n<form onsubmit={handleSubmit} class=\"product-form\">\n <div class=\"form-group\">\n <label for=\"name\">{t(M['products.product_form.name_label'])}</label>\n <input\n id=\"name\"\n type=\"text\"\n bind:value={formData.name}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.name}\n placeholder={t(M['products.product_form.name_placeholder'])}\n />\n {#if errors.name}\n <span class=\"error-message\">{errors.name}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"description\">Description</label>\n <textarea\n id=\"description\"\n bind:value={formData.description}\n disabled={loading}\n class=\"form-textarea\"\n placeholder={t(M['products.product_form.description_placeholder'])}\n rows=\"3\"\n ></textarea>\n </div>\n\n <div class=\"form-row\">\n <div class=\"form-group\">\n <label for=\"price\">Price *</label>\n <input\n id=\"price\"\n type=\"number\"\n step=\"0.01\"\n min=\"0\"\n bind:value={formData.price}\n disabled={loading}\n class=\"form-input\"\n class:error={errors.price}\n placeholder=\"0.00\"\n />\n {#if errors.price}\n <span class=\"error-message\">{errors.price}</span>\n {/if}\n </div>\n\n <div class=\"form-group\">\n <label for=\"category\">Category</label>\n <input\n id=\"category\"\n type=\"text\"\n bind:value={formData.category}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.category_placeholder'])}\n />\n </div>\n </div>\n\n <div class=\"form-group\">\n <label for=\"tags\">Tags</label>\n <input\n id=\"tags\"\n type=\"text\"\n bind:value={formData.tags}\n disabled={loading}\n class=\"form-input\"\n placeholder={t(M['products.product_form.tags_placeholder'])}\n />\n <small class=\"form-hint\">{t(M['products.product_form.tags_hint'])}</small>\n </div>\n\n <div class=\"form-group\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n bind:checked={formData.inStock}\n disabled={loading}\n class=\"form-checkbox\"\n />\n {t(M['products.product_form.in_stock_label'])}\n </label>\n </div>\n\n <div class=\"form-actions\">\n {#if onCancel}\n <button type=\"button\" onclick={onCancel} disabled={loading} class=\"cancel-btn\">\n Cancel\n </button>\n {/if}\n \n <button type=\"submit\" disabled={loading} class=\"submit-btn\">\n {#if loading}\n Saving...\n {:else}\n {product.id ? 'Update Product' : 'Create Product'}\n {/if}\n </button>\n </div>\n</form>\n\n<style>\n .product-form {\n max-width: 500px;\n padding: 1.5rem;\n background: var(--smrt-color-surface, #fff);\n border-radius: var(--smrt-radius-md, 8px);\n border: 1px solid var(--smrt-color-outline-variant, #e2e8f0);\n }\n \n .form-group {\n margin-bottom: 1rem;\n }\n \n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 1rem;\n }\n \n label {\n display: block;\n margin-bottom: 0.25rem;\n font-weight: var(--smrt-typography-weight-medium, 500);\n color: var(--smrt-color-on-surface, #374151);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n }\n\n .form-input, .form-textarea {\n width: 100%;\n padding: 0.5rem;\n border: 1px solid var(--smrt-color-outline-variant, #d1d5db);\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-body-medium-size, 0.875rem);\n transition: border-color 0.2s;\n }\n\n .form-input:focus, .form-textarea:focus {\n outline: none;\n border-color: var(--smrt-color-primary, #3b82f6);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--smrt-color-primary, #3b82f6) 10%, transparent);\n }\n\n .form-input.error {\n border-color: var(--smrt-color-error, #dc2626);\n }\n \n .form-textarea {\n resize: vertical;\n min-height: 80px;\n }\n \n .checkbox-label {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n }\n \n .form-checkbox {\n width: auto;\n }\n \n .form-hint {\n color: var(--smrt-color-on-surface-variant, #6b7280);\n font-size: var(--smrt-typography-body-small-size, 0.75rem);\n margin-top: 0.25rem;\n }\n\n .error-message {\n color: var(--smrt-color-error, #dc2626);\n font-size: var(--smrt-typography-label-medium-size, 0.75rem);\n margin-top: 0.25rem;\n display: block;\n }\n\n .form-actions {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n margin-top: 1.5rem;\n padding-top: 1rem;\n border-top: 1px solid var(--smrt-color-outline-variant, #f3f4f6);\n }\n \n .cancel-btn, .submit-btn {\n padding: 0.5rem 1rem;\n border-radius: var(--smrt-radius-sm, 4px);\n font-size: var(--smrt-typography-label-large-size, 0.875rem);\n font-weight: var(--smrt-typography-weight-medium, 500);\n cursor: pointer;\n border: 1px solid;\n transition: all 0.2s;\n }\n \n .cancel-btn {\n background: var(--smrt-color-surface, #fff);\n border-color: var(--smrt-color-outline-variant, #d1d5db);\n color: var(--smrt-color-on-surface, #374151);\n }\n\n .cancel-btn:hover:not(:disabled) {\n background: var(--smrt-color-surface-container-low, #f9fafb);\n }\n\n .submit-btn {\n background: var(--smrt-color-primary, #3b82f6);\n border-color: var(--smrt-color-primary, #3b82f6);\n color: var(--smrt-color-on-primary, white);\n }\n\n .submit-btn:hover:not(:disabled) {\n background: var(--smrt-color-primary, #2563eb);\n }\n \n .submit-btn:disabled, .cancel-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n</style>"],"names":["root","root_1","root_2","root_3","$$anchor"],"mappings":"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"}
|