diff --git a/frontend/src/components/admin/EventBookingSelect.tsx b/frontend/src/components/admin/EventBookingSelect.tsx new file mode 100644 index 00000000..d8b8d789 --- /dev/null +++ b/frontend/src/components/admin/EventBookingSelect.tsx @@ -0,0 +1,39 @@ +/** + * Booking-target dropdown for accounting (expenses + incoming invoices). + * "Company" (value null) or a specific event. Projects remain a separate + * aggregation of events and are intentionally NOT a booking target here. + */ +import React from 'react'; +import { useQuery } from '@tanstack/react-query'; +import { useTranslation } from 'react-i18next'; +import { eventsService } from '../../services/events.service'; + +interface Props { + value: number | null; + onChange: (eventId: number | null) => void; + className?: string; +} + +export const EventBookingSelect: React.FC = ({ value, onChange, className }) => { + const { t } = useTranslation(); + const { data } = useQuery({ + queryKey: ['events-for-booking'], + queryFn: () => eventsService.getEvents(1, 200), + staleTime: 60_000, + }); + const events = data?.events ?? []; + const cls = className + || 'w-full rounded-md border border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-800 px-3 py-2 text-sm'; + + return ( + + ); +}; + +export default EventBookingSelect; diff --git a/frontend/src/pages/admin/accounting/AccountingInboxPage.tsx b/frontend/src/pages/admin/accounting/AccountingInboxPage.tsx index 6eeae9b5..71678787 100644 --- a/frontend/src/pages/admin/accounting/AccountingInboxPage.tsx +++ b/frontend/src/pages/admin/accounting/AccountingInboxPage.tsx @@ -13,6 +13,7 @@ import { Camera, Upload, Inbox, X, CheckCircle2, Circle } from 'lucide-react'; import { Button, Card, CardContent, Input, LocalizedDateInput, Loading } from '../../../components/common'; import { DecimalInput } from '../../../components/common/DecimalInput'; import { CustomerAccountPicker, type SelectedCustomer } from '../../../components/admin/CustomerAccountPicker'; +import { EventBookingSelect } from '../../../components/admin/EventBookingSelect'; import { formatMoneyMinor } from '../../../utils/money'; import { useLocalizedDate } from '../../../hooks/useLocalizedDate'; import { @@ -34,27 +35,6 @@ const statusClasses: Record = { const labelCls = 'block text-sm font-medium text-neutral-700 dark:text-neutral-300 mb-1'; const selectCls = 'w-full rounded-md border border-neutral-300 dark:border-neutral-600 bg-white dark:bg-neutral-800 px-3 py-2 text-sm'; -const BookingField: React.FC<{ eventId: number | null; onChange: (id: number | null) => void }> = ({ eventId, onChange }) => { - const { t } = useTranslation(); - const isEvent = eventId != null; - return ( -
- -
- - {isEvent && ( - onChange(Number(e.target.value.replace(/[^0-9]/g, '')) || 0)} /> - )} -
-
- ); -}; - const PayModal: React.FC<{ doc: InboundDocument; onClose: () => void; onDone: () => void }> = ({ doc, onClose, onDone }) => { const { t } = useTranslation(); const [paidAt, setPaidAt] = useState(''); @@ -184,7 +164,12 @@ const TriageModal: React.FC<{ doc: InboundDocument; categories: ExpenseCategory[ - {BOOKING_DISPOSITIONS.includes(disposition) && } + {BOOKING_DISPOSITIONS.includes(disposition) && ( +
+ + +
+ )} {disposition === 'eigener_aufwand' && (
diff --git a/frontend/src/pages/admin/accounting/ExpensesLedgerPage.tsx b/frontend/src/pages/admin/accounting/ExpensesLedgerPage.tsx index 764a23f5..8e3a9db0 100644 --- a/frontend/src/pages/admin/accounting/ExpensesLedgerPage.tsx +++ b/frontend/src/pages/admin/accounting/ExpensesLedgerPage.tsx @@ -13,6 +13,7 @@ import { toast } from 'react-toastify'; import { X, Plus, Paperclip, Car, CalendarDays, Coins } from 'lucide-react'; import { Button, Card, CardContent, Input, Loading } from '../../../components/common'; import { DecimalInput } from '../../../components/common/DecimalInput'; +import { EventBookingSelect } from '../../../components/admin/EventBookingSelect'; import { formatMoneyMinor } from '../../../utils/money'; import { useLocalizedDate } from '../../../hooks/useLocalizedDate'; import { @@ -106,13 +107,7 @@ const AddExpenseModal: React.FC<{ categories: ExpenseCategory[]; onClose: () =>
-
- - {eventId != null && setEventId(Number(e.target.value.replace(/[^0-9]/g, '')) || 0)} />} -
+