Skip to content

Commit

Permalink
feat(layout): improve visibility on mobile devices
Browse files Browse the repository at this point in the history
  • Loading branch information
devshred committed Jun 5, 2024
1 parent 4a01d9a commit 70a01de
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 27 deletions.
298 changes: 297 additions & 1 deletion package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"framer-motion": "^11.2.10",
"gpxparser": "^3.0.8",
"hamburger-react": "^2.5.1",
"leaflet": "^1.9.4",
"prettier": "^3.2.5",
"react": "^18.3.1",
Expand All @@ -43,6 +45,7 @@
"react-leaflet": "^4.2.1",
"react-leaflet-custom-control": "^1.4.0",
"react-router-dom": "^6.23.1",
"react-use": "^17.5.0",
"sanitize-html": "^2.13.0",
"uuid": "^9.0.1",
"vite-plugin-package-version": "^1.1.0"
Expand Down
13 changes: 13 additions & 0 deletions src/components/layout/NavDesktop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import NavDesktopButton from './NavDesktopButton'

const NavDesktop = () => {
return (
<div className="hidden md:flex flex-1 justify-end mr-6">
<NavDesktopButton label="home" linkTo="/" />
<NavDesktopButton label="faq" linkTo="/faq" />
<NavDesktopButton label="about" linkTo="/about" />
</div>
)
}

export default NavDesktop
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import React from 'react'
import { Link } from 'react-router-dom'
import useLanguage from '../../hooks/useLanguage'

