mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-02-06 09:55:47 +00:00
refactor(lib): move info modal to dedicated /info route
- Add InfoRedirect component for one-time redirect to /info on page load - Simplify Modal component to pure presentation (remove redirect logic) - Change NavBar info button from showModal() to Link to /info route - Remove unused window.my_modal_3 global type declaration - Fix modal centering by removing conflicting position classes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ec2bce1ccb
commit
4eb782a6f0
@ -22,6 +22,7 @@ import {
|
||||
Content,
|
||||
AuthProvider,
|
||||
Modal,
|
||||
InfoRedirect,
|
||||
InvitePage,
|
||||
LoginPage,
|
||||
SignupPage,
|
||||
@ -41,7 +42,7 @@ import {
|
||||
UserSettings,
|
||||
} from 'utopia-ui'
|
||||
|
||||
import { Route, Routes, useNavigate } from 'react-router-dom'
|
||||
import { Route, Routes } from 'react-router-dom'
|
||||
|
||||
import './App.css'
|
||||
import { Suspense, useEffect, useState } from 'react'
|
||||
@ -196,14 +197,6 @@ function App() {
|
||||
|
||||
const currentUrl = window.location.href
|
||||
const bottomRoutes = getBottomRoutes(currentUrl)
|
||||
const navigate = useNavigate()
|
||||
|
||||
// Redirect to /info if map.info_open is true (on first load)
|
||||
useEffect(() => {
|
||||
if (map?.info_open && window.location.pathname === '/') {
|
||||
void navigate('/info')
|
||||
}
|
||||
}, [map?.info_open, navigate])
|
||||
|
||||
if (map && layers)
|
||||
return (
|
||||
@ -218,6 +211,7 @@ function App() {
|
||||
>
|
||||
<Permissions api={permissionsApiInstance} adminRole={config.adminRole} />
|
||||
{tagsApi && <Tags api={tagsApi}></Tags>}
|
||||
<InfoRedirect enabled={map.info_open} />
|
||||
<SideBar routes={[...routes, ...layerPageRoutes]} bottomRoutes={bottomRoutes} />
|
||||
<Content>
|
||||
<Quests />
|
||||
|
||||
27
lib/src/Components/AppShell/InfoRedirect.tsx
Normal file
27
lib/src/Components/AppShell/InfoRedirect.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
interface InfoRedirectProps {
|
||||
/** If true, redirects to /info route on initial page load (once) */
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects to /info route on initial page load when enabled.
|
||||
* Only redirects once per session to avoid redirect loops.
|
||||
* Place this component inside the Router context but outside of Routes.
|
||||
* @category AppShell
|
||||
*/
|
||||
export function InfoRedirect({ enabled }: InfoRedirectProps) {
|
||||
const navigate = useNavigate()
|
||||
const hasRedirected = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled && window.location.pathname === '/' && !hasRedirected.current) {
|
||||
hasRedirected.current = true
|
||||
void navigate('/info')
|
||||
}
|
||||
}, [enabled, navigate])
|
||||
|
||||
return null
|
||||
}
|
||||
@ -50,14 +50,9 @@ export default function NavBar({ appName }: { appName: string }) {
|
||||
{appName}
|
||||
</h1>
|
||||
</Link>
|
||||
<button
|
||||
className='tw:btn tw:px-2 tw:btn-ghost'
|
||||
onClick={() => {
|
||||
window.my_modal_3.showModal()
|
||||
}}
|
||||
>
|
||||
<Link className='tw:btn tw:px-2 tw:btn-ghost' to='/info'>
|
||||
<QuestionMarkIcon className='tw:h-5 tw:w-5' />
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
export * from './AppShell'
|
||||
export { SideBar } from './SideBar'
|
||||
export { Content } from './Content'
|
||||
export { InfoRedirect } from './InfoRedirect'
|
||||
export { default as SVG } from 'react-inlinesvg'
|
||||
|
||||
@ -8,7 +8,7 @@ export function Modal({ children }: { children: React.ReactNode }) {
|
||||
<MapOverlayPage
|
||||
backdrop
|
||||
card
|
||||
className='tw:absolute tw:h-fit tw:max-h-[calc(100%-2.5em)] tw:top-4 tw:bottom-4 tw:left-1/2 tw:transform tw:-translate-x-1/2 tw:overflow-scroll tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-[612px] tw:transition-opacity tw:duration-500 tw:opacity-100 tw:pointer-events-auto'
|
||||
className='tw:h-fit tw:max-h-[calc(100%-2.5em)] tw:overflow-auto tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-[612px] tw:transition-opacity tw:duration-500 tw:opacity-100 tw:pointer-events-auto'
|
||||
>
|
||||
{children}
|
||||
</MapOverlayPage>
|
||||
|
||||
@ -10,11 +10,3 @@ export * from './Components/Input'
|
||||
export * from './Components/Item'
|
||||
export * from './Components/Onboarding'
|
||||
export * from './Components/Profile'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
my_modal_3: {
|
||||
showModal(): void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user