refactor(source): reperation to merge map and landingpage (#209)

* adjustments to allow merge of map with landingpage

* 3.0.79

* 3.0.80

* version

* removed unused imports
This commit is contained in:
Anton Tranelis 2025-04-15 21:27:21 +01:00 committed by GitHub
parent eb5328e263
commit 7fdc41d679
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 33 additions and 45 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.78", "version": "3.0.80",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.78", "version": "3.0.80",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@heroicons/react": "^2.0.17", "@heroicons/react": "^2.0.17",

View File

@ -1,6 +1,6 @@
{ {
"name": "utopia-ui", "name": "utopia-ui",
"version": "3.0.78", "version": "3.0.81",
"description": "Reuseable React Components to build mapping apps for real life communities and networks", "description": "Reuseable React Components to build mapping apps for real life communities and networks",
"repository": "https://github.com/utopia-os/utopia-ui", "repository": "https://github.com/utopia-os/utopia-ui",
"homepage": "https://utopia-os.org/", "homepage": "https://utopia-os.org/",

View File

@ -13,15 +13,17 @@ export function AppShell({
appName, appName,
children, children,
assetsApi, assetsApi,
embedded,
}: { }: {
appName: string appName: string
children: React.ReactNode children: React.ReactNode
assetsApi: AssetsApi assetsApi: AssetsApi
embedded?: boolean
}) { }) {
return ( return (
<ContextWrapper> <ContextWrapper>
<div className='tw-flex tw-flex-col tw-h-full'> <div className='tw-flex tw-flex-col tw-h-full'>
<SetAppState assetsApi={assetsApi} /> <SetAppState assetsApi={assetsApi} embedded={embedded} />
<NavBar appName={appName}></NavBar> <NavBar appName={appName}></NavBar>
<div id='app-content' className='tw-flex'> <div id='app-content' className='tw-flex'>
{children} {children}

View File

@ -12,7 +12,7 @@ export function Content({ children }: ContentProps) {
return ( return (
<div <div
className={`${appState.sideBarOpen && !appState.sideBarSlim ? 'tw-ml-48' : appState.sideBarOpen && appState.sideBarSlim ? 'tw-ml-14' : ''} tw-flex tw-flex-col tw-w-full tw-h-full tw-bg-base-200 tw-relative tw-transition-all tw-duration-300`} className={`${appState.sideBarOpen && !appState.sideBarSlim ? 'tw-ml-48' : appState.sideBarOpen && appState.sideBarSlim ? 'tw-ml-14' : ''} tw-w-full tw-h-full tw-bg-base-100 tw-relative tw-transition-all tw-duration-300`}
> >
{children} {children}
</div> </div>

View File

@ -2,7 +2,7 @@ import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon'
import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon' import EllipsisVerticalIcon from '@heroicons/react/16/solid/EllipsisVerticalIcon'
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon' import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { Link, useLocation } from 'react-router-dom' import { Link } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { useAuth } from '#components/Auth/useAuth' import { useAuth } from '#components/Auth/useAuth'
@ -35,18 +35,10 @@ export default function NavBar({ appName }: { appName: string }) {
const nameRef = useRef<HTMLHeadingElement>(null) const nameRef = useRef<HTMLHeadingElement>(null)
const [nameWidth, setNameWidth] = useState<number>(0) const [nameWidth, setNameWidth] = useState<number>(0)
const location = useLocation()
const [showNav, setShowNav] = useState<boolean>(false)
useEffect(() => { useEffect(() => {
showNav && nameRef.current && setNameWidth(nameRef.current.scrollWidth) !appState.embedded && nameRef.current && setNameWidth(nameRef.current.scrollWidth)
}, [nameRef, appName, showNav]) }, [nameRef, appName, appState.embedded])
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded !== 'true' && setShowNav(true)
}, [location])
const onLogout = async () => { const onLogout = async () => {
await toast.promise(logout(), { await toast.promise(logout(), {
@ -66,7 +58,7 @@ export default function NavBar({ appName }: { appName: string }) {
}) })
} }
if (showNav) { if (!appState.embedded) {
return ( return (
<> <>
<div className='tw-navbar tw-bg-base-100 tw-z-[9998] tw-shadow-xl tw-relative'> <div className='tw-navbar tw-bg-base-100 tw-z-[9998] tw-shadow-xl tw-relative'>

View File

@ -4,13 +4,22 @@ import { useSetAppState } from './hooks/useAppState'
import type { AssetsApi } from '#types/AssetsApi' import type { AssetsApi } from '#types/AssetsApi'
export const SetAppState = ({ assetsApi }: { assetsApi: AssetsApi }) => { export const SetAppState = ({
assetsApi,
embedded,
}: {
assetsApi: AssetsApi
embedded?: boolean
}) => {
const setAppState = useSetAppState() const setAppState = useSetAppState()
useEffect(() => { useEffect(() => {
setAppState({ assetsApi }) setAppState({ assetsApi })
// eslint-disable-next-line react-hooks/exhaustive-deps }, [assetsApi, setAppState])
}, [assetsApi])
useEffect(() => {
setAppState({ embedded })
}, [embedded, setAppState])
return <></> return <></>
} }

View File

@ -1,5 +1,4 @@
import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon' import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon'
import { useState, useEffect } from 'react'
import { NavLink, useLocation } from 'react-router-dom' import { NavLink, useLocation } from 'react-router-dom'
import { useAppState, useSetAppState } from './hooks/useAppState' import { useAppState, useSetAppState } from './hooks/useAppState'
@ -19,14 +18,6 @@ export interface Route {
export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoutes?: Route[] }) { export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoutes?: Route[] }) {
const location = useLocation() const location = useLocation()
const [embedded, setEmbedded] = useState<boolean>(true)
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded !== 'true' && setEmbedded(false)
}, [location])
const params = new URLSearchParams(window.location.search) const params = new URLSearchParams(window.location.search)
const appState = useAppState() const appState = useAppState()
@ -45,12 +36,12 @@ export function SideBar({ routes, bottomRoutes }: { routes: Route[]; bottomRoute
id='sidenav' id='sidenav'
className={`${appState.sideBarOpen ? 'tw-translate-x-0' : '-tw-translate-x-full'} className={`${appState.sideBarOpen ? 'tw-translate-x-0' : '-tw-translate-x-full'}
${appState.sideBarSlim ? 'tw-w-14' : 'tw-w-48'} ${appState.sideBarSlim ? 'tw-w-14' : 'tw-w-48'}
${embedded ? 'tw-mt-0 tw-h-[100dvh]' : 'tw-mt-16 tw-h-[calc(100dvh-64px)]'} ${appState.embedded ? 'tw-mt-0 tw-h-[100dvh]' : 'tw-mt-16 tw-h-[calc(100dvh-64px)]'}
tw-fixed tw-left-0 tw-transition-all tw-duration-300 tw-top-0 tw-z-[10035] tw-fixed tw-left-0 tw-transition-all tw-duration-300 tw-top-0 tw-z-[10035]
tw-overflow-hidden tw-shadow-xl dark:tw-bg-zinc-800`} tw-overflow-hidden tw-shadow-xl dark:tw-bg-zinc-800`}
> >
<div <div
className={`tw-flex tw-flex-col ${embedded ? 'tw-h-full' : 'tw-h-[calc(100dvh-64px)]'}`} className={`tw-flex tw-flex-col ${appState.embedded ? 'tw-h-full' : 'tw-h-[calc(100dvh-64px)]'}`}
> >
<ul <ul
className='tw-menu tw-w-full tw-bg-base-100 tw-text-base-content tw-p-0' className='tw-menu tw-w-full tw-bg-base-100 tw-text-base-content tw-p-0'

View File

@ -8,6 +8,7 @@ interface AppState {
assetsApi: AssetsApi assetsApi: AssetsApi
sideBarOpen: boolean sideBarOpen: boolean
sideBarSlim: boolean sideBarSlim: boolean
embedded: boolean
} }
type UseAppManagerResult = ReturnType<typeof useAppManager> type UseAppManagerResult = ReturnType<typeof useAppManager>
@ -16,6 +17,7 @@ const initialAppState: AppState = {
assetsApi: {} as AssetsApi, assetsApi: {} as AssetsApi,
sideBarOpen: false, sideBarOpen: false,
sideBarSlim: false, sideBarSlim: false,
embedded: false,
} }
const AppContext = createContext<UseAppManagerResult>({ const AppContext = createContext<UseAppManagerResult>({

View File

@ -14,11 +14,12 @@ import FlagIcon from '@heroicons/react/24/outline/FlagIcon'
import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon' import MagnifyingGlassIcon from '@heroicons/react/24/outline/MagnifyingGlassIcon'
import axios from 'axios' import axios from 'axios'
import { LatLng, LatLngBounds, marker } from 'leaflet' import { LatLng, LatLngBounds, marker } from 'leaflet'
import { useEffect, useRef, useState } from 'react' import { useRef, useState } from 'react'
import SVG from 'react-inlinesvg' import SVG from 'react-inlinesvg'
import { useMap, useMapEvents } from 'react-leaflet' import { useMap, useMapEvents } from 'react-leaflet'
import { useLocation, useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useAppState } from '#components/AppShell/hooks/useAppState'
import { useDebounce } from '#components/Map/hooks/useDebounce' import { useDebounce } from '#components/Map/hooks/useDebounce'
import { useAddFilterTag } from '#components/Map/hooks/useFilter' import { useAddFilterTag } from '#components/Map/hooks/useFilter'
import { useItems } from '#components/Map/hooks/useItems' import { useItems } from '#components/Map/hooks/useItems'
@ -48,6 +49,7 @@ export const SearchControl = () => {
const items = useItems() const items = useItems()
const leafletRefs = useLeafletRefs() const leafletRefs = useLeafletRefs()
const addFilterTag = useAddFilterTag() const addFilterTag = useAddFilterTag()
const appState = useAppState()
useMapEvents({ useMapEvents({
popupopen: () => { popupopen: () => {
@ -97,21 +99,13 @@ export const SearchControl = () => {
} }
const searchInput = useRef<HTMLInputElement>(null) const searchInput = useRef<HTMLInputElement>(null)
const [embedded, setEmbedded] = useState<boolean>(true)
const location = useLocation()
useEffect(() => {
const params = new URLSearchParams(location.search)
const embedded = params.get('embedded')
embedded !== 'true' && setEmbedded(false)
}, [location])
return ( return (
<> <>
{!(windowDimensions.height < 500 && popupOpen && hideSuggestions) && ( {!(windowDimensions.height < 500 && popupOpen && hideSuggestions) && (
<div className='tw-w-[calc(100vw-2rem)] tw-max-w-[22rem] '> <div className='tw-w-[calc(100vw-2rem)] tw-max-w-[22rem] '>
<div className='tw-flex tw-flex-row'> <div className='tw-flex tw-flex-row'>
{embedded && <SidebarControl />} {appState.embedded && <SidebarControl />}
<div className='tw-relative'> <div className='tw-relative'>
<input <input
type='text' type='text'

View File

@ -181,9 +181,7 @@ export function UtopiaMapInner({
} }
return ( return (
<div <div className={`tw-h-full ${selectNewItemPosition != null ? 'crosshair-cursor-enabled' : ''}`}>
className={`tw-h-full ${selectNewItemPosition != null ? 'crosshair-cursor-enabled' : undefined}`}
>
<Outlet /> <Outlet />
<Control position='topLeft' zIndex='1000' absolute> <Control position='topLeft' zIndex='1000' absolute>
<SearchControl /> <SearchControl />