type NavbarButtonProps = {
type NavDesktopButtonProps = {
label: string
linkTo: string
}

const NavbarButton: React.FC<NavbarButtonProps> = ({ label, linkTo }) => {
const NavDesktopButton: React.FC<NavDesktopButtonProps> = ({ label, linkTo }) => {
const { getMessage } = useLanguage()
return (
<Link to={linkTo} className="btn-nav mx-1 text-nav-theme">
Expand All @@ -16,4 +16,4 @@ const NavbarButton: React.FC<NavbarButtonProps> = ({ label, linkTo }) => {
)
}

export default NavbarButton
export default NavDesktopButton
27 changes: 27 additions & 0 deletions src/components/layout/NavMobile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useRef, useState } from 'react'
import { Squash as Hamburger } from 'hamburger-react'
import { FaLightbulb, FaQuestion } from 'react-icons/fa6'
import { FaHome } from 'react-icons/fa'
import { useClickAway } from 'react-use'
import NavMobileButton from './NavMobileButton'

const NavMobile = () => {
const [isOpen, setOpen] = useState(false)
const ref = useRef(null)
useClickAway(ref, () => setOpen(false))

return (
<div ref={ref} className="md:hidden flex-1 justify-end mr-6 text-white">
<Hamburger toggled={isOpen} size={20} toggle={setOpen} />
{isOpen && (
<div className="fixed left-0 shadow-4xl right-0 top-[3.5rem] p-5 pt-0 bg-neutral-950 border-b border-b-white/20 z-10">
<NavMobileButton label="home" linkTo="/" icon={<FaHome />} setOpen={setOpen} />
<NavMobileButton label="faq" linkTo="/faq" icon={<FaQuestion />} setOpen={setOpen} />
<NavMobileButton label="about" linkTo="/about" icon={<FaLightbulb />} setOpen={setOpen} />
</div>
)}
</div>
)
}

export default NavMobile
27 changes: 27 additions & 0 deletions src/components/layout/NavMobileButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { Dispatch, ReactElement, SetStateAction } from 'react'
import useLanguage from '../../hooks/useLanguage'

type NavMobileButtonProps = {
label: string
linkTo: string
icon: ReactElement
setOpen: Dispatch<SetStateAction<boolean>>
}

const NavMobileButton: React.FC<NavMobileButtonProps> = ({ label, linkTo, icon, setOpen }) => {
const { getMessage } = useLanguage()
return (
<div className="w-full p-[0.08rem] rounded-xl bg-gradient-to-tr from-neutral-800 via-neutral-950 to-neutral-700">
<a
onClick={() => setOpen((prev) => !prev)}
className={'flex items-center justify-between w-full p-5 rounded-xl bg-neutral-950'}
href={linkTo}
>
<span className="flex gap-1 text-lg">{getMessage(label)}</span>
{icon}
</a>
</div>
)
}

export default NavMobileButton
19 changes: 9 additions & 10 deletions src/components/layout/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react'
import { Link } from 'react-router-dom'
import ThemeSwitcher from './ThemeSwitcher'
import NavDesktop from './NavDesktop'
import NavMobile from './NavMobile'
import LanguageSelector from './LanguageSelector'
import NavbarButton from './NavbarButton'
import ThemeSwitcher from './ThemeSwitcher'

type NavbarProps = {
title?: string
Expand All @@ -13,7 +14,7 @@ const DEFAULT_TITLE: string = 'GPS-Tools'
const Navbar: React.FC<NavbarProps> = ({ title = DEFAULT_TITLE }) => {
return (
<nav className="navbar bg-navbar flex flex-row h-16 mb-5 shadow-lg">
<div className="flex-none px-2 ml-6 mr-2">
<div className="flex-none px-2 ml-0 md:ml-3 lg:ml-6 mr-2">
<Link to="/" className="align-middle" aria-label="GPS-Tools Homepage">
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -29,13 +30,11 @@ const Navbar: React.FC<NavbarProps> = ({ title = DEFAULT_TITLE }) => {
</Link>
</div>

<div className="flex-1 justify-end mr-6">
<NavbarButton label="home" linkTo="/" />
<NavbarButton label="faq" linkTo="/faq" />
<NavbarButton label="about" linkTo="/about" />
<LanguageSelector />
<ThemeSwitcher />
</div>
<NavMobile />
<NavDesktop />

<LanguageSelector />
<ThemeSwitcher />
</nav>
)
}
Expand Down
9 changes: 5 additions & 4 deletions src/components/layout/ThemeSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { useEffect, useState } from 'react'

type Theme = 'light' | 'dark'
export type Theme = 'light' | 'dark'

const ThemeSwitcher = () => {
const [theme, setTheme] = useState<Theme>('dark')
const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark')
}

useEffect(() => {
document.querySelector('html')?.setAttribute('data-theme', theme)
}, [theme])

const toggleTheme = () => {
setTheme(theme === 'dark' ? 'light' : 'dark')
}

return (
<label className="swap swap-rotate mx-3 text-white" aria-label="Theme Switcher">
{/* this hidden checkbox controls the state */}
Expand Down
6 changes: 4 additions & 2 deletions src/components/services/providers/language/data/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"contact": "Kontakt",
"prefix_social_icons": "Ihr findet mich am ehesten auf dem Rad: ",
"about": "Über",
"home": "Track neu erstellen",
"home": "Startseite",
"faq": "FAQ",
"loading": "Wird geladen...",
"close": "Schließen",
"toggle_language": "Sprache zu Englisch wechseln",
"toggle_theme": "Theme wechseln",
"visualize_file": "Die Datei anzeigen.",
"visualize_files": "Die Dateien zusammenfügen/mergen und anzeigen.",
"button_new_process": "Eine neue Datei bearbeiten.",
Expand Down Expand Up @@ -44,7 +46,7 @@
"faq_image_routelist_subtitle": "Streckenpunkteliste Garmin Edge",
"faq_tcx_question": "Warum sollte ich TCX-Dateien exportieren?",
"faq_tcx_answer": "Falls Du einen Garmin Edge besitzt, bietet sich die Verwendung von TCX-Dateien an, da diese Geräte dann vor allem separate Wegpunkte zuverlässiger anzeigen. Wenn Du beim Download die 'Optimierungs'-Option aktivierst, werden die Wegpunkte zusätzlich optimiert, insbesondere werden die Wegpunkte auf einen Punkt des Track gelegt und korrekt sortiert.",
"faq_devices_question": "Wie bekomme ich die Datei auf's Gerät?",
"faq_devices_question": "Wie bekomme ich die Datei auf das Gerät?",
"faq_devices_answer": "Verbinde einfach Dein Navigationsgerät per USB-Kabel mit Deinem Computer und warte, bis sie als externes USB-Laufwerk erkannt werden. Kopiere anschließend die Datei nach:",
"faq_devices_name": "Gerät",
"faq_devices_directory": "Verzeichnis",
Expand Down
4 changes: 3 additions & 1 deletion src/components/services/providers/language/data/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
"prefix_social_icons": "You'll find me on my bike: ",
"faq": "FAQ",
"about": "About",
"home": "Create new track",
"home": "Homepage",
"loading": "Loading...",
"close": "Close",
"toggle_language": "Switch to German",
"toggle_theme": "Switch Theme",
"visualize_file": "Visualize the file.",
"visualize_files": "Merged and visualize the files.",
"button_new_process": "Start working on a new file.",
Expand Down
14 changes: 10 additions & 4 deletions src/components/track/DownloadLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ const DownloadLink: React.FC<DownloadLinkProps> = ({
(geoJson != null ? `&wp=${encodeToBase64(JSON.stringify(geoJson))}` : '')

return (
<Link to={linkTo} className="inline-button py-2 px-3 mx-2">
<FiDownload className="inline mr-1 relative bottom-0.5" />
{getMessage('download_as')} {type.toUpperCase()}
</Link>
<>
<Link to={linkTo} className="lg:hidden flex flex-1 inline-button py-2 px-3 mx-2">
<FiDownload className="inline mr-1 relative -bottom-0.5" />
{type.toUpperCase()}
</Link>
<Link to={linkTo} className="hidden lg:flex inline-button py-2 px-3 mx-2">
<FiDownload className="inline mr-1 relative -bottom-0.5" />
{getMessage('download_as')} {type.toUpperCase()}
</Link>
</>
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/track/TrackHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ const TrackHeader: React.FC<TrackHeaderProps> = ({
<FaEyeSlash className="text-3xl" onClick={() => setShowPolyline(true)} />
)}
</div>
<div className="flex-1 flex justify-end items-center mb-4">
<div>
<div className="flex-1 flex mb-4 justify-end items-center">
<div className="flex flex-row flex-1 justify-end items-center">
<DownloadLink
trackId={trackId}
type="gpx"
Expand Down
1 change: 1 addition & 0 deletions src/pages/AboutScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ const AboutScreen = () => {
<ErtIcon />
</a>
</p>
<p className="mt-10">&nbsp;</p>
</div>
)
}
Expand Down
1 change: 1 addition & 0 deletions src/pages/FaqScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const FaqScreen = () => {
<h1 className="text-2xl highlight-color">{getMessage('faq_merge_question')}</h1>
<div className="text-lg">{getMessage('faq_merge_answer')}</div>
</p>
<p className="mt-10">&nbsp;</p>
</div>
)
}
Expand Down

0 comments on commit 70a01de

Please sign in to comment.