Skip to content

Commit

Permalink
create search modal
Browse files Browse the repository at this point in the history
  • Loading branch information
ocitocit committed Oct 16, 2023
1 parent d633541 commit a27cd4e
Showing 1 changed file with 192 additions and 0 deletions.
192 changes: 192 additions & 0 deletions components/modals/SearchModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
'use client';

import qs from 'query-string';
import useSearchModal from "@/hooks/useSearchModal";
import Modal from "./Modal";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useMemo, useState } from "react";
import { Range } from "react-date-range";
import dynamic from "next/dynamic";
import CountrySelect, { CountrySelectValue } from "../inputs/CountrySelect";
import { formatISO } from 'date-fns';
import Heading from '../Heading';
import Calendar from '../inputs/Calendar';
import Counter from '../inputs/Counter';

enum STEPS {
LOCATION = 0,
DATE = 1,
INFO = 2
}

const SearchModal = () => {
const router = useRouter();
const params = useSearchParams();
const searchModal = useSearchModal();

const [location, setLocation] = useState<CountrySelectValue>();
const [step, setStep] = useState(STEPS.LOCATION);
const [guestCount, setGuestCount] = useState(1);
const [roomCount, setRoomCount] = useState(1);
const [bathroomCount, setBathroomCount] = useState(1);
const [dateRange, setDateRange] = useState<Range>({
startDate: new Date(),
endDate: new Date(),
key: 'selection'
});

const Map = useMemo(() => dynamic(() => import('../Map'), {
ssr: false
}), [location])

const onBack = useCallback(() => {
setStep((value) => value - 1)
}, []);

const onNext = useCallback(() => {
setStep((value) => value + 1)
}, []);

const onSubmit = useCallback(async () => {
if (step !== STEPS.INFO) {
return onNext();
}

let currentQuery = {};

if (params) {
currentQuery = qs.parse(params.toString());
}

const updatedQuery: any = {
...currentQuery,
locationValue: location?.value,
guestCount,
roomCount,
bathroomCount
};

if (dateRange.startDate) {
updatedQuery.startDate = formatISO(dateRange.startDate);
}

if (dateRange.endDate) {
updatedQuery.endDate = formatISO(dateRange.endDate);
}

const url = qs.stringifyUrl({
url: '/',
query: updatedQuery
}, { skipNull: true });

setStep(STEPS.LOCATION);
searchModal.onClose();

router.push(url);
}, [
step,
searchModal,
location,
router,
guestCount,
bathroomCount,
roomCount,
dateRange,
onNext,
params
]);

const actionLabel = useMemo(() => {
if (step === STEPS.INFO) {
return 'Search';
}

return 'Next';
}, [step]);

const secondaryActionLabel = useMemo(() => {
if (step === STEPS.LOCATION) {
return undefined;
}

return 'Back';
}, [step]);

let bodyContent = (
<div className='flex flex-col gap-8'>
<Heading
title='Where do you wanna go?'
subTitle='Find the perfect location!'
/>
<CountrySelect
value={location}
onChange={(value) => {
setLocation(value as CountrySelectValue)
}}
/>
<hr />
<Map center={location?.latlng} />
</div>
);

if (step === STEPS.DATE) {
bodyContent = (
<div className='flex flex-col gap-8'>
<Heading
title='When do you plan to go?'
subTitle='Make everyone is free!'
/>
<Calendar
value={dateRange}
onChange={(value) => setDateRange(value.selection)}
/>
</div>
)
};

if (step === STEPS.INFO) {
bodyContent = (
<div className='flex flex-col gap-8'>
<Heading
title='More information'
subTitle='Find your perfect place!'
/>
<Counter
title='Guests'
subtitle='How many guest are coming?'
value={guestCount}
onChange={(value) => setGuestCount(value)}
/>
<hr />
<Counter
title='Rooms'
subtitle='How many rooms do you need?'
value={roomCount}
onChange={(value) => setRoomCount(value)}
/>
<hr />
<Counter
title='Bathrooms'
subtitle='How many Bathrooms do you need?'
value={bathroomCount}
onChange={(value) => setBathroomCount(value)}
/>
</div>
)
};

return (
<Modal
isOpen={searchModal.isOpen}
onClose={searchModal.onClose}
onSubmit={onSubmit}
title="Filters"
actionLabel={actionLabel}
secondaryAction={step === STEPS.LOCATION ? undefined : onBack}
secondaryActionLabel={secondaryActionLabel}
body={bodyContent}
/>
);
};

export default SearchModal

0 comments on commit a27cd4e

Please sign in to comment.