From 3aa6eee0f54dec3e4f92be2ad335a04145ac4db8 Mon Sep 17 00:00:00 2001
From: Ariel Costas Guerrero <94913521+arielcostas@users.noreply.github.com>
Date: Mon, 3 Mar 2025 18:54:35 +0100
Subject: Improve the UI

---
 src/pages/StopList.tsx | 102 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100644 src/pages/StopList.tsx

(limited to 'src/pages/StopList.tsx')

diff --git a/src/pages/StopList.tsx b/src/pages/StopList.tsx
new file mode 100644
index 0000000..2351b51
--- /dev/null
+++ b/src/pages/StopList.tsx
@@ -0,0 +1,102 @@
+import { useEffect, useMemo, useState } from "react";
+import { Stop, StopDataProvider } from "../data/StopDataProvider";
+import StopItem from "../components/StopItem";
+import Fuse from "fuse.js";
+
+const sdp = new StopDataProvider();
+
+export function StopList() {
+	const [data, setData] = useState<Stop[] | null>(null)
+	const [searchResults, setSearchResults] = useState<Stop[] | null>(null);
+
+	useEffect(() => {
+		sdp.getStops().then((stops: Stop[]) => setData(stops))
+	}, []);
+
+	const handleStopSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
+		const stopName = event.target.value;
+		if (data) {
+			const fuse = new Fuse(data, { keys: ['name'], threshold: 0.3 });
+			const results = fuse.search(stopName).map(result => result.item);
+			setSearchResults(results);
+		}
+	}
+
+	const favouritedStops = useMemo(() => {
+		return data?.filter(stop => stop.favourite) ?? []
+	}, [data])
+
+	const recentStops = useMemo(() => {
+		const recent = sdp.getRecent();
+
+		if (recent.length === 0) return null;
+		
+		return recent.map(stopId => data?.find(stop => stop.stopId === stopId) as Stop).reverse();
+	}, [data])
+
+	if (data === null) return <h1 className="page-title">Loading...</h1>
+
+	return (
+		<div className="page-container">
+			<h1 className="page-title">UrbanoVigo Web</h1>
+
+			<form className="search-form">
+				<div className="form-group">
+					<label className="form-label" htmlFor="stopName">
+						Nombre de la parada
+					</label>
+					<input className="form-input" type="text" placeholder="Nombre de la parada" id="stopName" onChange={handleStopSearch} />
+				</div>
+			</form>
+
+			{searchResults && searchResults.length > 0 && (
+				<div className="list-container">
+					<h2 className="page-subtitle">Resultados de la búsqueda</h2>
+					<ul className="list">
+						{searchResults.map((stop: Stop) => (
+							<StopItem key={stop.stopId} stop={stop} />
+						))}
+					</ul>
+				</div>
+			)}
+
+			<div className="list-container">
+				<h2 className="page-subtitle">Paradas favoritas</h2>
+
+				{favouritedStops?.length === 0 && (
+					<p className="message">
+						Accede a una parada y márcala como favorita para verla aquí.
+					</p>
+				)}
+
+				<ul className="list">
+					{favouritedStops?.sort((a, b) => a.stopId - b.stopId).map((stop: Stop) => (
+						<StopItem key={stop.stopId} stop={stop} />
+					))}
+				</ul>
+			</div>
+
+			{recentStops && recentStops.length > 0 && (
+				<div className="list-container">
+					<h2 className="page-subtitle">Recientes</h2>
+
+					<ul className="list">
+						{recentStops.map((stop: Stop) => (
+							<StopItem key={stop.stopId} stop={stop} />
+						))}
+					</ul>
+				</div>
+			)}
+
+			<div className="list-container">
+				<h2 className="page-subtitle">Paradas</h2>
+
+				<ul className="list">
+					{data?.sort((a, b) => a.stopId - b.stopId).map((stop: Stop) => (
+						<StopItem key={stop.stopId} stop={stop} />
+					))}
+				</ul>
+			</div>
+		</div>
+	)
+}
-- 
cgit v1.3

