89 lines
3.6 KiB
TypeScript
89 lines
3.6 KiB
TypeScript
import type { Component } from 'solid-js';
|
|
import { createSignal } from 'solid-js';
|
|
import { Save } from 'lucide-solid';
|
|
import type { TemplateItem, Template } from '../types';
|
|
import TemplateItemList from '../components/template/TemplateItemList';
|
|
|
|
const TemplateCreator: Component = () => {
|
|
const [templateName, setTemplateName] = createSignal('');
|
|
const [items, setItems] = createSignal<TemplateItem[]>([]);
|
|
|
|
const handleAddItem = () => {
|
|
const newItem: TemplateItem = {
|
|
id: crypto.randomUUID(),
|
|
description: '',
|
|
quantity: 1,
|
|
unitPrice: 0
|
|
};
|
|
setItems([...items(), newItem]);
|
|
};
|
|
|
|
const handleUpdateItem = (id: string, updates: Partial<TemplateItem>) => {
|
|
setItems(items().map(item => item.id === id ? { ...item, ...updates } : item));
|
|
};
|
|
|
|
const handleDeleteItem = (id: string) => {
|
|
setItems(items().filter(item => item.id !== id));
|
|
};
|
|
|
|
const handleSaveTemplate = () => {
|
|
// Here we would typically save to localStorage or backend
|
|
// For now, we'll just log it or show a toast
|
|
const template: Template = {
|
|
id: crypto.randomUUID(),
|
|
name: templateName(),
|
|
items: items()
|
|
};
|
|
console.log('Template saved:', template);
|
|
alert(`Template "${template.name}" saved successfully!`);
|
|
|
|
// Reset form
|
|
setTemplateName('');
|
|
setItems([]);
|
|
};
|
|
|
|
return (
|
|
<div class="flex flex-col items-center py-6 px-4 font-sans print:bg-transparent print:border-none print:p-0">
|
|
<div class="max-w-4xl w-full bg-white rounded-xl shadow-premium p-8 mb-8 border border-gray-100 no-print">
|
|
<div class="flex items-center justify-between mb-8 pb-4 border-b border-gray-100">
|
|
<div>
|
|
<h1 class="text-3xl font-bold text-gray-800 mb-2 tracking-tight">Template Creator</h1>
|
|
<p class="text-gray-500 font-medium">Create templates for your estimate sub-scopes.</p>
|
|
</div>
|
|
|
|
<button
|
|
onClick={handleSaveTemplate}
|
|
disabled={!templateName() || items().length === 0}
|
|
class="flex items-center gap-2 px-6 py-2.5 text-sm font-bold text-white bg-blue-600 rounded-xl hover:bg-blue-700 transition-all shadow-premium hover:shadow-premium-hover disabled:opacity-50 disabled:cursor-not-allowed"
|
|
>
|
|
<Save class="w-4 h-4" />
|
|
Save Template
|
|
</button>
|
|
</div>
|
|
|
|
<div class="mb-8">
|
|
<label class="block text-sm font-semibold text-gray-700 mb-2">
|
|
Sub-Scope Name
|
|
</label>
|
|
<input
|
|
type="text"
|
|
value={templateName()}
|
|
onInput={(e) => setTemplateName(e.currentTarget.value)}
|
|
placeholder="e.g. Master Bathroom Rough-in"
|
|
class="w-full bg-gray-50/50 border border-gray-200 rounded-xl px-4 py-3 text-gray-800 focus:bg-white focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 outline-none font-medium transition-all shadow-sm"
|
|
/>
|
|
</div>
|
|
|
|
<TemplateItemList
|
|
items={items()}
|
|
onAddItem={handleAddItem}
|
|
onUpdateItem={handleUpdateItem}
|
|
onDeleteItem={handleDeleteItem}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TemplateCreator;
|