@voyantjs/hospitality-ui 0.13.0
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/README.md +13 -0
- package/dist/components/cancellation-policy-combobox.d.ts +9 -0
- package/dist/components/cancellation-policy-combobox.d.ts.map +1 -0
- package/dist/components/cancellation-policy-combobox.js +49 -0
- package/dist/components/maintenance-block-dialog.d.ts +11 -0
- package/dist/components/maintenance-block-dialog.d.ts.map +1 -0
- package/dist/components/maintenance-block-dialog.js +86 -0
- package/dist/components/maintenance-blocks-tab.d.ts +5 -0
- package/dist/components/maintenance-blocks-tab.d.ts.map +1 -0
- package/dist/components/maintenance-blocks-tab.js +51 -0
- package/dist/components/meal-plan-combobox.d.ts +10 -0
- package/dist/components/meal-plan-combobox.d.ts.map +1 -0
- package/dist/components/meal-plan-combobox.js +50 -0
- package/dist/components/meal-plan-dialog.d.ts +10 -0
- package/dist/components/meal-plan-dialog.d.ts.map +1 -0
- package/dist/components/meal-plan-dialog.js +86 -0
- package/dist/components/meal-plans-tab.d.ts +5 -0
- package/dist/components/meal-plans-tab.d.ts.map +1 -0
- package/dist/components/meal-plans-tab.js +44 -0
- package/dist/components/pagination-footer.d.ts +9 -0
- package/dist/components/pagination-footer.d.ts.map +1 -0
- package/dist/components/pagination-footer.js +11 -0
- package/dist/components/price-catalog-combobox.d.ts +9 -0
- package/dist/components/price-catalog-combobox.d.ts.map +1 -0
- package/dist/components/price-catalog-combobox.js +45 -0
- package/dist/components/rate-plan-combobox.d.ts +10 -0
- package/dist/components/rate-plan-combobox.d.ts.map +1 -0
- package/dist/components/rate-plan-combobox.js +50 -0
- package/dist/components/rate-plan-dialog.d.ts +11 -0
- package/dist/components/rate-plan-dialog.d.ts.map +1 -0
- package/dist/components/rate-plan-dialog.js +120 -0
- package/dist/components/rate-plans-tab.d.ts +5 -0
- package/dist/components/rate-plans-tab.d.ts.map +1 -0
- package/dist/components/rate-plans-tab.js +54 -0
- package/dist/components/room-block-dialog.d.ts +11 -0
- package/dist/components/room-block-dialog.d.ts.map +1 -0
- package/dist/components/room-block-dialog.js +91 -0
- package/dist/components/room-blocks-tab.d.ts +5 -0
- package/dist/components/room-blocks-tab.d.ts.map +1 -0
- package/dist/components/room-blocks-tab.js +51 -0
- package/dist/components/room-inventory-dialog.d.ts +11 -0
- package/dist/components/room-inventory-dialog.d.ts.map +1 -0
- package/dist/components/room-inventory-dialog.js +98 -0
- package/dist/components/room-inventory-tab.d.ts +5 -0
- package/dist/components/room-inventory-tab.d.ts.map +1 -0
- package/dist/components/room-inventory-tab.js +61 -0
- package/dist/components/room-type-combobox.d.ts +10 -0
- package/dist/components/room-type-combobox.d.ts.map +1 -0
- package/dist/components/room-type-combobox.js +46 -0
- package/dist/components/room-type-dialog.d.ts +10 -0
- package/dist/components/room-type-dialog.d.ts.map +1 -0
- package/dist/components/room-type-dialog.js +119 -0
- package/dist/components/room-types-tab.d.ts +5 -0
- package/dist/components/room-types-tab.d.ts.map +1 -0
- package/dist/components/room-types-tab.js +33 -0
- package/dist/components/room-unit-combobox.d.ts +10 -0
- package/dist/components/room-unit-combobox.d.ts.map +1 -0
- package/dist/components/room-unit-combobox.js +50 -0
- package/dist/components/room-unit-dialog.d.ts +10 -0
- package/dist/components/room-unit-dialog.d.ts.map +1 -0
- package/dist/components/room-unit-dialog.js +93 -0
- package/dist/components/room-units-tab.d.ts +5 -0
- package/dist/components/room-units-tab.d.ts.map +1 -0
- package/dist/components/room-units-tab.js +40 -0
- package/dist/components/stay-rule-dialog.d.ts +11 -0
- package/dist/components/stay-rule-dialog.d.ts.map +1 -0
- package/dist/components/stay-rule-dialog.js +140 -0
- package/dist/components/stay-rules-tab.d.ts +5 -0
- package/dist/components/stay-rules-tab.d.ts.map +1 -0
- package/dist/components/stay-rules-tab.js +49 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/package.json +68 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useStayRuleMutation } from "@voyantjs/hospitality-react";
|
|
3
|
+
import { Button, Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, Input, Label, Switch, Textarea, } from "@voyantjs/voyant-ui/components";
|
|
4
|
+
import { DatePicker } from "@voyantjs/voyant-ui/components/date-picker";
|
|
5
|
+
import { zodResolver } from "@voyantjs/voyant-ui/lib/zod-resolver";
|
|
6
|
+
import { Loader2 } from "lucide-react";
|
|
7
|
+
import { useEffect } from "react";
|
|
8
|
+
import { useForm } from "react-hook-form";
|
|
9
|
+
import { z } from "zod/v4";
|
|
10
|
+
import { RatePlanCombobox } from "./rate-plan-combobox";
|
|
11
|
+
import { RoomTypeCombobox } from "./room-type-combobox";
|
|
12
|
+
const WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
13
|
+
const intOrEmpty = z.coerce.number().int().optional().or(z.literal("")).nullable();
|
|
14
|
+
const formSchema = z.object({
|
|
15
|
+
ratePlanId: z.string().optional().nullable(),
|
|
16
|
+
roomTypeId: z.string().optional().nullable(),
|
|
17
|
+
validFrom: z.string().optional().nullable(),
|
|
18
|
+
validTo: z.string().optional().nullable(),
|
|
19
|
+
minNights: intOrEmpty,
|
|
20
|
+
maxNights: intOrEmpty,
|
|
21
|
+
minAdvanceDays: intOrEmpty,
|
|
22
|
+
maxAdvanceDays: intOrEmpty,
|
|
23
|
+
releaseDays: intOrEmpty,
|
|
24
|
+
closedToArrival: z.boolean(),
|
|
25
|
+
closedToDeparture: z.boolean(),
|
|
26
|
+
arrivalWeekdays: z.array(z.string()),
|
|
27
|
+
departureWeekdays: z.array(z.string()),
|
|
28
|
+
active: z.boolean(),
|
|
29
|
+
priority: z.coerce.number().int(),
|
|
30
|
+
notes: z.string().optional().nullable(),
|
|
31
|
+
});
|
|
32
|
+
export function StayRuleDialog({ open, onOpenChange, propertyId, rule, onSuccess, }) {
|
|
33
|
+
const isEditing = Boolean(rule);
|
|
34
|
+
const { create, update } = useStayRuleMutation();
|
|
35
|
+
const form = useForm({
|
|
36
|
+
resolver: zodResolver(formSchema),
|
|
37
|
+
defaultValues: {
|
|
38
|
+
ratePlanId: "",
|
|
39
|
+
roomTypeId: "",
|
|
40
|
+
validFrom: "",
|
|
41
|
+
validTo: "",
|
|
42
|
+
minNights: "",
|
|
43
|
+
maxNights: "",
|
|
44
|
+
minAdvanceDays: "",
|
|
45
|
+
maxAdvanceDays: "",
|
|
46
|
+
releaseDays: "",
|
|
47
|
+
closedToArrival: false,
|
|
48
|
+
closedToDeparture: false,
|
|
49
|
+
arrivalWeekdays: [],
|
|
50
|
+
departureWeekdays: [],
|
|
51
|
+
active: true,
|
|
52
|
+
priority: 0,
|
|
53
|
+
notes: "",
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (open && rule) {
|
|
58
|
+
form.reset({
|
|
59
|
+
ratePlanId: rule.ratePlanId ?? "",
|
|
60
|
+
roomTypeId: rule.roomTypeId ?? "",
|
|
61
|
+
validFrom: rule.validFrom ?? "",
|
|
62
|
+
validTo: rule.validTo ?? "",
|
|
63
|
+
minNights: rule.minNights ?? "",
|
|
64
|
+
maxNights: rule.maxNights ?? "",
|
|
65
|
+
minAdvanceDays: rule.minAdvanceDays ?? "",
|
|
66
|
+
maxAdvanceDays: rule.maxAdvanceDays ?? "",
|
|
67
|
+
releaseDays: rule.releaseDays ?? "",
|
|
68
|
+
closedToArrival: rule.closedToArrival,
|
|
69
|
+
closedToDeparture: rule.closedToDeparture,
|
|
70
|
+
arrivalWeekdays: rule.arrivalWeekdays ?? [],
|
|
71
|
+
departureWeekdays: rule.departureWeekdays ?? [],
|
|
72
|
+
active: rule.active,
|
|
73
|
+
priority: rule.priority,
|
|
74
|
+
notes: rule.notes ?? "",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (open) {
|
|
78
|
+
form.reset({
|
|
79
|
+
ratePlanId: "",
|
|
80
|
+
roomTypeId: "",
|
|
81
|
+
validFrom: "",
|
|
82
|
+
validTo: "",
|
|
83
|
+
minNights: "",
|
|
84
|
+
maxNights: "",
|
|
85
|
+
minAdvanceDays: "",
|
|
86
|
+
maxAdvanceDays: "",
|
|
87
|
+
releaseDays: "",
|
|
88
|
+
closedToArrival: false,
|
|
89
|
+
closedToDeparture: false,
|
|
90
|
+
arrivalWeekdays: [],
|
|
91
|
+
departureWeekdays: [],
|
|
92
|
+
active: true,
|
|
93
|
+
priority: 0,
|
|
94
|
+
notes: "",
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}, [form, open, rule]);
|
|
98
|
+
const toggleWeekday = (field, day, checked) => {
|
|
99
|
+
const current = form.watch(field) ?? [];
|
|
100
|
+
const next = checked ? [...current, day] : current.filter((value) => value !== day);
|
|
101
|
+
form.setValue(field, next);
|
|
102
|
+
};
|
|
103
|
+
const onSubmit = async (values) => {
|
|
104
|
+
const toInt = (value) => typeof value === "number" ? value : null;
|
|
105
|
+
const payload = {
|
|
106
|
+
propertyId,
|
|
107
|
+
ratePlanId: values.ratePlanId || null,
|
|
108
|
+
roomTypeId: values.roomTypeId || null,
|
|
109
|
+
validFrom: values.validFrom || null,
|
|
110
|
+
validTo: values.validTo || null,
|
|
111
|
+
minNights: toInt(values.minNights),
|
|
112
|
+
maxNights: toInt(values.maxNights),
|
|
113
|
+
minAdvanceDays: toInt(values.minAdvanceDays),
|
|
114
|
+
maxAdvanceDays: toInt(values.maxAdvanceDays),
|
|
115
|
+
releaseDays: toInt(values.releaseDays),
|
|
116
|
+
closedToArrival: values.closedToArrival,
|
|
117
|
+
closedToDeparture: values.closedToDeparture,
|
|
118
|
+
arrivalWeekdays: values.arrivalWeekdays.length > 0 ? values.arrivalWeekdays : null,
|
|
119
|
+
departureWeekdays: values.departureWeekdays.length > 0 ? values.departureWeekdays : null,
|
|
120
|
+
active: values.active,
|
|
121
|
+
priority: values.priority,
|
|
122
|
+
notes: values.notes || null,
|
|
123
|
+
};
|
|
124
|
+
const saved = isEditing
|
|
125
|
+
? await update.mutateAsync({ id: rule.id, input: payload })
|
|
126
|
+
: await create.mutateAsync(payload);
|
|
127
|
+
onOpenChange(false);
|
|
128
|
+
onSuccess?.(saved);
|
|
129
|
+
};
|
|
130
|
+
const arrivalWeekdays = form.watch("arrivalWeekdays") ?? [];
|
|
131
|
+
const departureWeekdays = form.watch("departureWeekdays") ?? [];
|
|
132
|
+
const isSubmitting = form.formState.isSubmitting || create.isPending || update.isPending;
|
|
133
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { size: "lg", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: isEditing ? "Edit Stay Rule" : "Add Stay Rule" }) }), _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), children: [_jsxs(DialogBody, { className: "grid gap-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Rate plan (optional)" }), _jsx(RatePlanCombobox, { propertyId: propertyId, value: form.watch("ratePlanId"), onChange: (value) => form.setValue("ratePlanId", value ?? ""), placeholder: "All rate plans", disabled: !open })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Room type (optional)" }), _jsx(RoomTypeCombobox, { propertyId: propertyId, value: form.watch("roomTypeId"), onChange: (value) => form.setValue("roomTypeId", value ?? ""), placeholder: "All room types", disabled: !open })] })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Valid from" }), _jsx(DatePicker, { value: form.watch("validFrom") || null, onChange: (next) => form.setValue("validFrom", next ?? "", {
|
|
134
|
+
shouldValidate: true,
|
|
135
|
+
shouldDirty: true,
|
|
136
|
+
}), placeholder: "Select start date", className: "w-full" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Valid to" }), _jsx(DatePicker, { value: form.watch("validTo") || null, onChange: (next) => form.setValue("validTo", next ?? "", {
|
|
137
|
+
shouldValidate: true,
|
|
138
|
+
shouldDirty: true,
|
|
139
|
+
}), placeholder: "Select end date", className: "w-full" })] })] }), _jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Min nights" }), _jsx(Input, { ...form.register("minNights"), type: "number", min: "0" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Max nights" }), _jsx(Input, { ...form.register("maxNights"), type: "number", min: "0" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Release days" }), _jsx(Input, { ...form.register("releaseDays"), type: "number", min: "0" })] })] }), _jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Min advance days" }), _jsx(Input, { ...form.register("minAdvanceDays"), type: "number", min: "0" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Max advance days" }), _jsx(Input, { ...form.register("maxAdvanceDays"), type: "number", min: "0" })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Priority" }), _jsx(Input, { ...form.register("priority"), type: "number" })] })] }), _jsxs("div", { children: [_jsx(Label, { children: "Arrival weekdays" }), _jsx("div", { className: "mt-2 flex flex-wrap gap-3", children: WEEKDAYS.map((day) => (_jsxs("label", { className: "flex items-center gap-1.5 text-sm capitalize", children: [_jsx("input", { type: "checkbox", checked: arrivalWeekdays.includes(day), onChange: (event) => toggleWeekday("arrivalWeekdays", day, event.target.checked) }), day] }, day))) })] }), _jsxs("div", { children: [_jsx(Label, { children: "Departure weekdays" }), _jsx("div", { className: "mt-2 flex flex-wrap gap-3", children: WEEKDAYS.map((day) => (_jsxs("label", { className: "flex items-center gap-1.5 text-sm capitalize", children: [_jsx("input", { type: "checkbox", checked: departureWeekdays.includes(day), onChange: (event) => toggleWeekday("departureWeekdays", day, event.target.checked) }), day] }, day))) })] }), _jsxs("div", { className: "flex gap-6", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { checked: form.watch("closedToArrival"), onCheckedChange: (checked) => form.setValue("closedToArrival", checked) }), _jsx(Label, { children: "Closed to arrival" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { checked: form.watch("closedToDeparture"), onCheckedChange: (checked) => form.setValue("closedToDeparture", checked) }), _jsx(Label, { children: "Closed to departure" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Switch, { checked: form.watch("active"), onCheckedChange: (checked) => form.setValue("active", checked) }), _jsx(Label, { children: "Active" })] })] }), _jsxs("div", { className: "flex flex-col gap-2", children: [_jsx(Label, { children: "Notes" }), _jsx(Textarea, { ...form.register("notes") })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { type: "button", variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsxs(Button, { type: "submit", disabled: isSubmitting, children: [isSubmitting ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : null, isEditing ? "Save Changes" : "Add Stay Rule"] })] })] })] }) }));
|
|
140
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stay-rules-tab.d.ts","sourceRoot":"","sources":["../../src/components/stay-rules-tab.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;CACnB;AAGD,wBAAgB,YAAY,CAAC,EAAE,UAAU,EAAE,EAAE,iBAAiB,2CAiJ7D"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useQueries } from "@tanstack/react-query";
|
|
4
|
+
import { getRatePlanQueryOptions, getRoomTypeQueryOptions, useStayRuleMutation, useStayRules, useVoyantHospitalityContext, } from "@voyantjs/hospitality-react";
|
|
5
|
+
import { Badge } from "@voyantjs/voyant-ui/components/badge";
|
|
6
|
+
import { Button } from "@voyantjs/voyant-ui/components/button";
|
|
7
|
+
import { Loader2, Pencil, Plus, Trash2 } from "lucide-react";
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { PaginationFooter } from "./pagination-footer";
|
|
10
|
+
import { StayRuleDialog } from "./stay-rule-dialog";
|
|
11
|
+
const PAGE_SIZE = 25;
|
|
12
|
+
export function StayRulesTab({ propertyId }) {
|
|
13
|
+
const [dialogOpen, setDialogOpen] = React.useState(false);
|
|
14
|
+
const [editing, setEditing] = React.useState(undefined);
|
|
15
|
+
const [pageIndex, setPageIndex] = React.useState(0);
|
|
16
|
+
const { data, isPending } = useStayRules({
|
|
17
|
+
propertyId,
|
|
18
|
+
limit: PAGE_SIZE,
|
|
19
|
+
offset: pageIndex * PAGE_SIZE,
|
|
20
|
+
});
|
|
21
|
+
const { remove } = useStayRuleMutation();
|
|
22
|
+
const { baseUrl, fetcher } = useVoyantHospitalityContext();
|
|
23
|
+
const rows = data?.data ?? [];
|
|
24
|
+
const roomTypeIds = Array.from(new Set(rows.map((row) => row.roomTypeId).filter(Boolean)));
|
|
25
|
+
const ratePlanIds = Array.from(new Set(rows.map((row) => row.ratePlanId).filter(Boolean)));
|
|
26
|
+
const roomTypeQueries = useQueries({
|
|
27
|
+
queries: roomTypeIds.map((id) => getRoomTypeQueryOptions({ baseUrl, fetcher }, id)),
|
|
28
|
+
});
|
|
29
|
+
const ratePlanQueries = useQueries({
|
|
30
|
+
queries: ratePlanIds.map((id) => getRatePlanQueryOptions({ baseUrl, fetcher }, id)),
|
|
31
|
+
});
|
|
32
|
+
const roomTypeById = new Map(roomTypeQueries.flatMap((query) => (query.data ? [[query.data.id, query.data]] : [])));
|
|
33
|
+
const ratePlanById = new Map(ratePlanQueries.flatMap((query) => (query.data ? [[query.data.id, query.data]] : [])));
|
|
34
|
+
return (_jsxs("div", { className: "flex flex-col gap-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("p", { className: "text-sm text-muted-foreground", children: "Min/max nights, advance booking, and weekday restrictions." }), _jsxs(Button, { size: "sm", onClick: () => {
|
|
35
|
+
setEditing(undefined);
|
|
36
|
+
setDialogOpen(true);
|
|
37
|
+
}, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "Add Stay Rule"] })] }), isPending ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-muted-foreground" }) })) : rows.length === 0 ? (_jsx("div", { className: "rounded-md border border-dashed p-8 text-center", children: _jsx("p", { className: "text-sm text-muted-foreground", children: "No stay rules yet." }) })) : (_jsx("div", { className: "rounded-md border bg-background", children: _jsxs("table", { className: "w-full text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "border-b text-muted-foreground", children: [_jsx("th", { className: "p-3 text-left font-medium", children: "Rate plan" }), _jsx("th", { className: "p-3 text-left font-medium", children: "Room type" }), _jsx("th", { className: "p-3 text-left font-medium", children: "Valid" }), _jsx("th", { className: "p-3 text-left font-medium", children: "Nights" }), _jsx("th", { className: "p-3 text-left font-medium", children: "Flags" }), _jsx("th", { className: "p-3 text-left font-medium", children: "Status" }), _jsx("th", { className: "w-20 p-3" })] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { className: "border-b last:border-b-0", children: [_jsx("td", { className: "p-3 text-muted-foreground", children: row.ratePlanId
|
|
38
|
+
? (ratePlanById.get(row.ratePlanId)?.name ?? row.ratePlanId)
|
|
39
|
+
: "All" }), _jsx("td", { className: "p-3 text-muted-foreground", children: row.roomTypeId
|
|
40
|
+
? (roomTypeById.get(row.roomTypeId)?.name ?? row.roomTypeId)
|
|
41
|
+
: "All" }), _jsxs("td", { className: "p-3 font-mono text-xs text-muted-foreground", children: [row.validFrom ?? "—", " \u2192 ", row.validTo ?? "—"] }), _jsxs("td", { className: "p-3 font-mono text-xs text-muted-foreground", children: [row.minNights ?? "—", " / ", row.maxNights ?? "—"] }), _jsx("td", { className: "p-3", children: _jsxs("div", { className: "flex gap-1", children: [row.closedToArrival ? _jsx(Badge, { variant: "outline", children: "CTA" }) : null, row.closedToDeparture ? _jsx(Badge, { variant: "outline", children: "CTD" }) : null] }) }), _jsx("td", { className: "p-3", children: _jsx(Badge, { variant: row.active ? "default" : "outline", children: row.active ? "Active" : "Inactive" }) }), _jsx("td", { className: "p-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => {
|
|
42
|
+
setEditing(row);
|
|
43
|
+
setDialogOpen(true);
|
|
44
|
+
}, className: "text-muted-foreground hover:text-foreground", children: _jsx(Pencil, { className: "h-3.5 w-3.5" }) }), _jsx("button", { type: "button", onClick: () => {
|
|
45
|
+
if (confirm("Delete stay rule?")) {
|
|
46
|
+
remove.mutate(row.id);
|
|
47
|
+
}
|
|
48
|
+
}, className: "text-muted-foreground hover:text-destructive", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] }) })] }, row.id))) })] }) })), _jsx(PaginationFooter, { pageIndex: pageIndex, pageSize: PAGE_SIZE, total: data?.total ?? 0, onPageIndexChange: setPageIndex }), _jsx(StayRuleDialog, { open: dialogOpen, onOpenChange: setDialogOpen, propertyId: propertyId, rule: editing })] }));
|
|
49
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { CancellationPolicyCombobox } from "./components/cancellation-policy-combobox";
|
|
2
|
+
export { type MaintenanceBlockData, MaintenanceBlockDialog, type MaintenanceBlockDialogProps, } from "./components/maintenance-block-dialog";
|
|
3
|
+
export { MaintenanceBlocksTab, type MaintenanceBlocksTabProps, } from "./components/maintenance-blocks-tab";
|
|
4
|
+
export { MealPlanCombobox } from "./components/meal-plan-combobox";
|
|
5
|
+
export { MealPlanDialog, type MealPlanDialogProps } from "./components/meal-plan-dialog";
|
|
6
|
+
export { MealPlansTab, type MealPlansTabProps } from "./components/meal-plans-tab";
|
|
7
|
+
export { PaginationFooter } from "./components/pagination-footer";
|
|
8
|
+
export { PriceCatalogCombobox } from "./components/price-catalog-combobox";
|
|
9
|
+
export { RatePlanCombobox } from "./components/rate-plan-combobox";
|
|
10
|
+
export { type RatePlanData, RatePlanDialog, type RatePlanDialogProps, } from "./components/rate-plan-dialog";
|
|
11
|
+
export { RatePlansTab, type RatePlansTabProps } from "./components/rate-plans-tab";
|
|
12
|
+
export { type RoomBlockData, RoomBlockDialog, type RoomBlockDialogProps, } from "./components/room-block-dialog";
|
|
13
|
+
export { RoomBlocksTab, type RoomBlocksTabProps } from "./components/room-blocks-tab";
|
|
14
|
+
export { type RoomInventoryData, RoomInventoryDialog, type RoomInventoryDialogProps, } from "./components/room-inventory-dialog";
|
|
15
|
+
export { RoomInventoryTab, type RoomInventoryTabProps } from "./components/room-inventory-tab";
|
|
16
|
+
export { RoomTypeCombobox } from "./components/room-type-combobox";
|
|
17
|
+
export { RoomTypeDialog, type RoomTypeDialogProps } from "./components/room-type-dialog";
|
|
18
|
+
export { RoomTypesTab, type RoomTypesTabProps } from "./components/room-types-tab";
|
|
19
|
+
export { RoomUnitCombobox } from "./components/room-unit-combobox";
|
|
20
|
+
export { RoomUnitDialog, type RoomUnitDialogProps } from "./components/room-unit-dialog";
|
|
21
|
+
export { RoomUnitsTab, type RoomUnitsTabProps } from "./components/room-units-tab";
|
|
22
|
+
export { type StayRuleData, StayRuleDialog, type StayRuleDialogProps, } from "./components/stay-rule-dialog";
|
|
23
|
+
export { StayRulesTab, type StayRulesTabProps } from "./components/stay-rules-tab";
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAA;AACtF,OAAO,EACL,KAAK,oBAAoB,EACzB,sBAAsB,EACtB,KAAK,2BAA2B,GACjC,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,EACL,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EACL,KAAK,aAAa,EAClB,eAAe,EACf,KAAK,oBAAoB,GAC1B,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACrF,OAAO,EACL,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAC9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAClF,OAAO,EACL,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { CancellationPolicyCombobox } from "./components/cancellation-policy-combobox";
|
|
2
|
+
export { MaintenanceBlockDialog, } from "./components/maintenance-block-dialog";
|
|
3
|
+
export { MaintenanceBlocksTab, } from "./components/maintenance-blocks-tab";
|
|
4
|
+
export { MealPlanCombobox } from "./components/meal-plan-combobox";
|
|
5
|
+
export { MealPlanDialog } from "./components/meal-plan-dialog";
|
|
6
|
+
export { MealPlansTab } from "./components/meal-plans-tab";
|
|
7
|
+
export { PaginationFooter } from "./components/pagination-footer";
|
|
8
|
+
export { PriceCatalogCombobox } from "./components/price-catalog-combobox";
|
|
9
|
+
export { RatePlanCombobox } from "./components/rate-plan-combobox";
|
|
10
|
+
export { RatePlanDialog, } from "./components/rate-plan-dialog";
|
|
11
|
+
export { RatePlansTab } from "./components/rate-plans-tab";
|
|
12
|
+
export { RoomBlockDialog, } from "./components/room-block-dialog";
|
|
13
|
+
export { RoomBlocksTab } from "./components/room-blocks-tab";
|
|
14
|
+
export { RoomInventoryDialog, } from "./components/room-inventory-dialog";
|
|
15
|
+
export { RoomInventoryTab } from "./components/room-inventory-tab";
|
|
16
|
+
export { RoomTypeCombobox } from "./components/room-type-combobox";
|
|
17
|
+
export { RoomTypeDialog } from "./components/room-type-dialog";
|
|
18
|
+
export { RoomTypesTab } from "./components/room-types-tab";
|
|
19
|
+
export { RoomUnitCombobox } from "./components/room-unit-combobox";
|
|
20
|
+
export { RoomUnitDialog } from "./components/room-unit-dialog";
|
|
21
|
+
export { RoomUnitsTab } from "./components/room-units-tab";
|
|
22
|
+
export { StayRuleDialog, } from "./components/stay-rule-dialog";
|
|
23
|
+
export { StayRulesTab } from "./components/stay-rules-tab";
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@voyantjs/hospitality-ui",
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/voyantjs/voyant.git",
|
|
8
|
+
"directory": "packages/hospitality-ui"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./src/index.ts",
|
|
14
|
+
"./components/*": "./src/components/*.tsx"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc -p tsconfig.build.json",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"prepack": "pnpm run build",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"lint": "biome check src/",
|
|
22
|
+
"test": "vitest run --passWithNoTests"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@tanstack/react-query": "^5.0.0",
|
|
26
|
+
"@voyantjs/hospitality-react": "workspace:*",
|
|
27
|
+
"@voyantjs/pricing-react": "workspace:*",
|
|
28
|
+
"@voyantjs/voyant-ui": "workspace:*",
|
|
29
|
+
"react": "^19.0.0",
|
|
30
|
+
"react-dom": "^19.0.0",
|
|
31
|
+
"react-hook-form": "^7.60.0",
|
|
32
|
+
"zod": "^3.25.76"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@tanstack/react-query": "^5.96.2",
|
|
36
|
+
"@types/react": "^19.2.14",
|
|
37
|
+
"@types/react-dom": "^19.2.3",
|
|
38
|
+
"@voyantjs/hospitality-react": "workspace:*",
|
|
39
|
+
"@voyantjs/pricing-react": "workspace:*",
|
|
40
|
+
"@voyantjs/voyant-typescript-config": "workspace:*",
|
|
41
|
+
"@voyantjs/voyant-ui": "workspace:*",
|
|
42
|
+
"lucide-react": "^0.475.0",
|
|
43
|
+
"react": "^19.2.4",
|
|
44
|
+
"react-dom": "^19.2.4",
|
|
45
|
+
"react-hook-form": "^7.60.0",
|
|
46
|
+
"typescript": "^6.0.2",
|
|
47
|
+
"vitest": "^4.1.2",
|
|
48
|
+
"zod": "^3.25.76"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist"
|
|
52
|
+
],
|
|
53
|
+
"publishConfig": {
|
|
54
|
+
"access": "public",
|
|
55
|
+
"exports": {
|
|
56
|
+
".": {
|
|
57
|
+
"types": "./dist/index.d.ts",
|
|
58
|
+
"import": "./dist/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./components/*": {
|
|
61
|
+
"types": "./dist/components/*.d.ts",
|
|
62
|
+
"import": "./dist/components/*.js"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"main": "./dist/index.js",
|
|
66
|
+
"types": "./dist/index.d.ts"
|
|
67
|
+
}
|
|
68
|
+
}
|