From 112582c489f94e2b302402dde4a1ae0f45ffd079 Mon Sep 17 00:00:00 2001 From: pir8bay Date: Sat, 6 Jul 2024 13:06:10 +0300 Subject: [PATCH] added route like and options UI --- src/components/RouteCard.tsx | 125 +++++++++++++++++++++++++----- src/components/RouteOptions.tsx | 68 ++++++++++++++++ src/components/RouteStaticMap.tsx | 2 +- src/index.css | 53 +++++++++++++ 4 files changed, 227 insertions(+), 21 deletions(-) create mode 100644 src/components/RouteOptions.tsx diff --git a/src/components/RouteCard.tsx b/src/components/RouteCard.tsx index 90c0ea85..2ac9b951 100644 --- a/src/components/RouteCard.tsx +++ b/src/components/RouteCard.tsx @@ -1,9 +1,10 @@ -import { createSignal, createEffect, Suspense, type VoidComponent } from 'solid-js' +import { createSignal, createEffect, Suspense, Show, type Component } from 'solid-js' import dayjs from 'dayjs' import Avatar from '~/components/material/Avatar' import { CardContent, CardHeader } from '~/components/material/Card' import Icon from '~/components/material/Icon' +import RouteOptions from '~/components/RouteOptions' import RouteStaticMap from '~/components/RouteStaticMap' import RouteStatistics from '~/components/RouteStatistics' import Timeline from './Timeline' @@ -12,13 +13,84 @@ import type { Route, RouteSegments } from '~/types' import { reverseGeocode } from '~/map' +type RouteOptionsProps = { + route?: Route; +} + +const [showRouteOptionsCard, setShowRouteOptionsCard] = createSignal(false) + +const RouteOptionsCard: Component = (props) => { + const [isMdOrLarger, setIsMdOrLarger] = createSignal(false) + + // listen isMdOrLarger + createEffect(() => { + const updateSize = () => { + setIsMdOrLarger(window.innerWidth >= 768) + } + window.addEventListener('resize', updateSize) + // Initial check + updateSize() + + return () => window.removeEventListener('resize', updateSize) + }) + + const stopPropagation = (event: MouseEvent) => { + event.stopPropagation() + + setShowRouteOptionsCard(false) + } + + return ( + +
+
event.stopPropagation()}> + +
+
+
+ ) +} + +type FavoriteRoutes = string[] + const RouteHeader = (props: { route?: RouteSegments }) => { + const startTime = () => props?.route?.segment_start_times ? dayjs(props.route.segment_start_times[0]) : null const endTime = () => props?.route?.segment_end_times ? dayjs(props.route.segment_end_times.at(-1)) : null const headline = () => startTime()?.format('ddd, MMM D, YYYY') const subhead = () => `${startTime()?.format('h:mm A')} to ${endTime()?.format('h:mm A')}` + const [isFavorite, setIsFavorite] = createSignal(false) + + const toggleFavorite = (routeName: string) => { + let favorites: FavoriteRoutes = JSON.parse(localStorage.getItem('favoriteRoutes') || '[]') as FavoriteRoutes + const isFavorite = favorites.includes(routeName) + favorites = isFavorite ? favorites.filter(name => name !== routeName) : [...favorites, routeName] + localStorage.setItem('favoriteRoutes', JSON.stringify(favorites)) + setIsFavorite(!isFavorite) + } + + createEffect(() => { + const favorites: FavoriteRoutes = JSON.parse(localStorage.getItem('favoriteRoutes') || '[]') as FavoriteRoutes + setIsFavorite(favorites.includes(props.route?.fullname ?? '')) + }) + + const handleLikeClick = (event: MouseEvent) => { + event.stopPropagation() + props.route?.fullname && toggleFavorite(props.route.fullname) + } + + const handleMoreOptionsClick = (event: MouseEvent) => { + event.stopPropagation() + setShowRouteOptionsCard(true) + } + return ( { directions_car } + trailing={ +
+ + +
+ } /> ) } @@ -130,31 +212,34 @@ type RouteCardProps = { route?: Route; } -const RouteCard: VoidComponent = (props) => { +const RouteCard: Component = (props) => { const route = () => props.route + const navigateToRouteActivity = () => { + location.href = `/${route()?.dongle_id}/${route()?.fullname?.slice(17)}` + } + return ( - -
-
- } - > - - -
+
) } diff --git a/src/components/RouteOptions.tsx b/src/components/RouteOptions.tsx new file mode 100644 index 00000000..bde8825d --- /dev/null +++ b/src/components/RouteOptions.tsx @@ -0,0 +1,68 @@ +import { createSignal, createEffect, type Component } from 'solid-js' +import type { Route } from '~/types' + +type RouteOptionsProps = { + route?: Route; +} + +const RouteOptions: Component = (props) => { + const [isPreservedChecked, setIsPreservedChecked] = createSignal(true) + const [isPublicAccessChecked, setIsPublicAccessChecked] = createSignal(false) + + const [routeId, setRouteId] = createSignal() + + createEffect(() => { + const routeFullName = props?.route?.fullname + setRouteId(routeFullName?.split('|')[1]) + }) + + return ( +
+
+
+ file_copy + Route ID +
+
+ share + Share +
+
+
+ Route ID: {routeId()} +
+
+
+ Preserved + +
+
+ Public Access + +
+
+
+
+ View in useradmin + + keyboard_arrow_right + +
+
+ Upload Options + + cloud_upload + +
+
+
+ ) +} + +export default RouteOptions diff --git a/src/components/RouteStaticMap.tsx b/src/components/RouteStaticMap.tsx index 1a010bea..1185e294 100644 --- a/src/components/RouteStaticMap.tsx +++ b/src/components/RouteStaticMap.tsx @@ -83,7 +83,7 @@ const RouteStaticMap: VoidComponent = (props) => { diff --git a/src/index.css b/src/index.css index c9915dc5..c4c1c4b8 100644 --- a/src/index.css +++ b/src/index.css @@ -222,4 +222,57 @@ .custom-card:hover { background-color: var(--color-surface-container); } + + .custom-switch { + position: relative; + display: inline-block; + width: 45px; + height: 28px; + } + + .custom-switch input { + opacity: 0; + width: 0; + height: 0; + } + + .custom-slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #8d8d8d; + transition: .4s; + } + + .custom-slider:before { + position: absolute; + content: ""; + height: 100%; + width: 60%; + background-color: #fff; + transition: .4s; + } + + .custom-switch input:checked + .custom-slider { + background-color: #32CD32; + } + + .custom-switch input:focus + .custom-slider { + box-shadow: 0 0 1px #32CD32; + } + + .custom-switch input:checked + .custom-slider:before { + transform: translateX(26px); + } + + .custom-slider.round { + border-radius: 34px; + } + + .custom-slider.round:before { + border-radius: 50%; + } }