feat: add modal with login, register, nostr routes
This commit is contained in:
parent
87c6807ba0
commit
868ae6f23e
77
src/layouts/modal/index.tsx
Normal file
77
src/layouts/modal/index.tsx
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import { Box, Button, Modal as ModalMui, Typography } from '@mui/material'
|
||||||
|
import {
|
||||||
|
Link,
|
||||||
|
matchPath,
|
||||||
|
Outlet,
|
||||||
|
useLocation,
|
||||||
|
useNavigate
|
||||||
|
} from 'react-router-dom'
|
||||||
|
import styles from './style.module.scss'
|
||||||
|
import { appPublicRoutes } from '../../routes'
|
||||||
|
|
||||||
|
function useRouteMatch(patterns: readonly string[]) {
|
||||||
|
const { pathname } = useLocation()
|
||||||
|
|
||||||
|
for (let i = 0; i < patterns.length; i += 1) {
|
||||||
|
const pattern = patterns[i]
|
||||||
|
const possibleMatch = matchPath(pattern, pathname)
|
||||||
|
if (possibleMatch !== null) {
|
||||||
|
return possibleMatch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Modal = () => {
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const tabs = [
|
||||||
|
{ to: appPublicRoutes.login, title: 'Login', label: 'Login' },
|
||||||
|
{ to: appPublicRoutes.register, title: 'Register', label: 'Register' },
|
||||||
|
{ to: appPublicRoutes.nostr, title: 'Login', label: <>Ostrich</> }
|
||||||
|
]
|
||||||
|
const routeMatch = useRouteMatch(tabs.map((t) => t.to))
|
||||||
|
const activeTab = routeMatch?.pattern?.path
|
||||||
|
const handleClose = () => {
|
||||||
|
navigate(appPublicRoutes.landingPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalMui
|
||||||
|
open={true}
|
||||||
|
onClose={handleClose}
|
||||||
|
aria-labelledby="modal-title"
|
||||||
|
aria-describedby="modal-description"
|
||||||
|
>
|
||||||
|
<Box className={styles.modal}>
|
||||||
|
<Typography id="modal-title" variant="h2">
|
||||||
|
Login
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box component={'ul'}>
|
||||||
|
{tabs.map((t) => {
|
||||||
|
return (
|
||||||
|
<Link to={t.to} key={t.to}>
|
||||||
|
<Button
|
||||||
|
variant={
|
||||||
|
activeTab === t.to || t.to === appPublicRoutes.nostr
|
||||||
|
? 'contained'
|
||||||
|
: 'text'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{t.label}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Outlet />
|
||||||
|
|
||||||
|
<Typography id="modal-description" variant="h4">
|
||||||
|
Welcome to Sigit
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</ModalMui>
|
||||||
|
)
|
||||||
|
}
|
14
src/layouts/modal/style.module.scss
Normal file
14
src/layouts/modal/style.module.scss
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
.modal {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
|
||||||
|
background-color: white;
|
||||||
|
padding: 4px;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
max-width: 500px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { Box, Button, Container, TextField, Typography } from '@mui/material'
|
import { Box, Button, TextField } from '@mui/material'
|
||||||
import { getPublicKey, nip19 } from 'nostr-tools'
|
import { getPublicKey, nip19 } from 'nostr-tools'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
@ -22,6 +22,7 @@ import { npubToHex, queryNip05 } from '../../utils'
|
|||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
import { hexToBytes } from '@noble/hashes/utils'
|
import { hexToBytes } from '@noble/hashes/utils'
|
||||||
import { NIP05_REGEX } from '../../constants'
|
import { NIP05_REGEX } from '../../constants'
|
||||||
|
import { appPublicRoutes } from '../../routes'
|
||||||
|
|
||||||
export const Login = () => {
|
export const Login = () => {
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
@ -352,29 +353,31 @@ export const Login = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container maxWidth={'sm'}>
|
<>
|
||||||
{isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
|
{isLoading && <LoadingSpinner desc={loadingSpinnerDesc} />}
|
||||||
<div className={styles.loginPage}>
|
|
||||||
<Typography variant="h4">Welcome to Sigit</Typography>
|
|
||||||
<TextField
|
|
||||||
onKeyDown={handleInputKeyDown}
|
|
||||||
label="nip05 login / nip46 bunker string"
|
|
||||||
value={inputValue}
|
|
||||||
onChange={(e) => setInputValue(e.target.value)}
|
|
||||||
sx={{ width: '100%', mt: 2 }}
|
|
||||||
/>
|
|
||||||
{isNostrExtensionAvailable && (
|
|
||||||
<Button onClick={loginWithExtension} variant="text">
|
|
||||||
Login with extension
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
<Box>
|
||||||
<Button disabled={!inputValue} onClick={login} variant="contained">
|
<div className={styles.loginPage}>
|
||||||
Login
|
<TextField
|
||||||
</Button>
|
onKeyDown={handleInputKeyDown}
|
||||||
</Box>
|
label="nip05 login / nip46 bunker string"
|
||||||
</div>
|
value={inputValue}
|
||||||
</Container>
|
onChange={(e) => setInputValue(e.target.value)}
|
||||||
|
sx={{ width: '100%', mt: 2 }}
|
||||||
|
/>
|
||||||
|
{isNostrExtensionAvailable && (
|
||||||
|
<Button onClick={loginWithExtension} variant="text">
|
||||||
|
Login with extension
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Button disabled={!inputValue} onClick={login} variant="contained">
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
3
src/pages/nostr/index.tsx
Normal file
3
src/pages/nostr/index.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const Nostr = () => {
|
||||||
|
return <>Nostr</>
|
||||||
|
}
|
3
src/pages/register/index.tsx
Normal file
3
src/pages/register/index.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const Register = () => {
|
||||||
|
return <>Register</>
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
|
import { Modal } from '../layouts/modal'
|
||||||
import { CreatePage } from '../pages/create'
|
import { CreatePage } from '../pages/create'
|
||||||
import { HomePage } from '../pages/home'
|
import { HomePage } from '../pages/home'
|
||||||
import { LandingPage } from '../pages/landing'
|
import { LandingPage } from '../pages/landing'
|
||||||
import { Login } from '../pages/login'
|
import { Login } from '../pages/login'
|
||||||
|
import { Nostr } from '../pages/nostr'
|
||||||
import { ProfilePage } from '../pages/profile'
|
import { ProfilePage } from '../pages/profile'
|
||||||
|
import { Register } from '../pages/register'
|
||||||
import { SettingsPage } from '../pages/settings/Settings'
|
import { SettingsPage } from '../pages/settings/Settings'
|
||||||
import { CacheSettingsPage } from '../pages/settings/cache'
|
import { CacheSettingsPage } from '../pages/settings/cache'
|
||||||
import { ProfileSettingsPage } from '../pages/settings/profile'
|
import { ProfileSettingsPage } from '../pages/settings/profile'
|
||||||
@ -26,6 +29,8 @@ export const appPublicRoutes = {
|
|||||||
profile: '/profile/:npub',
|
profile: '/profile/:npub',
|
||||||
landingPage: '/',
|
landingPage: '/',
|
||||||
login: '/login',
|
login: '/login',
|
||||||
|
register: '/login/register',
|
||||||
|
nostr: '/login/nostr',
|
||||||
verify: '/verify',
|
verify: '/verify',
|
||||||
source: 'https://git.sigit.io/sig/it'
|
source: 'https://git.sigit.io/sig/it'
|
||||||
}
|
}
|
||||||
@ -79,9 +84,24 @@ export const publicRoutes: PublicRouteProps[] = [
|
|||||||
element: <LandingPage />,
|
element: <LandingPage />,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: appPublicRoutes.login,
|
element: <Modal />,
|
||||||
hiddenWhenLoggedIn: true,
|
children: [
|
||||||
element: <Login />
|
{
|
||||||
|
path: appPublicRoutes.login,
|
||||||
|
hiddenWhenLoggedIn: true,
|
||||||
|
element: <Login />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: appPublicRoutes.register,
|
||||||
|
hiddenWhenLoggedIn: true,
|
||||||
|
element: <Register />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: appPublicRoutes.nostr,
|
||||||
|
hiddenWhenLoggedIn: true,
|
||||||
|
element: <Nostr />
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,14 @@ export const theme = extendTheme({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
MuiModal: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: {
|
||||||
|
insetBlock: '25px',
|
||||||
|
insetInline: '20px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
MuiButton: {
|
MuiButton: {
|
||||||
styleOverrides: {
|
styleOverrides: {
|
||||||
root: {
|
root: {
|
||||||
|
Loading…
Reference in New Issue
Block a user