From 4192cc1b5d1e2951963457516de0f9fe668c3b9a Mon Sep 17 00:00:00 2001 From: Ariel Costas Guerrero <94913521+arielcostas@users.noreply.github.com> Date: Mon, 3 Mar 2025 19:13:53 +0100 Subject: Improve more the UI --- package-lock.json | 10 +++ package.json | 1 + src/Layout.css | 21 +++++- src/Layout.tsx | 8 +-- src/components/LineIcon.css | 156 +++++++++++++++++++++++++++++--------------- src/main.tsx | 27 +++++++- src/pages/StopList.tsx | 18 ++++- src/styles/Pages.css | 71 ++++++++++++++------ 8 files changed, 229 insertions(+), 83 deletions(-) diff --git a/package-lock.json b/package-lock.json index b483971..3ce48eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.0.0", "dependencies": { + "@fontsource-variable/outfit": "^5.2.5", "fuse.js": "^7.1.0", "lucide-react": "^0.477.0", "react": "^18.3.1", @@ -598,6 +599,15 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@fontsource-variable/outfit": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@fontsource-variable/outfit/-/outfit-5.2.5.tgz", + "integrity": "sha512-MejrIp6Cbmd3u5AZtsot8kmhZiyQM5CATsdcBB2hktYIrv5CVekRSUmFDXL4FpF7K70IvFp2ZMfImm5VhnVf7Q==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", diff --git a/package.json b/package.json index 3197eeb..6d2a61b 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "preview": "vite preview" }, "dependencies": { + "@fontsource-variable/outfit": "^5.2.5", "fuse.js": "^7.1.0", "lucide-react": "^0.477.0", "react": "^18.3.1", diff --git a/src/Layout.css b/src/Layout.css index 52b0262..ab4eecd 100644 --- a/src/Layout.css +++ b/src/Layout.css @@ -18,12 +18,12 @@ bottom: 0; left: 0; right: 0; - background-color: #ffffff; + background-color: var(--background-color); display: flex; justify-content: space-around; align-items: center; height: 60px; - border-top: 1px solid #e0e0e0; + border-top: 1px solid var(--border-color); box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1); } @@ -40,5 +40,20 @@ } .nav-item.active { - color: #007bff; + color: var(--button-background-color); +} + +.theme-toggle { + background: none; + border: none; + cursor: pointer; + color: inherit; + display: flex; + align-items: center; + justify-content: center; + padding: 8px; +} + +.theme-toggle:hover { + color: var(--button-hover-background-color); } \ No newline at end of file diff --git a/src/Layout.tsx b/src/Layout.tsx index 5aaafbf..34f5dbf 100644 --- a/src/Layout.tsx +++ b/src/Layout.tsx @@ -9,20 +9,20 @@ interface LayoutProps { export function Layout({ children }: LayoutProps) { const location = useLocation(); - + const navItems = [ { - name: 'Stops', + name: 'Paradas', icon: MapPin, path: '/stops' }, { - name: 'Maps', + name: 'Mapa', icon: Map, path: '/map' }, { - name: 'About', + name: 'Acerca de', icon: Info, path: '/about' } diff --git a/src/components/LineIcon.css b/src/components/LineIcon.css index 8c9f7ee..e7e8949 100644 --- a/src/components/LineIcon.css +++ b/src/components/LineIcon.css @@ -1,191 +1,239 @@ +:root { + --line-c1: rgb(237, 71, 19); + --line-c3d: rgb(255, 204, 0); + --line-c3i: rgb(255, 204, 0); + --line-l4a: rgb(0, 153, 0); + --line-l4c: rgb(0, 153, 0); + --line-l5a: rgb(0, 176, 240); + --line-l5b: rgb(0, 176, 240); + --line-l6: rgb(204, 51, 153); + --line-l7: rgb(150, 220, 153); + --line-l9b: rgb(244, 202, 140); + --line-l10: rgb(153, 51, 0); + --line-l11: rgb(226, 0, 38); + --line-l12a: rgb(106, 150, 190); + --line-l12b: rgb(106, 150, 190); + --line-l13: rgb(0, 176, 240); + --line-l14: rgb(129, 142, 126); + --line-l15a: rgb(216, 168, 206); + --line-l15b: rgb(216, 168, 206); + --line-l15c: rgb(216, 168, 168); + --line-l16: rgb(129, 142, 126); + --line-l17: rgb(214, 245, 31); + --line-l18a: rgb(212, 80, 168); + --line-l18b: rgb(0, 0, 0); + --line-l18h: rgb(0, 0, 0); + --line-l23: rgb(0, 70, 210); + --line-l24: rgb(191, 191, 191); + --line-l25: rgb(172, 100, 4); + --line-l27: rgb(112, 74, 42); + --line-l28: rgb(176, 189, 254); + --line-l29: rgb(248, 184, 90); + --line-l31: rgb(255, 255, 0); + --line-a: rgb(119, 41, 143); + --line-h: rgb(0, 96, 168); + --line-h1: rgb(0, 96, 168); + --line-h2: rgb(0, 96, 168); + --line-h3: rgb(0, 96, 168); + --line-lzd: rgb(61, 78, 167); + --line-n1: rgb(191, 191, 191); + --line-n4: rgb(102, 51, 102); + --line-psa1: rgb(0, 153, 0); + --line-psa4: rgb(0, 153, 0); + --line-ptl: rgb(150, 220, 153); + --line-turistico: rgb(102, 51, 102); + --line-u1: rgb(172, 100, 4); + --line-u2: rgb(172, 100, 4); +} + .line-icon { - display: inline-block; - padding: 0.25rem 0.5rem; - margin-right: 0.5rem; - border-bottom: 3px solid; - font-size: 0.9rem; - font-weight: 600; - text-transform: uppercase; - color: inherit; - /* Prevent color change on hover */ + display: inline-block; + padding: 0.25rem 0.5rem; + margin-right: 0.5rem; + border-bottom: 3px solid; + font-size: 0.9rem; + font-weight: 600; + text-transform: uppercase; + color: inherit; + /* Prevent color change on hover */ } .line-c1 { - border-color: rgb(237, 71, 19); + border-color: var(--line-c1); } .line-c3d { - border-color: rgb(255, 204, 0); + border-color: var(--line-c3d); } .line-c3i { - border-color: rgb(255, 204, 0); + border-color: var(--line-c3i); } .line-l4a { - border-color: rgb(0, 153, 0); + border-color: var(--line-l4a); } .line-l4c { - border-color: rgb(0, 153, 0); + border-color: var(--line-l4c); } .line-l5a { - border-color: rgb(0, 176, 240); + border-color: var(--line-l5a); } .line-l5b { - border-color: rgb(0, 176, 240); + border-color: var(--line-l5b); } .line-l6 { - border-color: rgb(204, 51, 153); + border-color: var(--line-l6); } .line-l7 { - border-color: rgb(150, 220, 153); + border-color: var(--line-l7); } .line-l9b { - border-color: rgb(244, 202, 140); + border-color: var(--line-l9b); } .line-l10 { - border-color: rgb(153, 51, 0); + border-color: var(--line-l10); } .line-l11 { - border-color: rgb(226, 0, 38); + border-color: var(--line-l11); } .line-l12a { - border-color: rgb(106, 150, 190); + border-color: var(--line-l12a); } .line-l12b { - border-color: rgb(106, 150, 190); + border-color: var(--line-l12b); } .line-l13 { - border-color: rgb(0, 176, 240); + border-color: var(--line-l13); } .line-l14 { - border-color: rgb(129, 142, 126); + border-color: var(--line-l14); } .line-l15a { - border-color: rgb(216, 168, 206); + border-color: var(--line-l15a); } .line-l15b { - border-color: rgb(216, 168, 206); + border-color: var(--line-l15b); } .line-l15c { - border-color: rgb(216, 168, 168); + border-color: var(--line-l15c); } .line-l16 { - border-color: rgb(129, 142, 126); + border-color: var(--line-l16); } .line-l17 { - border-color: rgb(214, 245, 31); + border-color: var(--line-l17); } .line-l18a { - border-color: rgb(212, 80, 168); + border-color: var(--line-l18a); } .line-l18b { - border-color: rgb(0, 0, 0); + border-color: var(--line-l18b); } .line-l18h { - border-color: rgb(0, 0, 0); + border-color: var(--line-l18h); } .line-l23 { - border-color: rgb(0, 70, 210); + border-color: var(--line-l23); } .line-l24 { - border-color: rgb(191, 191, 191); + border-color: var(--line-l24); } .line-l25 { - border-color: rgb(172, 100, 4); + border-color: var(--line-l25); } .line-l27 { - border-color: rgb(112, 74, 42); + border-color: var(--line-l27); } .line-l28 { - border-color: rgb(176, 189, 254); + border-color: var(--line-l28); } .line-l29 { - border-color: rgb(248, 184, 90); + border-color: var(--line-l29); } .line-l31 { - border-color: rgb(255, 255, 0); + border-color: var(--line-l31); } .line-a { - border-color: rgb(119, 41, 143); + border-color: var(--line-a); } .line-h { - border-color: rgb(0, 96, 168); + border-color: var(--line-h); } .line-h1 { - border-color: rgb(0, 96, 168); + border-color: var(--line-h1); } .line-h2 { - border-color: rgb(0, 96, 168); + border-color: var(--line-h2); } .line-h3 { - border-color: rgb(0, 96, 168); + border-color: var(--line-h3); } .line-lzd { - border-color: rgb(61, 78, 167); + border-color: var(--line-lzd); } .line-n1 { - border-color: rgb(191, 191, 191); + border-color: var(--line-n1); } .line-n4 { - border-color: rgb(102, 51, 102); + border-color: var(--line-n4); } .line-psa1 { - border-color: rgb(0, 153, 0); + border-color: var(--line-psa1); } .line-psa4 { - border-color: rgb(0, 153, 0); + border-color: var(--line-psa4); } .line-ptl { - border-color: rgb(150, 220, 153); + border-color: var(--line-ptl); } .line-turistico { - border-color: rgb(102, 51, 102); + border-color: var(--line-turistico); } .line-u1 { - border-color: rgb(172, 100, 4); + border-color: var(--line-u1); } .line-u2 { - border-color: rgb(172, 100, 4); + border-color: var(--line-u2); } \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index cf9a20c..85d2caf 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,14 @@ +import '@fontsource-variable/outfit' +import './styles/Pages.css' + import { createRoot } from 'react-dom/client' import { createBrowserRouter, Navigate, RouterProvider } from 'react-router' import { StopList } from './pages/StopList.tsx' import { Estimates } from './pages/Estimates.tsx' import { StopMap } from './pages/Map.tsx' import { Layout } from './Layout.tsx' -import './styles/Pages.css' +import { Sun, Moon } from 'lucide-react'; +import { useState, useEffect } from 'react'; const router = createBrowserRouter([ { @@ -30,11 +34,32 @@ const router = createBrowserRouter([ ]) function About() { + const [theme, setTheme] = useState<'light' | 'dark'>(() => { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme) { + return savedTheme as 'light' | 'dark'; + } + const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; + return prefersDark ? 'dark' : 'light'; + }); + + useEffect(() => { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + }, [theme]); + + const toggleTheme = () => { + setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); + }; + return (
This application helps you find bus stops and check bus arrival estimates.
Version 1.0.0
+