♻️ Migrate account flows
💄 Optimize container width
			
			
This commit is contained in:
		@@ -59,14 +59,14 @@ export function SnLoginCheckpoint({
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Collapse in={!!error} sx={{ width: 320 }}>
 | 
			
		||||
      <Collapse in={!!error} sx={{ width: '100%' }}>
 | 
			
		||||
        <Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
 | 
			
		||||
          {error}
 | 
			
		||||
        </Alert>
 | 
			
		||||
      </Collapse>
 | 
			
		||||
 | 
			
		||||
      <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
 | 
			
		||||
            label={factor.type == 0 ? 'Password' : 'Verification code'}
 | 
			
		||||
            type="password"
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ export function SnLoginRouter({
 | 
			
		||||
        </Alert>
 | 
			
		||||
      </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">
 | 
			
		||||
          {factorList.map((factor) => (
 | 
			
		||||
            <Button
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import { ArrowForward } from '@mui/icons-material'
 | 
			
		||||
import { Alert, Box, Button, Collapse, Link, TextField, Typography } from '@mui/material'
 | 
			
		||||
import { SnAuthFactor, SnAuthResult, SnAuthTicket } from '@/services/auth'
 | 
			
		||||
import { useForm } from 'react-hook-form'
 | 
			
		||||
import NextLink from 'next/link'
 | 
			
		||||
 | 
			
		||||
import ErrorIcon from '@mui/icons-material/Error'
 | 
			
		||||
 | 
			
		||||
@@ -38,14 +39,14 @@ export function SnLoginStart({ onNext }: { onNext: (val: SnAuthTicket, fcs: SnAu
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Collapse in={!!error} sx={{ width: 320 }}>
 | 
			
		||||
      <Collapse in={!!error} sx={{ width: '100%' }}>
 | 
			
		||||
        <Alert sx={{ mb: 4 }} icon={<ErrorIcon fontSize="inherit" />} severity="error">
 | 
			
		||||
          {error}
 | 
			
		||||
        </Alert>
 | 
			
		||||
      </Collapse>
 | 
			
		||||
 | 
			
		||||
      <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
 | 
			
		||||
            label="Username"
 | 
			
		||||
            helperText="You can also use email address and phone number"
 | 
			
		||||
@@ -57,8 +58,14 @@ export function SnLoginStart({ onNext }: { onNext: (val: SnAuthTicket, fcs: SnAu
 | 
			
		||||
          </Button>
 | 
			
		||||
 | 
			
		||||
          <Typography variant="caption" sx={{ opacity: 0.75, mx: 2 }}>
 | 
			
		||||
            By continuing means you agree to our <Link href="#">Terms of Service</Link> and{' '}
 | 
			
		||||
            <Link href="#">Privacy Policy</Link>
 | 
			
		||||
            By continuing means you agree to our{' '}
 | 
			
		||||
            <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>
 | 
			
		||||
        </Box>
 | 
			
		||||
      </form>
 | 
			
		||||
 
 | 
			
		||||
@@ -86,8 +86,9 @@ export default function Login() {
 | 
			
		||||
        height: 'calc(100vh - 64px)',
 | 
			
		||||
        textAlign: 'center',
 | 
			
		||||
      }}
 | 
			
		||||
      maxWidth="xs"
 | 
			
		||||
    >
 | 
			
		||||
      <Box>
 | 
			
		||||
      <Box sx={{ width: '100%' }}>
 | 
			
		||||
        <Typography variant="h5" component="h1">
 | 
			
		||||
          Login
 | 
			
		||||
        </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>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user