diff --git a/frontend/components/LinesExplorerContentSelectPattern/LinesExplorerContentSelectPattern.js b/frontend/components/LinesExplorerContentSelectPattern/LinesExplorerContentSelectPattern.js
index 4739d0a8..80e93547 100644
--- a/frontend/components/LinesExplorerContentSelectPattern/LinesExplorerContentSelectPattern.js
+++ b/frontend/components/LinesExplorerContentSelectPattern/LinesExplorerContentSelectPattern.js
@@ -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';
@@ -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();
@@ -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 (
-
+
{linesExplorerContext.entities.line?.id && linesExplorerContext.entities.pattern?.id && !comboboxStore.dropdownOpened ? (
@@ -111,7 +158,7 @@ export default function LinesExplorerContentSelectPattern() {
{t('no_results')}
) : (
allPatternsDataFilteredBySearchQuery.map((item) => (
-
+
{item.headsign}
))
diff --git a/frontend/components/LinesExplorerToolbarSelectDate/LinesExplorerToolbarSelectDate.js b/frontend/components/LinesExplorerToolbarSelectDate/LinesExplorerToolbarSelectDate.js
index 5f721910..bfae1e91 100644
--- a/frontend/components/LinesExplorerToolbarSelectDate/LinesExplorerToolbarSelectDate.js
+++ b/frontend/components/LinesExplorerToolbarSelectDate/LinesExplorerToolbarSelectDate.js
@@ -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;
//
@@ -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();
@@ -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);
};
//
@@ -87,30 +76,30 @@ export default function LinesExplorerToolbarSelectDate() {
return (
-
+
{t('today')}
-
+
{t('tomorrow')}
-
+
);
- return (
-
-
-
- {t('today')}
-
-
- {t('tomorrow')}
-
-
-
-
- );
+ // return (
+ //
+ //
+ //
+ // {t('today')}
+ //
+ //
+ // {t('tomorrow')}
+ //
+ //
+ //
+ //
+ // );
//
}
diff --git a/frontend/contexts/LinesExplorerContext.js b/frontend/contexts/LinesExplorerContext.js
index f5b3f510..f30d9812 100644
--- a/frontend/contexts/LinesExplorerContext.js
+++ b/frontend/contexts/LinesExplorerContext.js
@@ -4,6 +4,7 @@
import useSWR from 'swr';
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
+import parseDateToString from '@/services/parseDateToString';
/* * */
@@ -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 }));
@@ -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 }));
}, []);
@@ -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]
);
//