Skip to content

Commit

Permalink
Fix pattern selector
Browse files Browse the repository at this point in the history
  • Loading branch information
joao-vasconcelos committed Dec 4, 2023
1 parent 24254a9 commit 03c192d
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

/* * */

import useSWR from 'swr';
import { Combobox, TextInput, useCombobox, ActionIcon, Group } from '@mantine/core';
import { useEffect, useMemo, useState } from 'react';
import { useEffect, useState } from 'react';
import { useTranslations } from 'next-intl';
import styles from './LinesExplorerContentSelectPattern.module.css';
import useSearch from '@/hooks/useSearch';
Expand All @@ -25,18 +24,63 @@ export default function LinesExplorerContentSelectPattern() {
const linesExplorerContext = useLinesExplorerContext();
const comboboxStore = useCombobox();
const [searchQuery, setSearchQuery] = useState('');
const [debouncedSearchQuery] = useDebouncedValue(searchQuery, 300);
const [debouncedSearchQuery] = useDebouncedValue(searchQuery, 10);
const [allPatternsData, setAllPatternsData] = useState([]);

//
// D. Search
// B. Fetch data

useEffect(() => {
(async function () {
// Exit if no line is selected
if (!linesExplorerContext.entities?.line?.id) return;
// Exit if no date is selected
if (!linesExplorerContext.entities?.date_string) return;
// Initiate a temporaty variable to hold formatted patterns
let formattedPatternOptions = [];
// Loop through each line pattern to retrieve its info
for (const patternId of linesExplorerContext.entities.line.patterns) {
// Fetch pattern info
const patternDataResponse = await fetch(`https://api.carrismetropolitana.pt/patterns/${patternId}`);
const patternData = await patternDataResponse.json();
// Check if this pattern is valid on the selected date
const isValidOnSelectedDate = patternData.valid_on.includes(linesExplorerContext.entities.date_string);
// Format response
formattedPatternOptions.push({
id: patternData.id,
line_id: patternData.line_id,
route_id: patternData.route_id,
short_name: patternData.short_name,
direction: patternData.direction,
headsign: patternData.headsign,
color: patternData.color,
text_color: patternData.text_color,
municipalities: patternData.municipalities,
localities: patternData.localities,
label: patternData.headsign || 'no headsign',
disabled: !isValidOnSelectedDate,
});
}
// Update state with formatted patterns
setAllPatternsData(formattedPatternOptions);
// Pre-select the first pattern if none is selected
if (!linesExplorerContext.entities.pattern) {
linesExplorerContext.selectPattern(formattedPatternOptions[0]);
}
//
})();
}, [linesExplorerContext]);

const allPatternsDataFilteredBySearchQuery = useSearch(debouncedSearchQuery, linesExplorerContext.entities?.available_patterns, {
keys: ['id', 'headsign'],
//
// C. Search

const allPatternsDataFilteredBySearchQuery = useSearch(debouncedSearchQuery, allPatternsData, {
keys: ['id', 'headsign', 'municipalities', 'localities'],
regexReplace: /[^a-zA-Z0-9\s]/g,
});

//
// E. Handle actions
// D. Handle actions

const handleClickSearchField = ({ currentTarget }) => {
if (currentTarget.select) currentTarget.select();
Expand All @@ -61,17 +105,20 @@ export default function LinesExplorerContentSelectPattern() {
comboboxStore.openDropdown();
};

const handleSelectLine = (chosenSelectItemValue) => {
linesExplorerContext.selectPattern(chosenSelectItemValue);
comboboxStore.closeDropdown();
const handleSelectPattern = (chosenSelectItemValue) => {
const foundPattern = allPatternsData.find((item) => item.id === chosenSelectItemValue);
if (foundPattern) {
linesExplorerContext.selectPattern(foundPattern);
comboboxStore.closeDropdown();
}
};

//
// F. Render components
// E. Render components

return (
<div className={styles.container}>
<Combobox onOptionSubmit={handleSelectLine} store={comboboxStore}>
<Combobox onOptionSubmit={handleSelectPattern} store={comboboxStore}>
<Combobox.Target>
{linesExplorerContext.entities.line?.id && linesExplorerContext.entities.pattern?.id && !comboboxStore.dropdownOpened ? (
<Group className={styles.comboboxTarget} onClick={handleClickSearchField}>
Expand Down Expand Up @@ -111,7 +158,7 @@ export default function LinesExplorerContentSelectPattern() {
<Combobox.Empty>{t('no_results')}</Combobox.Empty>
) : (
allPatternsDataFilteredBySearchQuery.map((item) => (
<Combobox.Option key={item.id} value={item.id} className={item.id === linesExplorerContext.entities.line?.id && styles.selected}>
<Combobox.Option key={item.id} value={item.id} className={item.id === linesExplorerContext.entities.line?.id && styles.selected} disabled={item.disabled}>
<div className={styles.comboboxOption}>{item.headsign}</div>
</Combobox.Option>
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@ export default function LinesExplorerToolbarSelectDate() {
const t = useTranslations('LinesExplorerToolbarSelectDate');

//
// C. Handle actions
// B. Transform data

const todayDate = useMemo(() => {
// Get the current date and time
const currentDate = new Date();
const currentHour = currentDate.getHours();
// If the current hour is after midnight and before 4AM,
// set the date to the previous day.
if (currentHour >= 0 && currentHour < 4) {
currentDate.setDate(currentDate.getDate() - 1);
}
// If the current hour is after midnight and before 4AM, set the date to the previous day.
if (currentHour >= 0 && currentHour < 4) currentDate.setDate(currentDate.getDate() - 1);
// Return date for today
return currentDate;
//
Expand All @@ -39,10 +36,6 @@ export default function LinesExplorerToolbarSelectDate() {
return todayDateString === linesExplorerContext.entities.date;
}, [linesExplorerContext.entities.date, todayDate]);

//
//
//

const tomorrowDate = useMemo(() => {
// Get the current date and time
const currentDate = new Date();
Expand All @@ -66,19 +59,15 @@ export default function LinesExplorerToolbarSelectDate() {
// C. Handle actions

const handleSetToday = () => {
// Set the date value for today
handleSetDate(todayDate);
};

const handleSetTomorrow = () => {
// Set the date value for tomorrow
handleSetDate(tomorrowDate);
};

const handleSetDate = (value) => {
// Set the date value for tomorrow
// lineForm.setFieldValue('date', value);
// lineForm.setFieldValue('date_string', parseDateToString(value));
linesExplorerContext.selectDate(value);
};

//
Expand All @@ -87,30 +76,30 @@ export default function LinesExplorerToolbarSelectDate() {
return (
<div className={styles.container}>
<Button.Group>
<Button size="lg" variant="default">
<Button size="md" variant="default" onClick={handleSetToday}>
{t('today')}
</Button>
<Button size="lg" variant="default">
<Button size="md" variant="default" onClick={handleSetTomorrow}>
{t('tomorrow')}
</Button>
<DatePickerInput aria-label={t('label')} placeholder={t('placeholder')} dropdownType="modal" onChange={handleSetDate} value={linesExplorerContext.entities.date} size="lg" classNames={{ input: `${styles.input} ${!isTodaySelected && !isTomorrowSelected && styles.selected}` }} />
<DatePickerInput aria-label={t('label')} placeholder={t('placeholder')} dropdownType="modal" onChange={handleSetDate} value={linesExplorerContext.entities.date} size="md" classNames={{ input: `${styles.input} ${!isTodaySelected && !isTomorrowSelected && styles.selected}` }} />
</Button.Group>
</div>
);

return (
<div className={styles.container}>
<div className={styles.wrapper}>
<div className={`${styles.button} ${isTodaySelected && styles.selected}`} onClick={handleSetToday}>
{t('today')}
</div>
<div className={`${styles.button} ${isTomorrowSelected && styles.selected}`} onClick={handleSetTomorrow}>
{t('tomorrow')}
</div>
<DatePickerInput aria-label={t('label')} placeholder={t('placeholder')} dropdownType="modal" onChange={handleSetDate} value={linesExplorerContext.entities.date} size="lg" />
</div>
</div>
);
// return (
// <div className={styles.container}>
// <div className={styles.wrapper}>
// <div className={`${styles.button} ${isTodaySelected && styles.selected}`} onClick={handleSetToday}>
// {t('today')}
// </div>
// <div className={`${styles.button} ${isTomorrowSelected && styles.selected}`} onClick={handleSetTomorrow}>
// {t('tomorrow')}
// </div>
// <DatePickerInput aria-label={t('label')} placeholder={t('placeholder')} dropdownType="modal" onChange={handleSetDate} value={linesExplorerContext.entities.date} size="lg" />
// </div>
// </div>
// );

//
}
21 changes: 18 additions & 3 deletions frontend/contexts/LinesExplorerContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import useSWR from 'swr';
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
import parseDateToString from '@/services/parseDateToString';

/* * */

Expand Down Expand Up @@ -99,7 +100,7 @@ export function LinesExplorerContextProvider({ children }) {
// ---------

const selectLine = useCallback(
async (lineId) => {
(lineId) => {
const foundLine = allLinesData.find((item) => item.id === lineId);
if (foundLine) {
setEntitiesState((prev) => ({ ...prev, line: foundLine, pattern: null, shape: null }));
Expand All @@ -116,7 +117,18 @@ export function LinesExplorerContextProvider({ children }) {

// ---------

const selectPattern = useCallback(async (patternData) => {
const selectDate = useCallback((date) => {
if (!date) return;
setEntitiesState((prev) => ({ ...prev, date: date, date_string: parseDateToString(date) }));
}, []);

const clearSelectedDate = useCallback(() => {
setEntitiesState((prev) => ({ ...prev, date: null, date_string: null }));
}, []);

// ---------

const selectPattern = useCallback((patternData) => {
setEntitiesState((prev) => ({ ...prev, pattern: patternData }));
}, []);

Expand Down Expand Up @@ -160,11 +172,14 @@ export function LinesExplorerContextProvider({ children }) {
selectLine,
clearSelectedLine,
//
selectDate,
clearSelectedDate,
//
selectPattern,
clearSelectedPattern,
//
}),
[mapState, updateMapState, entitiesState, updateEntitiesState, selectMunicipality, clearSelectedMunicipality, selectLine, clearSelectedLine, selectPattern, clearSelectedPattern]
[mapState, updateMapState, entitiesState, updateEntitiesState, selectMunicipality, clearSelectedMunicipality, selectLine, clearSelectedLine, selectDate, clearSelectedDate, selectPattern, clearSelectedPattern]
);

//
Expand Down

0 comments on commit 03c192d

Please sign in to comment.