@@ -20,6 +20,7 @@ import {
2020 FREQUENCY_LABELS ,
2121} from "@/hooks/useBills" ;
2222import { Button } from "@/components/ui/button" ;
23+ import { BillEntryForm } from "@/components/BillEntryForm" ;
2324import { toast } from "sonner" ;
2425import { isSafeUrl } from "@/lib/utils" ;
2526import {
@@ -402,30 +403,20 @@ export default function BillDetailPage() {
402403
403404 { /* Add price form */ }
404405 { showAddPrice && (
405- < form
406+ < BillEntryForm
406407 onSubmit = { handleAddPrice }
407- className = "bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-3 mb-3 space-y-2"
408+ amount = { newAmount }
409+ onAmountChange = { setNewAmount }
410+ date = { newDate }
411+ onDateChange = { setNewDate }
412+ dateAriaLabel = "Effective date"
413+ notes = { newNotes }
414+ onNotesChange = { setNewNotes }
415+ onCancel = { ( ) => setShowAddPrice ( false ) }
416+ isPending = { addPrice . isPending }
417+ isOnline = { isOnline }
418+ offlineTitle = "Adding a price entry requires an internet connection"
408419 >
409- < div className = "flex gap-2" >
410- < input
411- type = "number"
412- value = { newAmount }
413- onChange = { ( e ) => setNewAmount ( e . target . value ) }
414- placeholder = "Amount"
415- min = "0.01"
416- step = "0.01"
417- required
418- className = "flex-1 px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
419- />
420- < input
421- type = "date"
422- value = { newDate }
423- onChange = { ( e ) => setNewDate ( e . target . value ) }
424- required
425- aria-label = "Effective date"
426- className = "px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
427- />
428- </ div >
429420 < div >
430421 < label htmlFor = "bill-price-end-date" className = "block text-xs text-gray-500 dark:text-gray-400 mb-1" >
431422 Valid until (optional)
@@ -439,34 +430,7 @@ export default function BillDetailPage() {
439430 className = "w-full px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
440431 />
441432 </ div >
442- < input
443- type = "text"
444- value = { newNotes }
445- onChange = { ( e ) => setNewNotes ( e . target . value ) }
446- placeholder = "Notes (optional)"
447- className = "w-full px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
448- />
449- < div className = "flex gap-2" >
450- < Button
451- type = "button"
452- variant = "outline"
453- size = "sm"
454- className = "flex-1"
455- onClick = { ( ) => setShowAddPrice ( false ) }
456- >
457- Cancel
458- </ Button >
459- < Button
460- type = "submit"
461- size = "sm"
462- className = "flex-1"
463- disabled = { addPrice . isPending || ! isOnline }
464- title = { isOnline ? undefined : "Adding a price entry requires an internet connection" }
465- >
466- { addPrice . isPending ? "Saving..." : "Save" }
467- </ Button >
468- </ div >
469- </ form >
433+ </ BillEntryForm >
470434 ) }
471435
472436 { historyLoading && (
@@ -544,58 +508,20 @@ export default function BillDetailPage() {
544508 </ div >
545509
546510 { showAddAmountEntry && (
547- < form
511+ < BillEntryForm
548512 onSubmit = { handleAddAmountEntry }
549- className = "bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-3 mb-3 space-y-2"
550- >
551- < div className = "flex gap-2" >
552- < input
553- type = "number"
554- value = { newEntryAmount }
555- onChange = { ( e ) => setNewEntryAmount ( e . target . value ) }
556- placeholder = "Amount"
557- min = "0.01"
558- step = "0.01"
559- required
560- className = "flex-1 px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
561- />
562- < input
563- type = "date"
564- value = { newEntryPeriodDate }
565- onChange = { ( e ) => setNewEntryPeriodDate ( e . target . value ) }
566- required
567- aria-label = "Period date"
568- className = "px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
569- />
570- </ div >
571- < input
572- type = "text"
573- value = { newEntryNotes }
574- onChange = { ( e ) => setNewEntryNotes ( e . target . value ) }
575- placeholder = "Notes (optional)"
576- className = "w-full px-3 py-1.5 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
577- />
578- < div className = "flex gap-2" >
579- < Button
580- type = "button"
581- variant = "outline"
582- size = "sm"
583- className = "flex-1"
584- onClick = { ( ) => setShowAddAmountEntry ( false ) }
585- >
586- Cancel
587- </ Button >
588- < Button
589- type = "submit"
590- size = "sm"
591- className = "flex-1"
592- disabled = { addAmountEntry . isPending || ! isOnline }
593- title = { isOnline ? undefined : "Adding an amount entry requires an internet connection" }
594- >
595- { addAmountEntry . isPending ? "Saving..." : "Save" }
596- </ Button >
597- </ div >
598- </ form >
513+ amount = { newEntryAmount }
514+ onAmountChange = { setNewEntryAmount }
515+ date = { newEntryPeriodDate }
516+ onDateChange = { setNewEntryPeriodDate }
517+ dateAriaLabel = "Period date"
518+ notes = { newEntryNotes }
519+ onNotesChange = { setNewEntryNotes }
520+ onCancel = { ( ) => setShowAddAmountEntry ( false ) }
521+ isPending = { addAmountEntry . isPending }
522+ isOnline = { isOnline }
523+ offlineTitle = "Adding an amount entry requires an internet connection"
524+ />
599525 ) }
600526
601527 { amountEntriesLoading && (
0 commit comments