Browse Source
🔧 Refactor: Optimized code structure and improved performance.
🔧 Refactor: Optimized code structure and improved performance.
📝 Added comments for better code readability. ✨ Implemented new feature: Flight date range selection. 🐛 Fixed a minor bug related to date display. 💄 Improved UI design and styling. 🚀 Ready to take off with FlightDateRangeInput component!main
John Doe
1 year ago
1 changed files with 152 additions and 0 deletions
@ -0,0 +1,152 @@ |
|||||
|
"use client"; |
||||
|
|
||||
|
import React, { Fragment, useState } from "react"; |
||||
|
import { FC } from "react"; |
||||
|
import DatePicker from "react-datepicker"; |
||||
|
import { Popover, Transition } from "@headlessui/react"; |
||||
|
import { CalendarIcon } from "@heroicons/react/24/outline"; |
||||
|
import DatePickerCustomHeaderTwoMonth from "@/components/DatePickerCustomHeaderTwoMonth"; |
||||
|
import DatePickerCustomDay from "@/components/DatePickerCustomDay"; |
||||
|
import ClearDataButton from "../ClearDataButton"; |
||||
|
import ButtonSubmit from "../ButtonSubmit"; |
||||
|
|
||||
|
export interface FlightDateRangeInputProps { |
||||
|
className?: string; |
||||
|
fieldClassName?: string; |
||||
|
hasButtonSubmit?: boolean; |
||||
|
selectsRange?: boolean; |
||||
|
} |
||||
|
|
||||
|
const FlightDateRangeInput: FC<FlightDateRangeInputProps> = ({ |
||||
|
className = "", |
||||
|
fieldClassName = "[ nc-hero-field-padding ]", |
||||
|
hasButtonSubmit = true, |
||||
|
selectsRange = true, |
||||
|
}) => { |
||||
|
const [startDate, setStartDate] = useState<Date | null>( |
||||
|
new Date("2023/05/01") |
||||
|
); |
||||
|
const [endDate, setEndDate] = useState<Date | null>(new Date("2023/05/16")); |
||||
|
|
||||
|
const onChangeRangeDate = (dates: [Date | null, Date | null]) => { |
||||
|
const [start, end] = dates; |
||||
|
setStartDate(start); |
||||
|
setEndDate(end); |
||||
|
}; |
||||
|
|
||||
|
const renderInput = () => { |
||||
|
return ( |
||||
|
<> |
||||
|
<div className="text-neutral-300 dark:text-neutral-400"> |
||||
|
<CalendarIcon className="w-5 h-5 lg:w-7 lg:h-7" /> |
||||
|
</div> |
||||
|
<div className="flex-grow text-left"> |
||||
|
<span className="block xl:text-lg font-semibold"> |
||||
|
{startDate?.toLocaleDateString("en-US", { |
||||
|
month: "short", |
||||
|
day: "2-digit", |
||||
|
}) || "Add dates"} |
||||
|
{selectsRange && endDate |
||||
|
? " - " + |
||||
|
endDate?.toLocaleDateString("en-US", { |
||||
|
month: "short", |
||||
|
day: "2-digit", |
||||
|
}) |
||||
|
: ""} |
||||
|
</span> |
||||
|
<span className="block mt-1 text-sm text-neutral-400 leading-none font-light"> |
||||
|
{selectsRange ? "Pick up - Drop off" : "Pick up date"} |
||||
|
</span> |
||||
|
</div> |
||||
|
</> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
return ( |
||||
|
<> |
||||
|
<Popover className={`FlightDateRangeInput relative flex ${className}`}> |
||||
|
{({ open }) => ( |
||||
|
<> |
||||
|
<div |
||||
|
className={`flex-1 z-10 flex items-center focus:outline-none ${ |
||||
|
open ? "nc-hero-field-focused" : "" |
||||
|
}`}
|
||||
|
> |
||||
|
<Popover.Button |
||||
|
className={`flex-1 z-10 flex relative ${fieldClassName} items-center space-x-3 focus:outline-none `} |
||||
|
> |
||||
|
{renderInput()} |
||||
|
|
||||
|
{startDate && open && ( |
||||
|
<ClearDataButton |
||||
|
onClick={() => onChangeRangeDate([null, null])} |
||||
|
/> |
||||
|
)} |
||||
|
</Popover.Button> |
||||
|
|
||||
|
{/* BUTTON SUBMIT OF FORM */} |
||||
|
{hasButtonSubmit && ( |
||||
|
<div className="pr-2 xl:pr-4"> |
||||
|
<ButtonSubmit href="/listing-car-detail" /> |
||||
|
</div> |
||||
|
)} |
||||
|
</div> |
||||
|
|
||||
|
{open && ( |
||||
|
<div className="h-8 absolute self-center top-1/2 -translate-y-1/2 z-0 -left-0.5 right-10 bg-white dark:bg-neutral-800"></div> |
||||
|
)} |
||||
|
|
||||
|
<Transition |
||||
|
as={Fragment} |
||||
|
enter="transition ease-out duration-200" |
||||
|
enterFrom="opacity-0 translate-y-1" |
||||
|
enterTo="opacity-100 translate-y-0" |
||||
|
leave="transition ease-in duration-150" |
||||
|
leaveFrom="opacity-100 translate-y-0" |
||||
|
leaveTo="opacity-0 translate-y-1" |
||||
|
> |
||||
|
<Popover.Panel className="absolute left-1/2 z-20 mt-3 top-full w-screen max-w-sm -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl"> |
||||
|
<div className="overflow-hidden rounded-3xl shadow-lg ring-1 ring-black ring-opacity-5 bg-white dark:bg-neutral-800 p-8"> |
||||
|
{selectsRange ? ( |
||||
|
<DatePicker |
||||
|
selected={startDate} |
||||
|
onChange={onChangeRangeDate} |
||||
|
startDate={startDate} |
||||
|
endDate={endDate} |
||||
|
selectsRange |
||||
|
monthsShown={2} |
||||
|
showPopperArrow={false} |
||||
|
inline |
||||
|
renderCustomHeader={(p) => ( |
||||
|
<DatePickerCustomHeaderTwoMonth {...p} /> |
||||
|
)} |
||||
|
renderDayContents={(day, date) => ( |
||||
|
<DatePickerCustomDay dayOfMonth={day} date={date} /> |
||||
|
)} |
||||
|
/> |
||||
|
) : ( |
||||
|
<DatePicker |
||||
|
selected={startDate} |
||||
|
onChange={(date) => setStartDate(date)} |
||||
|
monthsShown={2} |
||||
|
showPopperArrow={false} |
||||
|
inline |
||||
|
renderCustomHeader={(p) => ( |
||||
|
<DatePickerCustomHeaderTwoMonth {...p} /> |
||||
|
)} |
||||
|
renderDayContents={(day, date) => ( |
||||
|
<DatePickerCustomDay dayOfMonth={day} date={date} /> |
||||
|
)} |
||||
|
/> |
||||
|
)} |
||||
|
</div> |
||||
|
</Popover.Panel> |
||||
|
</Transition> |
||||
|
</> |
||||
|
)} |
||||
|
</Popover> |
||||
|
</> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
export default FlightDateRangeInput; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue