refactor(bill-modal): extract TemplateSection (BM2, 7/n)
The save-as-template toggle + name input move to their own presentational component. Behavior-preserving — BillModal 1105 -> 1090 lines. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ad68d965b6
commit
20b46c81df
|
|
@ -23,6 +23,7 @@ import PaymentHistoryList from '@/components/bill-modal/PaymentHistoryList';
|
||||||
import PaymentFormFields from '@/components/bill-modal/PaymentFormFields';
|
import PaymentFormFields from '@/components/bill-modal/PaymentFormFields';
|
||||||
import UnmatchDialogs from '@/components/bill-modal/UnmatchDialogs';
|
import UnmatchDialogs from '@/components/bill-modal/UnmatchDialogs';
|
||||||
import LinkedTransactionsSection from '@/components/bill-modal/LinkedTransactionsSection';
|
import LinkedTransactionsSection from '@/components/bill-modal/LinkedTransactionsSection';
|
||||||
|
import TemplateSection from '@/components/bill-modal/TemplateSection';
|
||||||
import { transactionTitle, isSimilarPayee } from '@/components/bill-modal/transactionDisplay';
|
import { transactionTitle, isSimilarPayee } from '@/components/bill-modal/transactionDisplay';
|
||||||
import {
|
import {
|
||||||
BILLING_SCHEDULE_OPTIONS,
|
BILLING_SCHEDULE_OPTIONS,
|
||||||
|
|
@ -916,30 +917,14 @@ export default function BillModal({ bill, initialBill, categories, onClose, onSa
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-span-2 rounded-lg border border-border/60 bg-muted/20 p-3">
|
<TemplateSection
|
||||||
<label className="flex items-center gap-2.5 cursor-pointer group">
|
inp={inp}
|
||||||
<input
|
saveTemplate={saveTemplate}
|
||||||
type="checkbox"
|
setSaveTemplate={setSaveTemplate}
|
||||||
checked={saveTemplate}
|
templateName={templateName}
|
||||||
onChange={e => setSaveTemplate(e.target.checked)}
|
setTemplateName={setTemplateName}
|
||||||
className="h-4 w-4 rounded border-border accent-primary"
|
namePlaceholder={name}
|
||||||
/>
|
/>
|
||||||
<span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">
|
|
||||||
Save this setup as a reusable template
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
{saveTemplate && (
|
|
||||||
<div className="mt-2 space-y-1.5">
|
|
||||||
<Label className="text-xs uppercase tracking-wider text-muted-foreground">Template Name</Label>
|
|
||||||
<Input
|
|
||||||
className={inp}
|
|
||||||
value={templateName}
|
|
||||||
onChange={e => setTemplateName(e.target.value)}
|
|
||||||
placeholder={name || 'My bill template'}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { Input } from '@/components/ui/input';
|
||||||
|
|
||||||
|
// "Save this setup as a reusable template" toggle + optional template name.
|
||||||
|
// Presentational — the parent owns the state and performs the save.
|
||||||
|
export default function TemplateSection({
|
||||||
|
inp,
|
||||||
|
saveTemplate, setSaveTemplate,
|
||||||
|
templateName, setTemplateName,
|
||||||
|
namePlaceholder,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="col-span-2 rounded-lg border border-border/60 bg-muted/20 p-3">
|
||||||
|
<label className="flex items-center gap-2.5 cursor-pointer group">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={saveTemplate}
|
||||||
|
onChange={e => setSaveTemplate(e.target.checked)}
|
||||||
|
className="h-4 w-4 rounded border-border accent-primary"
|
||||||
|
/>
|
||||||
|
<span className="text-sm text-muted-foreground group-hover:text-foreground transition-colors">
|
||||||
|
Save this setup as a reusable template
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
{saveTemplate && (
|
||||||
|
<div className="mt-2 space-y-1.5">
|
||||||
|
<Label className="text-xs uppercase tracking-wider text-muted-foreground">Template Name</Label>
|
||||||
|
<Input
|
||||||
|
className={inp}
|
||||||
|
value={templateName}
|
||||||
|
onChange={e => setTemplateName(e.target.value)}
|
||||||
|
placeholder={namePlaceholder || 'My bill template'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue