make app icon url not required, swap change theme button icons, fix loading spinners render, add loading state to submit button on create page
This commit is contained in:
@@ -3,7 +3,7 @@ import { Button } from '@/shared/Button/Button'
|
|||||||
import { Input } from '@/shared/Input/Input'
|
import { Input } from '@/shared/Input/Input'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { Autocomplete, CircularProgress, Stack, Typography } from '@mui/material'
|
import { Autocomplete, Stack, Typography } from '@mui/material'
|
||||||
import { StyledInput } from './styled'
|
import { StyledInput } from './styled'
|
||||||
import { FormEvent, useEffect, useState } from 'react'
|
import { FormEvent, useEffect, useState } from 'react'
|
||||||
import { isEmptyString } from '@/utils/helpers/helpers'
|
import { isEmptyString } from '@/utils/helpers/helpers'
|
||||||
@@ -13,6 +13,7 @@ import { selectApps } from '@/store'
|
|||||||
import { dbi } from '@/modules/db'
|
import { dbi } from '@/modules/db'
|
||||||
import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar'
|
import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar'
|
||||||
import { setApps } from '@/store/reducers/content.slice'
|
import { setApps } from '@/store/reducers/content.slice'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
export const ModalAppDetails = () => {
|
export const ModalAppDetails = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
||||||
@@ -118,7 +119,7 @@ export const ModalAppDetails = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFormValid = !isEmptyString(url) && !isEmptyString(name) && !isEmptyString(icon)
|
const isFormValid = !isEmptyString(url) && !isEmptyString(name)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal open={isModalOpened} onClose={handleCloseModal}>
|
<Modal open={isModalOpened} onClose={handleCloseModal}>
|
||||||
@@ -165,7 +166,7 @@ export const ModalAppDetails = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Button varianttype="secondary" type="submit" fullWidth disabled={!isFormValid || isLoading}>
|
<Button varianttype="secondary" type="submit" fullWidth disabled={!isFormValid || isLoading}>
|
||||||
Save changes {isLoading && <CircularProgress sx={{ marginLeft: '0.5rem' }} size={'1rem'} />}
|
Save changes {isLoading && <LoadingSpinner />}
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -5,7 +5,7 @@ import { Button } from '@/shared/Button/Button'
|
|||||||
import { Input } from '@/shared/Input/Input'
|
import { Input } from '@/shared/Input/Input'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { CircularProgress, Stack, Typography, useTheme } from '@mui/material'
|
import { Stack, Typography, useTheme } from '@mui/material'
|
||||||
import { StyledAppLogo } from './styled'
|
import { StyledAppLogo } from './styled'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { useForm } from 'react-hook-form'
|
import { useForm } from 'react-hook-form'
|
||||||
@@ -18,6 +18,7 @@ import { fetchNip05 } from '@/utils/helpers/helpers'
|
|||||||
import { DOMAIN } from '@/utils/consts'
|
import { DOMAIN } from '@/utils/consts'
|
||||||
import { CheckmarkIcon } from '@/assets'
|
import { CheckmarkIcon } from '@/assets'
|
||||||
import { getPublicKey, nip19 } from 'nostr-tools'
|
import { getPublicKey, nip19 } from 'nostr-tools'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
const FORM_DEFAULT_VALUES = {
|
const FORM_DEFAULT_VALUES = {
|
||||||
username: '',
|
username: '',
|
||||||
@@ -195,7 +196,7 @@ export const ModalImportKeys = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Button type="submit" disabled={isLoading}>
|
<Button type="submit" disabled={isLoading}>
|
||||||
Import key {isLoading && <CircularProgress sx={{ marginLeft: '0.5rem' }} size={'1rem'} />}
|
Import key {isLoading && <LoadingSpinner />}
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -4,7 +4,7 @@ import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
|||||||
import { swicCall } from '@/modules/swic'
|
import { swicCall } from '@/modules/swic'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { CircularProgress, Stack, Typography } from '@mui/material'
|
import { Stack, Typography } from '@mui/material'
|
||||||
import { StyledAppLogo } from './styled'
|
import { StyledAppLogo } from './styled'
|
||||||
import { Input } from '@/shared/Input/Input'
|
import { Input } from '@/shared/Input/Input'
|
||||||
import { Button } from '@/shared/Button/Button'
|
import { Button } from '@/shared/Button/Button'
|
||||||
@@ -16,6 +16,7 @@ import { DOMAIN } from '@/utils/consts'
|
|||||||
import { fetchNip05 } from '@/utils/helpers/helpers'
|
import { fetchNip05 } from '@/utils/helpers/helpers'
|
||||||
import { usePassword } from '@/hooks/usePassword'
|
import { usePassword } from '@/hooks/usePassword'
|
||||||
import { dbi } from '@/modules/db'
|
import { dbi } from '@/modules/db'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
const FORM_DEFAULT_VALUES = {
|
const FORM_DEFAULT_VALUES = {
|
||||||
username: '',
|
username: '',
|
||||||
@@ -120,7 +121,7 @@ export const ModalLogin = () => {
|
|||||||
error={!!errors.password}
|
error={!!errors.password}
|
||||||
/>
|
/>
|
||||||
<Button type="submit" fullWidth disabled={isLoading}>
|
<Button type="submit" fullWidth disabled={isLoading}>
|
||||||
Add account {isLoading && <CircularProgress sx={{ marginLeft: '0.5rem' }} size={'1rem'} />}
|
Add account {isLoading && <LoadingSpinner />}
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { Box, CircularProgress, Stack, Typography } from '@mui/material'
|
import { Box, Stack, Typography } from '@mui/material'
|
||||||
import { StyledButton, StyledSettingContainer, StyledSynchedText } from './styled'
|
import { StyledButton, StyledSettingContainer, StyledSynchedText } from './styled'
|
||||||
import { SectionTitle } from '@/shared/SectionTitle/SectionTitle'
|
import { SectionTitle } from '@/shared/SectionTitle/SectionTitle'
|
||||||
import { CheckmarkIcon } from '@/assets'
|
import { CheckmarkIcon } from '@/assets'
|
||||||
@@ -16,6 +16,7 @@ import { usePassword } from '@/hooks/usePassword'
|
|||||||
import { useAppSelector } from '@/store/hooks/redux'
|
import { useAppSelector } from '@/store/hooks/redux'
|
||||||
import { selectKeys } from '@/store'
|
import { selectKeys } from '@/store'
|
||||||
import { isValidPassphase, isWeakPassphase } from '@/modules/keys'
|
import { isValidPassphase, isWeakPassphase } from '@/modules/keys'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
type ModalSettingsProps = {
|
type ModalSettingsProps = {
|
||||||
isSynced: boolean
|
isSynced: boolean
|
||||||
@@ -141,7 +142,7 @@ export const ModalSettings: FC<ModalSettingsProps> = ({ isSynced }) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
<StyledButton type="submit" fullWidth disabled={!isChecked}>
|
<StyledButton type="submit" fullWidth disabled={!isChecked}>
|
||||||
Sync {isLoading && <CircularProgress sx={{ marginLeft: '0.5rem' }} size={'1rem'} />}
|
Sync {isLoading && <LoadingSpinner mode="secondary" />}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
</StyledSettingContainer>
|
</StyledSettingContainer>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@@ -2,7 +2,7 @@ import { useEnqueueSnackbar } from '@/hooks/useEnqueueSnackbar'
|
|||||||
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
||||||
import { Modal } from '@/shared/Modal/Modal'
|
import { Modal } from '@/shared/Modal/Modal'
|
||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { CircularProgress, Stack, Typography, useTheme } from '@mui/material'
|
import { Stack, Typography, useTheme } from '@mui/material'
|
||||||
import React, { ChangeEvent, useEffect, useState } from 'react'
|
import React, { ChangeEvent, useEffect, useState } from 'react'
|
||||||
import { StyledAppLogo } from './styled'
|
import { StyledAppLogo } from './styled'
|
||||||
import { Input } from '@/shared/Input/Input'
|
import { Input } from '@/shared/Input/Input'
|
||||||
@@ -12,6 +12,7 @@ import { swicCall } from '@/modules/swic'
|
|||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import { DOMAIN } from '@/utils/consts'
|
import { DOMAIN } from '@/utils/consts'
|
||||||
import { fetchNip05 } from '@/utils/helpers/helpers'
|
import { fetchNip05 } from '@/utils/helpers/helpers'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
export const ModalSignUp = () => {
|
export const ModalSignUp = () => {
|
||||||
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
const { getModalOpened, createHandleCloseReplace } = useModalSearchParams()
|
||||||
@@ -110,7 +111,7 @@ export const ModalSignUp = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button fullWidth type="submit" disabled={isLoading}>
|
<Button fullWidth type="submit" disabled={isLoading}>
|
||||||
Create account {isLoading && <CircularProgress sx={{ marginLeft: '0.5rem' }} size={'1rem'} />}
|
Create account {isLoading && <LoadingSpinner />}
|
||||||
</Button>
|
</Button>
|
||||||
</Stack>
|
</Stack>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@@ -23,7 +23,7 @@ export const Header = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isDarkMode = themeMode === 'dark'
|
const isDarkMode = themeMode === 'dark'
|
||||||
const themeIcon = isDarkMode ? <DarkModeIcon htmlColor="#fff" /> : <LightModeIcon htmlColor="#000" />
|
const themeIcon = isDarkMode ? <LightModeIcon htmlColor="#fff" /> : <DarkModeIcon htmlColor="#000" />
|
||||||
|
|
||||||
const handleChangeMode = () => {
|
const handleChangeMode = () => {
|
||||||
dispatch(setThemeMode({ mode: isDarkMode ? 'light' : 'dark' }))
|
dispatch(setThemeMode({ mode: isDarkMode ? 'light' : 'dark' }))
|
||||||
|
@@ -9,6 +9,7 @@ import { useModalSearchParams } from '@/hooks/useModalSearchParams'
|
|||||||
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
import { MODAL_PARAMS_KEYS } from '@/types/modal'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { getReferrerAppUrl } from '@/utils/helpers/helpers'
|
import { getReferrerAppUrl } from '@/utils/helpers/helpers'
|
||||||
|
import { LoadingSpinner } from '@/shared/LoadingSpinner/LoadingSpinner'
|
||||||
|
|
||||||
const CreatePage = () => {
|
const CreatePage = () => {
|
||||||
const notify = useEnqueueSnackbar()
|
const notify = useEnqueueSnackbar()
|
||||||
@@ -17,6 +18,8 @@ const CreatePage = () => {
|
|||||||
|
|
||||||
const [searchParams] = useSearchParams()
|
const [searchParams] = useSearchParams()
|
||||||
|
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
const name = searchParams.get('name') || ''
|
const name = searchParams.get('name') || ''
|
||||||
const token = searchParams.get('token') || ''
|
const token = searchParams.get('token') || ''
|
||||||
const appNpub = searchParams.get('appNpub') || ''
|
const appNpub = searchParams.get('appNpub') || ''
|
||||||
@@ -31,12 +34,14 @@ const CreatePage = () => {
|
|||||||
|
|
||||||
const handleClickAddAccount = async () => {
|
const handleClickAddAccount = async () => {
|
||||||
try {
|
try {
|
||||||
|
setIsLoading(true)
|
||||||
const key: any = await swicCall('generateKey', name)
|
const key: any = await swicCall('generateKey', name)
|
||||||
|
|
||||||
const appUrl = getReferrerAppUrl();
|
const appUrl = getReferrerAppUrl()
|
||||||
|
|
||||||
console.log('Created', key.npub, 'app', appUrl)
|
console.log('Created', key.npub, 'app', appUrl)
|
||||||
setCreated(true)
|
setCreated(true)
|
||||||
|
setIsLoading(false)
|
||||||
|
|
||||||
handleOpen(MODAL_PARAMS_KEYS.CONFIRM_CONNECT, {
|
handleOpen(MODAL_PARAMS_KEYS.CONFIRM_CONNECT, {
|
||||||
search: {
|
search: {
|
||||||
@@ -53,6 +58,7 @@ const CreatePage = () => {
|
|||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
notify(error.message || error.toString(), 'error')
|
notify(error.message || error.toString(), 'error')
|
||||||
|
setIsLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +94,9 @@ const CreatePage = () => {
|
|||||||
<Typography textAlign={'left'} variant="h6" paddingTop="0.5em">
|
<Typography textAlign={'left'} variant="h6" paddingTop="0.5em">
|
||||||
Chosen name: <b>{nip05}</b>
|
Chosen name: <b>{nip05}</b>
|
||||||
</Typography>
|
</Typography>
|
||||||
<GetStartedButton onClick={handleClickAddAccount}>Create account</GetStartedButton>
|
<GetStartedButton onClick={handleClickAddAccount}>
|
||||||
|
Create account {isLoading && <LoadingSpinner />}
|
||||||
|
</GetStartedButton>
|
||||||
|
|
||||||
<Typography textAlign={'left'} variant="h5" paddingTop="1em">
|
<Typography textAlign={'left'} variant="h5" paddingTop="1em">
|
||||||
What you need to know:
|
What you need to know:
|
||||||
|
@@ -48,6 +48,7 @@ export const StyledEmptyAppsBox = styled(Box)(({ theme }) => {
|
|||||||
placeItems: 'center',
|
placeItems: 'center',
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
opacity: '0.6',
|
opacity: '0.6',
|
||||||
|
maxHeight: '100%',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@@ -28,20 +28,20 @@ const StyledButton = styled(
|
|||||||
},
|
},
|
||||||
color: theme.palette.text.primary,
|
color: theme.palette.text.primary,
|
||||||
'&.disabled': {
|
'&.disabled': {
|
||||||
opacity: 0.5,
|
background: `${theme.palette.backgroundSecondary.default}50`,
|
||||||
cursor: 'not-allowed',
|
cursor: 'not-allowed',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
...commonStyles,
|
...commonStyles,
|
||||||
'&.button:is(:hover, :active, &, .disabled)': {
|
'&.button:is(:hover, :active, &)': {
|
||||||
background: theme.palette.primary.main,
|
background: theme.palette.primary.main,
|
||||||
},
|
},
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
'&.disabled': {
|
'&.disabled': {
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
opacity: 0.5,
|
background: `${theme.palette.primary.main}50`,
|
||||||
cursor: 'not-allowed',
|
cursor: 'not-allowed',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
17
src/shared/LoadingSpinner/LoadingSpinner.tsx
Normal file
17
src/shared/LoadingSpinner/LoadingSpinner.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { CircularProgress, CircularProgressProps, styled } from '@mui/material'
|
||||||
|
import { FC } from 'react'
|
||||||
|
|
||||||
|
type LoadingSpinnerProps = CircularProgressProps & {
|
||||||
|
mode?: 'default' | 'secondary'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LoadingSpinner: FC<LoadingSpinnerProps> = (props) => {
|
||||||
|
return <StyledCircularProgress {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export const StyledCircularProgress = styled((props: LoadingSpinnerProps) => (
|
||||||
|
<CircularProgress size={'1rem'} {...props} />
|
||||||
|
))(({ theme, mode = 'default' }) => ({
|
||||||
|
marginLeft: '0.5rem',
|
||||||
|
color: mode === 'default' ? theme.palette.text.secondary : theme.palette.text.primary,
|
||||||
|
}))
|
Reference in New Issue
Block a user