Skip to content

Commit 7171239

Browse files
authored
feat: add timescape for handling the input of dates (#394)
* feat: add `timescape` * feat: add a function to generate a simple random id * feat: add timescape input * fix: applying the api changes to the datepicker inputs * fix: remove the readonly styles * chore: sync api for readonly * feat: selection based style with ring on the root * duration grid * feat: move the time selector on the same popover * chore: bump timescape to 0.5.0
1 parent 496aca4 commit 7171239

File tree

9 files changed

+393
-377
lines changed

9 files changed

+393
-377
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
"recharts": "2.13.0-alpha.4",
7575
"sonner": "^1.5.0",
7676
"tailwind-merge": "^2.4.0",
77+
"timescape": "^0.5.0",
7778
"zod": "^3.23.8"
7879
},
7980
"devDependencies": {

pnpm-lock.yaml

+34
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/add-rental/customer-information/customer-stage.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,7 @@ export const CustomerStage = ({
227227
readOnly
228228
>
229229
<FormControl>
230-
<InputDatePickerSlot
231-
placeholder={tl("display.dateOfBirth")}
232-
/>
230+
<InputDatePickerSlot />
233231
</FormControl>
234232
</InputDatePicker>
235233
<FormMessage />

src/components/add-rental/rental-information/duration-stage.tsx

+29-21
Original file line numberDiff line numberDiff line change
@@ -160,23 +160,33 @@ export const DurationStage = ({
160160
name: "checkinDate",
161161
});
162162

163-
const handleCheckoutDateChange = (date: Date) => {
164-
const previousCheckoutDate = form_checkoutDate;
165-
const previousCheckinDate = form_checkinDate;
163+
const handleCheckoutDateChange = React.useCallback(
164+
(date: Date | undefined) => {
165+
if (date === undefined) return;
166166

167-
const diffMinsBetweenDates = differenceInMinutes(
168-
previousCheckinDate,
169-
previousCheckoutDate
170-
);
171-
const checkin = add(date, {
172-
minutes: diffMinsBetweenDates,
173-
});
174-
form.setValue("checkoutDate", date, { shouldValidate: true });
175-
form.setValue("checkinDate", checkin, { shouldValidate: true });
176-
};
177-
const handleCheckinDateChange = (date: Date) => {
178-
form.setValue("checkinDate", date, { shouldValidate: true });
179-
};
167+
const previousCheckoutDate = form_checkoutDate;
168+
const previousCheckinDate = form_checkinDate;
169+
170+
const diffMinsBetweenDates = differenceInMinutes(
171+
previousCheckinDate,
172+
previousCheckoutDate
173+
);
174+
const checkin = add(date, {
175+
minutes: diffMinsBetweenDates,
176+
});
177+
form.setValue("checkoutDate", date, { shouldValidate: true });
178+
form.setValue("checkinDate", checkin, { shouldValidate: true });
179+
},
180+
[form, form_checkinDate, form_checkoutDate]
181+
);
182+
const handleCheckinDateChange = React.useCallback(
183+
(date: Date | undefined) => {
184+
if (date === undefined) return;
185+
186+
form.setValue("checkinDate", date, { shouldValidate: true });
187+
},
188+
[form]
189+
);
180190

181191
React.useEffect(() => {
182192
if (agreementNumberQuery.status !== "success") return;
@@ -198,7 +208,7 @@ export const DurationStage = ({
198208
className="flex flex-col gap-4 px-1 pt-4"
199209
autoComplete="off"
200210
>
201-
<div className="grid gap-4 md:grid-cols-3">
211+
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
202212
<div>
203213
<FormField
204214
control={form.control}
@@ -270,10 +280,9 @@ export const DurationStage = ({
270280
mode="datetime"
271281
format={dateTimeFormat}
272282
timeFormat={timeFormat}
273-
required
274283
>
275284
<FormControl>
276-
<InputDatePickerSlot placeholder="Checkout date" />
285+
<InputDatePickerSlot />
277286
</FormControl>
278287
</InputDatePicker>
279288
<FormMessage />
@@ -322,10 +331,9 @@ export const DurationStage = ({
322331
mode="datetime"
323332
format={dateTimeFormat}
324333
timeFormat={timeFormat}
325-
required
326334
>
327335
<FormControl>
328-
<InputDatePickerSlot placeholder="Checkin date" />
336+
<InputDatePickerSlot />
329337
</FormControl>
330338
</InputDatePicker>
331339
<FormMessage />

src/components/ui/form.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
FieldPath,
88
FieldValues,
99
FormProvider,
10+
useController,
1011
useFormContext,
1112
} from "react-hook-form";
1213

@@ -43,9 +44,11 @@ const FormField = <
4344
const useFormField = () => {
4445
const fieldContext = React.useContext(FormFieldContext);
4546
const itemContext = React.useContext(FormItemContext);
46-
const { getFieldState, formState } = useFormContext();
47+
const { getFieldState, formState, setFocus, control, trigger } =
48+
useFormContext();
4749

4850
const fieldState = getFieldState(fieldContext.name, formState);
51+
const formControl = useController({ control, name: fieldContext.name });
4952

5053
if (!fieldContext) {
5154
throw new Error("useFormField should be used within <FormField>");
@@ -60,6 +63,9 @@ const useFormField = () => {
6063
formDescriptionId: `${id}-form-item-description`,
6164
formMessageId: `${id}-form-item-message`,
6265
...fieldState,
66+
onBlur: formControl.field.onBlur,
67+
onFocus: () => setFocus(fieldContext.name),
68+
trigger: () => trigger(fieldContext.name),
6369
};
6470
};
6571

0 commit comments

Comments
 (0)