aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/app/components')
-rw-r--r--src/frontend/app/components/LineIcon.css3
-rw-r--r--src/frontend/app/components/StopGallery.tsx36
-rw-r--r--src/frontend/app/components/StopGalleryItem.tsx38
-rw-r--r--src/frontend/app/components/StopItem.tsx17
4 files changed, 65 insertions, 29 deletions
diff --git a/src/frontend/app/components/LineIcon.css b/src/frontend/app/components/LineIcon.css
index c6dffd8..6363c85 100644
--- a/src/frontend/app/components/LineIcon.css
+++ b/src/frontend/app/components/LineIcon.css
@@ -13,6 +13,7 @@
--line-l5b: hsl(204, 100%, 54%);
--line-l5b-text: hsl(0, 0%, 100%);
--line-l6: hsl(330, 60%, 50%);
+ --line-l6-text: hsl(0, 0%, 100%);
--line-l7: hsl(120, 60%, 70%);
--line-l9b: hsl(36, 83%, 75%);
--line-l10: hsl(30, 80%, 20%);
@@ -40,6 +41,7 @@
--line-l23-text: hsl(0, 0%, 100%);
--line-l24: hsl(0, 0%, 75%);
--line-l25: hsl(34, 95%, 35%);
+ --line-l25-text: hsl(0, 0%, 100%);
--line-l27: hsl(30, 60%, 30%);
--line-l27-text: hsl(0, 0%, 100%);
--line-l28: hsl(230, 98%, 84%);
@@ -59,6 +61,7 @@
--line-h3-text: hsl(0, 0%, 100%);
--line-lzd: hsl(220, 60%, 50%);
--line-n1: hsl(0, 51%, 53%);
+ --line-n1-text: hsl(0, 0%, 100%);
--line-n4: hsl(300, 33%, 30%);
--line-n4-text: hsl(0, 0%, 100%);
--line-psa1: hsl(120, 100%, 30%);
diff --git a/src/frontend/app/components/StopGallery.tsx b/src/frontend/app/components/StopGallery.tsx
index 500ea20..c1d9780 100644
--- a/src/frontend/app/components/StopGallery.tsx
+++ b/src/frontend/app/components/StopGallery.tsx
@@ -1,6 +1,5 @@
import React, { useEffect, useRef, useState } from "react";
import { type Stop } from "../data/StopDataProvider";
-import "./StopGallery.css";
import StopGalleryItem from "./StopGalleryItem";
interface StopGalleryProps {
@@ -36,10 +35,12 @@ const StopGallery: React.FC<StopGalleryProps> = ({
if (stops.length === 0 && emptyMessage) {
return (
- <div className="gallery-container stoplist-section">
- <h3 className="page-subtitle">{title}</h3>
- <div className="gallery-empty-state">
- <p className="message">{emptyMessage}</p>
+ <div className="w-full px-4 flex flex-col gap-2">
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">{title}</h3>
+ <div className="text-center">
+ <p className="text-sm px-4 py-3 bg-gray-100 dark:bg-gray-800 rounded-lg">
+ {emptyMessage}
+ </p>
</div>
</div>
);
@@ -50,24 +51,31 @@ const StopGallery: React.FC<StopGalleryProps> = ({
}
return (
- <div className="gallery-container stoplist-section">
- <div className="gallery-header">
- <h3 className="page-subtitle">{title}</h3>
- <span className="gallery-counter">{stops.length}</span>
- </div>
+ <div className="w-full px-4 flex flex-col gap-2">
+ <h3 className="text-lg font-semibold text-gray-900 dark:text-gray-100">{title}</h3>
- <div ref={scrollRef} className="gallery-scroll-container">
- <div className="gallery-track">
+ <div
+ ref={scrollRef}
+ className="overflow-x-auto overflow-y-hidden snap-x snap-mandatory scrollbar-hide pb-2"
+ style={{
+ WebkitOverflowScrolling: 'touch',
+ scrollbarWidth: 'none',
+ msOverflowStyle: 'none'
+ }}
+ >
+ <div className="flex gap-3">
{stops.map((stop) => (
<StopGalleryItem key={stop.stopId} stop={stop} />
))}
</div>
</div>
- <div className="gallery-dots">
+ <div className="flex justify-center gap-1.5 mt-1">
{stops.map((_, index) => (
<span
key={index}
- className={`dot ${index === activeIndex ? "active" : ""}`}
+ className={`w-1.5 h-1.5 rounded-full transition-colors duration-200 ${
+ index === activeIndex ? "bg-blue-600" : "bg-gray-300 dark:bg-gray-700"
+ }`}
></span>
))}
</div>
diff --git a/src/frontend/app/components/StopGalleryItem.tsx b/src/frontend/app/components/StopGalleryItem.tsx
index 72a13e5..6c80362 100644
--- a/src/frontend/app/components/StopGalleryItem.tsx
+++ b/src/frontend/app/components/StopGalleryItem.tsx
@@ -9,21 +9,43 @@ interface StopGalleryItemProps {
const StopGalleryItem: React.FC<StopGalleryItemProps> = ({ stop }) => {
return (
- <div className="gallery-item">
- <Link className="gallery-item-link" to={`/stops/${stop.stopId}`}>
- <div className="gallery-item-header">
- {stop.favourite && <span className="favourite-icon">★</span>}
- <span className="gallery-item-code">({stop.stopId})</span>
+ <div className="flex-[0_0_90%] max-w-80 snap-start snap-always md:flex-[0_0_320px] lg:flex-[0_0_340px]">
+ <Link
+ className="
+ block p-3 min-h-[100px]
+ bg-gradient-to-br from-white to-gray-50 dark:from-gray-800 dark:to-gray-800/80
+ border-2 border-gray-200 dark:border-gray-700 rounded-xl
+ no-underline text-gray-900 dark:text-gray-100
+ hover:border-blue-400 dark:hover:border-blue-600 hover:shadow-sm
+ transition-all duration-200
+ "
+ to={`/stops/${stop.stopId}`}
+ >
+ <div className="flex items-center gap-2 mb-1">
+ {stop.favourite && <span className="text-yellow-500 text-base">★</span>}
+ <span className="text-xs text-gray-600 dark:text-gray-400 font-medium">
+ ({stop.stopId})
+ </span>
</div>
- <div className="gallery-item-name">
+ <div
+ className="text-[0.95rem] font-semibold mb-2 leading-snug line-clamp-2 min-h-[2.5em]"
+ style={{
+ display: '-webkit-box',
+ WebkitLineClamp: 2,
+ WebkitBoxOrient: 'vertical',
+ overflow: 'hidden'
+ }}
+ >
{StopDataProvider.getDisplayName(stop)}
</div>
- <div className="gallery-item-lines">
+ <div className="flex flex-wrap gap-1 items-center">
{stop.lines?.slice(0, 5).map((line) => (
<LineIcon key={line} line={line} />
))}
{stop.lines && stop.lines.length > 5 && (
- <span className="more-lines">+{stop.lines.length - 5}</span>
+ <span className="text-xs text-gray-600 dark:text-gray-400 font-medium px-1.5 py-0.5 bg-gray-200 dark:bg-gray-700 rounded">
+ +{stop.lines.length - 5}
+ </span>
)}
</div>
</Link>
diff --git a/src/frontend/app/components/StopItem.tsx b/src/frontend/app/components/StopItem.tsx
index 7875b59..9679b05 100644
--- a/src/frontend/app/components/StopItem.tsx
+++ b/src/frontend/app/components/StopItem.tsx
@@ -9,18 +9,21 @@ interface StopItemProps {
const StopItem: React.FC<StopItemProps> = ({ stop }) => {
return (
- <li className="list-item">
- <Link className="list-item-link" to={`/stops/${stop.stopId}`}>
- <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
- <span style={{ fontWeight: 600 }}>
- {stop.favourite && <span className="favourite-icon">★</span>}
+ <li className="pb-3 border-b border-gray-200 dark:border-gray-700 md:border md:border-gray-300 dark:md:border-gray-700 md:rounded-lg md:p-3 md:pb-3">
+ <Link
+ className="block text-gray-900 dark:text-gray-100 no-underline hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200"
+ to={`/stops/${stop.stopId}`}
+ >
+ <div className="flex justify-between items-baseline">
+ <span className="font-semibold">
+ {stop.favourite && <span className="text-yellow-500 mr-1">★</span>}
{StopDataProvider.getDisplayName(stop)}
</span>
- <span style={{ fontSize: "0.85em", color: "var(--subtitle-color)", marginLeft: "0.5rem" }}>
+ <span className="text-sm text-gray-600 dark:text-gray-400 ml-2">
({stop.stopId})
</span>
</div>
- <div className="line-icons" style={{ marginTop: "0.25rem" }}>
+ <div className="flex flex-wrap gap-1 mt-1">
{stop.lines?.map((line) => (
<LineIcon key={line} line={line} />
))}