diff --git a/.DS_Store b/.DS_Store index ac395b4..69ac4dc 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/src/components/card/Card.jsx b/src/components/card/Card.jsx index d0da14f..008fdfb 100644 --- a/src/components/card/Card.jsx +++ b/src/components/card/Card.jsx @@ -7,7 +7,12 @@ import './card.css'; const Card = ({ name, place, image, startDate, endDate }) => { const [imgError, setImgError] = useState(false); return ( -
  • +
  • { + console.log('laks'); + }} + >
    {!imgError ? ( { const day = date.getDate(); @@ -21,8 +22,17 @@ const dateConverter = (date) => { }; export const CustomCalendar = () => { - const { searchDate, setSearchDate, setStartDateSpan, setEndDateSpan, isSingleDate, widgetProp } = - useContext(WidgetContext); + const { + searchDate, + setSearchDate, + setStartDateSpan, + setEndDateSpan, + isSingleDate, + widgetProp, + displayType, + calendarModalToggle, + setCalendarModalToggle, + } = useContext(WidgetContext); const [activeStartDate, setActiveStartDate] = useState(); const [view, setView] = useState('month'); @@ -43,6 +53,8 @@ export const CustomCalendar = () => { const searchDateHandler = (value) => { sessionStorage.setItem(sessionStorageVariableNames.WidgetSearchDate, value); setSearchDate(value); + + setCalendarModalToggle(!calendarModalToggle); if (!isSingleDate) { const selectedDate = dateConverter(new Date(value)); setStartDateSpan(selectedDate); @@ -89,7 +101,10 @@ export const CustomCalendar = () => { }; return ( -
    +
    .widget-layout .react-calendar-wrapper .react-calendar__tile--now:enabled:hover, +#calendar-widget > .widget-layout .react-calendar-wrapper .react-calendar__tile--now:enabled:focus, +#calendar-widget > .widget-layout .react-calendar-wrapper .react-calendar__tile:enabled:hover, +#calendar-widget > .widget-layout .react-calendar-wrapper .react-calendar__tile:enabled:focus { + background: var(--dynamic-color-100); +} + #calendar-widget > .widget-layout .react-calendar-wrapper @@ -87,6 +94,11 @@ color: #222732; } +#calendar-widget > .widget-layout .react-calendar-wrapper .react-calendar__tile--hasActive { + background: var(--dynamic-color-600) !important; + color: var(--primary-white-opaque) !important; +} + #calendar-widget > .widget-layout .react-calendar-wrapper .react-calendar__navigation__prev2-button, #calendar-widget > .widget-layout diff --git a/src/components/loader/Loader.jsx b/src/components/loader/Loader.jsx new file mode 100644 index 0000000..cae6c4e --- /dev/null +++ b/src/components/loader/Loader.jsx @@ -0,0 +1,8 @@ +import React from 'react'; +import './loader.css'; + +const Loader = () => { + return ; +}; + +export default Loader; diff --git a/src/components/loader/loader.css b/src/components/loader/loader.css new file mode 100644 index 0000000..02e8231 --- /dev/null +++ b/src/components/loader/loader.css @@ -0,0 +1,101 @@ +#calendar-widget > .widget-layout .loader { + font-size: 10px; + width: 1em; + height: 1em; + border-radius: 50%; + position: relative; + text-indent: -9999em; + animation: mulShdSpin 1.1s infinite ease; + transform: translateZ(0); +} +@keyframes mulShdSpin { + 0%, + 100% { + box-shadow: + 0em -2.6em 0em 0em #ffffff, + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.2), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.2), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.2), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.2), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.5), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.7); + } + 12.5% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.7), + 1.8em -1.8em 0 0em #ffffff, + 2.5em 0em 0 0em var(--dynamic-color-500, 0.2), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.2), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.2), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.2), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.2), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.5); + } + 25% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.5), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.7), + 2.5em 0em 0 0em #ffffff, + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.2), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.2), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.2), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.2), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2); + } + 37.5% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.2), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.5), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.7), + 1.75em 1.75em 0 0em #ffffff, + 0em 2.5em 0 0em var(--dynamic-color-500, 0.2), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.2), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.2), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2); + } + 50% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.2), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.5), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.7), + 0em 2.5em 0 0em #ffffff, + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.2), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.2), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2); + } + 62.5% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.2), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.2), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.5), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.7), + -1.8em 1.8em 0 0em #ffffff, + -2.6em 0em 0 0em var(--dynamic-color-500, 0.2), + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2); + } + 75% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.2), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.2), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.2), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.5), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.7), + -2.6em 0em 0 0em #ffffff, + -1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2); + } + 87.5% { + box-shadow: + 0em -2.6em 0em 0em var(--dynamic-color-500, 0.2), + 1.8em -1.8em 0 0em var(--dynamic-color-500, 0.2), + 2.5em 0em 0 0em var(--dynamic-color-500, 0.2), + 1.75em 1.75em 0 0em var(--dynamic-color-500, 0.2), + 0em 2.5em 0 0em var(--dynamic-color-500, 0.2), + -1.8em 1.8em 0 0em var(--dynamic-color-500, 0.5), + -2.6em 0em 0 0em var(--dynamic-color-500, 0.7), + -1.8em -1.8em 0 0em #ffffff; + } +} diff --git a/src/components/panel/Panel.jsx b/src/components/panel/Panel.jsx index add39c0..cb163f8 100644 --- a/src/components/panel/Panel.jsx +++ b/src/components/panel/Panel.jsx @@ -1,28 +1,68 @@ -import React, { useContext } from 'react'; +import React, { useContext, useEffect, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { displayTypes } from '../../constants/generalConstants'; import WidgetContext from '../../context/WidgetContext'; import { CustomCalendar } from '../customCalendar/CustomCalendar'; +import Loader from '../loader/Loader'; import NoResult from '../noResult/NoResult'; import ResultHeader from '../resultHeader/ResultHeader'; import Results from '../results/Results'; import './panel.css'; const ResultPanel = () => { - const { displayType, totalCount } = useContext(WidgetContext); + const calendarModalRef = useRef(null); + + const { displayType, totalCount, calendarModalToggle, setCalendarModalToggle, isLoading } = + useContext(WidgetContext); const { t } = useTranslation(); + + const calendarPopOverHandler = () => { + setCalendarModalToggle(!calendarModalToggle); + }; + + useEffect(() => { + const handleOutsideClick = (event) => { + if ( + calendarModalRef.current && + !calendarModalRef.current.contains(event.target) && + calendarModalToggle + ) { + setCalendarModalToggle(false); + } + }; + + document.addEventListener('mousedown', handleOutsideClick); + + return () => { + document.removeEventListener('mousedown', handleOutsideClick); + }; + }, [calendarModalToggle]); + return (
    {displayType === displayTypes.MOBILE && (
    - + + {calendarModalToggle && ( +
    +
    + +
    +
    + )}
    )} -
    -
    {totalCount > 0 ? : }
    +
    0 ? {} : { alignItems: 'center' }}> + {!isLoading ? ( +
    {totalCount > 0 ? : }
    + ) : ( +
    + +
    + )} {displayType === displayTypes.DESKTOP && }
    diff --git a/src/components/panel/panel.css b/src/components/panel/panel.css index 7ae6c89..28c01ba 100644 --- a/src/components/panel/panel.css +++ b/src/components/panel/panel.css @@ -3,7 +3,7 @@ gap: 8px; width: 100%; justify-content: center; - align-items: center; + min-height: 100px; } #calendar-widget > .widget-layout .result-panel-wrapper .button-container { @@ -11,7 +11,13 @@ padding: 16px 0; } +#calendar-widget > .widget-layout .results { + width: 100%; +} + #calendar-widget > .widget-layout .result-panel-wrapper .button-container > button { + position: relative; + color: var(--dynamic-color-500); width: 100%; height: 40px; @@ -25,3 +31,32 @@ letter-spacing: 0em; text-align: center; } + +#calendar-widget > .widget-layout .result-panel-wrapper .button-container .calendar-modal-pivot { + width: 100%; + margin: 0 auto; + position: relative; + display: flex; + justify-content: flex-end; +} + +#calendar-widget + > .widget-layout + .result-panel-wrapper + .button-container + .calendar-modal-pivot + > .calendar-modal-wrapper { + position: absolute; + box-shadow: 0px 8px 32px 0px #00000033; + background-color: var(--primary-white-opaque); + + top: 10px; + z-index: 10; +} + +#calendar-widget > .widget-layout .result-panel-wrapper .loader-wrapper { + width: 100%; + min-height: 100%; + display: grid; + place-content: center; +} diff --git a/src/components/results/Results.jsx b/src/components/results/Results.jsx index b5243e9..d3ddeba 100644 --- a/src/components/results/Results.jsx +++ b/src/components/results/Results.jsx @@ -1,12 +1,14 @@ import React, { useContext } from 'react'; +import { displayTypes } from '../../constants/generalConstants'; import WidgetContext from '../../context/WidgetContext'; import Card from '../card/Card'; import './results.css'; const Results = () => { - const { data } = useContext(WidgetContext); - const screenHeight = window.screen.height - 270; + const { data, displayType } = useContext(WidgetContext); + const screenHeight = + displayType === displayTypes.DESKTOP ? window.screen.height - 275 : window.screen.height - 350; return (
      {data?.length > 0 && diff --git a/src/context/WidgetContext.js b/src/context/WidgetContext.js index e333a0e..68ba324 100644 --- a/src/context/WidgetContext.js +++ b/src/context/WidgetContext.js @@ -1,8 +1,8 @@ import { createContext, useCallback, useEffect, useState } from 'react'; import { entityTypes } from '../constants/generalConstants'; import { sessionStorageVariableNames } from '../constants/sessionStorageVariableNames'; -import { useSize } from '../hooks/useSize'; import { generateUrl } from '../utils/generateUrl'; +import { useSize } from '../utils/hooks/useSize'; import { transformData } from '../utils/transformData'; const WidgetContext = createContext(undefined); @@ -13,7 +13,6 @@ export const WidgetContextProvider = ({ widgetProps, children }) => { const [totalCount, setTotalCount] = useState(); const [error, setError] = useState(); const [searchKeyWord, setSearchKeyWord] = useState(''); - const [searchDate, setSearchDate] = useState(); const [startDateSpan, setStartDateSpan] = useState( sessionStorage.getItem(sessionStorageVariableNames.WidgetStartDate), @@ -22,6 +21,8 @@ export const WidgetContextProvider = ({ widgetProps, children }) => { sessionStorage.getItem(sessionStorageVariableNames.WidgetEndDate), ); const [isSingleDate, setIsSingleDate] = useState(); + const [calendarModalToggle, setCalendarModalToggle] = useState(false); // controls calendar as modal for mobile view + const [isLoading, setIsLoading] = useState(true); const displayType = useSize(); @@ -39,6 +40,7 @@ export const WidgetContextProvider = ({ widgetProps, children }) => { setData(transformData({ data, locale: widgetProps?.locale || 'en' })); setTotalCount(meta?.totalCount); + setIsLoading(false); } catch (error) { setError('Error fetching data'); console.error('Error fetching data:', error); @@ -46,9 +48,14 @@ export const WidgetContextProvider = ({ widgetProps, children }) => { }, [widgetProps, searchKeyWord, startDateSpan, endDateSpan]); useEffect(() => { + setIsLoading(true); getData(); }, [widgetProps, searchKeyWord, startDateSpan, endDateSpan]); + useEffect(() => { + calendarModalToggle && setCalendarModalToggle(false); + }, [startDateSpan, endDateSpan]); + return ( { endDateSpan, isSingleDate, displayType, + calendarModalToggle, + isLoading, getData, setSearchKeyWord, setSearchDate, setStartDateSpan, setEndDateSpan, setIsSingleDate, + setCalendarModalToggle, }} > {children} diff --git a/src/hooks/useSize.js b/src/utils/hooks/useSize.js similarity index 88% rename from src/hooks/useSize.js rename to src/utils/hooks/useSize.js index 3b9f2db..756c7b4 100644 --- a/src/hooks/useSize.js +++ b/src/utils/hooks/useSize.js @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { displayTypes } from '../constants/generalConstants'; +import { displayTypes } from '../../constants/generalConstants'; export const useSize = () => { const [size, setSize] = useState(window.innerWidth);