♻️ Migrate account flows
💄 Optimize container width
This commit is contained in:
parent
f5ca0c192f
commit
d92ffbae5d
@ -59,14 +59,14 @@ export function SnLoginCheckpoint({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Collapse in={!!error} sx={{ width: 320 }}>
|
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||||
<Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
<Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', width: 320, gap: 2, textAlign: 'center' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', width: '100%', gap: 2, textAlign: 'center' }}>
|
||||||
<TextField
|
<TextField
|
||||||
label={factor.type == 0 ? 'Password' : 'Verification code'}
|
label={factor.type == 0 ? 'Password' : 'Verification code'}
|
||||||
type="password"
|
type="password"
|
||||||
|
@ -44,7 +44,7 @@ export function SnLoginRouter({
|
|||||||
</Alert>
|
</Alert>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', width: 320, gap: 2, textAlign: 'center' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', width: '100%', gap: 2, textAlign: 'center' }}>
|
||||||
<ButtonGroup orientation="vertical" aria-label="Vertical button group">
|
<ButtonGroup orientation="vertical" aria-label="Vertical button group">
|
||||||
{factorList.map((factor) => (
|
{factorList.map((factor) => (
|
||||||
<Button
|
<Button
|
||||||
|
@ -6,6 +6,7 @@ import { ArrowForward } from '@mui/icons-material'
|
|||||||
import { Alert, Box, Button, Collapse, Link, TextField, Typography } from '@mui/material'
|
import { Alert, Box, Button, Collapse, Link, TextField, Typography } from '@mui/material'
|
||||||
import { SnAuthFactor, SnAuthResult, SnAuthTicket } from '@/services/auth'
|
import { SnAuthFactor, SnAuthResult, SnAuthTicket } from '@/services/auth'
|
||||||
import { useForm } from 'react-hook-form'
|
import { useForm } from 'react-hook-form'
|
||||||
|
import NextLink from 'next/link'
|
||||||
|
|
||||||
import ErrorIcon from '@mui/icons-material/Error'
|
import ErrorIcon from '@mui/icons-material/Error'
|
||||||
|
|
||||||
@ -38,14 +39,14 @@ export function SnLoginStart({ onNext }: { onNext: (val: SnAuthTicket, fcs: SnAu
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Collapse in={!!error} sx={{ width: 320 }}>
|
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||||
<Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
<Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||||
{error}
|
{error}
|
||||||
</Alert>
|
</Alert>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
|
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', width: 320, gap: 2, textAlign: 'center' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', width: '100%', gap: 2, textAlign: 'center' }}>
|
||||||
<TextField
|
<TextField
|
||||||
label="Username"
|
label="Username"
|
||||||
helperText="You can also use email address and phone number"
|
helperText="You can also use email address and phone number"
|
||||||
@ -57,8 +58,14 @@ export function SnLoginStart({ onNext }: { onNext: (val: SnAuthTicket, fcs: SnAu
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Typography variant="caption" sx={{ opacity: 0.75, mx: 2 }}>
|
<Typography variant="caption" sx={{ opacity: 0.75, mx: 2 }}>
|
||||||
By continuing means you agree to our <Link href="#">Terms of Service</Link> and{' '}
|
By continuing means you agree to our{' '}
|
||||||
<Link href="#">Privacy Policy</Link>
|
<NextLink href="/terms/privacy-policy" passHref>
|
||||||
|
<Link component="span">Privacy Policy</Link>
|
||||||
|
</NextLink>{' '}
|
||||||
|
and{' '}
|
||||||
|
<NextLink href="/terms/user-agreements" passHref>
|
||||||
|
<Link component="span">User Agreements</Link>
|
||||||
|
</NextLink>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</form>
|
</form>
|
||||||
|
@ -86,8 +86,9 @@ export default function Login() {
|
|||||||
height: 'calc(100vh - 64px)',
|
height: 'calc(100vh - 64px)',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
}}
|
}}
|
||||||
|
maxWidth="xs"
|
||||||
>
|
>
|
||||||
<Box>
|
<Box sx={{ width: '100%' }}>
|
||||||
<Typography variant="h5" component="h1">
|
<Typography variant="h5" component="h1">
|
||||||
Login
|
Login
|
||||||
</Typography>
|
</Typography>
|
||||||
|
71
src/pages/flow/accounts/confirm.tsx
Normal file
71
src/pages/flow/accounts/confirm.tsx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { sni } from '@/services/network'
|
||||||
|
import { Container, Box, Typography, CircularProgress, Alert, Collapse } from '@mui/material'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
import ErrorIcon from '@mui/icons-material/Error'
|
||||||
|
|
||||||
|
import 'animate.css'
|
||||||
|
|
||||||
|
export default function AccountConfirm() {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
|
||||||
|
async function confirm() {
|
||||||
|
try {
|
||||||
|
await sni.post('/cgi/id/users/me/confirm', {
|
||||||
|
code: router.query['code'] as string,
|
||||||
|
})
|
||||||
|
router.push('/')
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
confirm()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container
|
||||||
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
placeItems: 'center',
|
||||||
|
height: 'calc(100vh - 64px)',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
maxWidth="xs"
|
||||||
|
>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Typography variant="h5" component="h1">
|
||||||
|
Confirm Account
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle2" component="h2">
|
||||||
|
Confirm your registeration on Solar Network
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||||
|
<Alert sx={{ mt: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||||
|
{error}
|
||||||
|
</Alert>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
{!error && (
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<CircularProgress />
|
||||||
|
|
||||||
|
<Typography
|
||||||
|
variant="body2"
|
||||||
|
sx={{ mt: 3 }}
|
||||||
|
className="animate__animated animate__flash animate__infinite"
|
||||||
|
style={{ '--animate-duration': '3s' } as any}
|
||||||
|
>
|
||||||
|
Hold on a moment, we're working on it...
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
71
src/pages/flow/accounts/deletion.tsx
Normal file
71
src/pages/flow/accounts/deletion.tsx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { sni } from '@/services/network'
|
||||||
|
import { Container, Box, Typography, Alert, Collapse, Button } from '@mui/material'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
import ErrorIcon from '@mui/icons-material/Error'
|
||||||
|
|
||||||
|
import 'animate.css'
|
||||||
|
|
||||||
|
export default function AccountConfirm() {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [busy, setBusy] = useState(false)
|
||||||
|
|
||||||
|
async function confirm() {
|
||||||
|
try {
|
||||||
|
setBusy(true)
|
||||||
|
await sni.patch('/cgi/id/users/me/deletion', {
|
||||||
|
code: router.query['code'] as string,
|
||||||
|
})
|
||||||
|
router.push('/')
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.toString())
|
||||||
|
} finally {
|
||||||
|
setBusy(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container
|
||||||
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
placeItems: 'center',
|
||||||
|
height: 'calc(100vh - 64px)',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
maxWidth="xs"
|
||||||
|
>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Typography variant="h5" component="h1">
|
||||||
|
Delete Account
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle2" component="h2">
|
||||||
|
Confirm delete your account from Solar Network
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||||
|
<Alert sx={{ mt: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||||
|
{error}
|
||||||
|
</Alert>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
<Box sx={{ mt: 3 }}>
|
||||||
|
<Typography variant="body2" gutterBottom>
|
||||||
|
Are you sure you want to delete your account? This action is irreversible. All the resources created by you
|
||||||
|
or related to your account will be deleted.
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body2">
|
||||||
|
If you have changed your mind, you can close this tab at any time, nothing will be affected.
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Button sx={{ mt: 3 }} onClick={() => confirm()} disabled={busy}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
79
src/pages/flow/accounts/password-reset.tsx
Normal file
79
src/pages/flow/accounts/password-reset.tsx
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import { sni } from '@/services/network'
|
||||||
|
import { Container, Box, Typography, Alert, Collapse, Button, TextField } from '@mui/material'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
|
||||||
|
import ErrorIcon from '@mui/icons-material/Error'
|
||||||
|
|
||||||
|
import 'animate.css'
|
||||||
|
|
||||||
|
export type SnResetPasswordForm = {
|
||||||
|
password: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AccountConfirm() {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const { handleSubmit, register } = useForm<SnResetPasswordForm>()
|
||||||
|
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [busy, setBusy] = useState(false)
|
||||||
|
|
||||||
|
async function confirm(data: any) {
|
||||||
|
try {
|
||||||
|
setBusy(true)
|
||||||
|
await sni.patch('/cgi/id/users/me/password-reset', {
|
||||||
|
code: router.query['code'] as string,
|
||||||
|
new_password: data.password,
|
||||||
|
})
|
||||||
|
router.push('/')
|
||||||
|
} catch (err: any) {
|
||||||
|
setError(err.toString())
|
||||||
|
} finally {
|
||||||
|
setBusy(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container
|
||||||
|
sx={{
|
||||||
|
display: 'grid',
|
||||||
|
placeItems: 'center',
|
||||||
|
height: 'calc(100vh - 64px)',
|
||||||
|
textAlign: 'center',
|
||||||
|
}}
|
||||||
|
maxWidth="xs"
|
||||||
|
>
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Typography variant="h5" component="h1">
|
||||||
|
Reset Password
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="subtitle2" component="h2">
|
||||||
|
Reset your password on Solar Network
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Collapse in={!!error} sx={{ width: '100%' }}>
|
||||||
|
<Alert sx={{ mt: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
|
||||||
|
{error}
|
||||||
|
</Alert>
|
||||||
|
</Collapse>
|
||||||
|
|
||||||
|
<form onSubmit={handleSubmit(confirm)}>
|
||||||
|
<Box sx={{ mt: 3, display: 'flex', flexDirection: 'column', width: '100%', gap: 2, textAlign: 'center' }}>
|
||||||
|
<TextField
|
||||||
|
label="New Password"
|
||||||
|
type="password"
|
||||||
|
autoComplete="new-password"
|
||||||
|
{...register('password', { required: true })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button type="submit" disabled={busy}>
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
</form>
|
||||||
|
</Box>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user