@campxdev/shared 1.7.9 → 1.7.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/shared",
3
- "version": "1.7.9",
3
+ "version": "1.7.10",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -30,8 +30,8 @@ function ChangePassword({ close }) {
30
30
  try {
31
31
  await axios.post(
32
32
  isDevelopment
33
- ? 'https://auth-api.campx.dev/auth/change-password'
34
- : 'https://auth-api.campx.in/auth/change-password',
33
+ ? 'https://api.campx.dev/auth-server/auth/change-password'
34
+ : 'https://api.campx.in/auth-server/auth/change-password',
35
35
  {
36
36
  oldPassword,
37
37
  newPassword,
@@ -1,14 +1,29 @@
1
1
  import { Visibility, VisibilityOff } from '@mui/icons-material'
2
- import { Alert, Box, IconButton, InputAdornment, Stack } from '@mui/material'
2
+ import {
3
+ Alert,
4
+ Box,
5
+ Button,
6
+ IconButton,
7
+ InputAdornment,
8
+ Stack,
9
+ Typography,
10
+ styled,
11
+ } from '@mui/material'
3
12
  import axiosBase from 'axios'
4
13
  import Cookies from 'js-cookie'
5
- import { useState } from 'react'
14
+ import { useEffect, useState } from 'react'
6
15
  import { useForm } from 'react-hook-form'
7
16
  import ActionButton from './ActionButton'
8
17
  import { FormTextField } from './HookForm'
18
+ import axios from '../config/axios'
19
+ import ResetPassword from './ResetPassword'
20
+ import { Link } from 'react-router-dom'
9
21
 
10
22
  export function LoginForm({ loginUrl }: { loginUrl?: string }) {
11
23
  const [showPassword, setShowPassword] = useState(false)
24
+ const [forgotMail, setForgotMail] = useState(null)
25
+ const [forgotPassword, setForgotPassword] = useState(true)
26
+ const [resetPassword, setResetPassword] = useState(false)
12
27
  const { handleSubmit, control } = useForm()
13
28
  const [error, setError] = useState('')
14
29
 
@@ -30,44 +45,115 @@ export function LoginForm({ loginUrl }: { loginUrl?: string }) {
30
45
  }
31
46
  }
32
47
 
48
+ const [mailSent, setMailSent] = useState(false)
49
+
50
+ async function handleSendMail() {
51
+ try {
52
+ await axios
53
+ .get(
54
+ `https://api.campx.dev/auth-server/auth/forgot-password?email=${forgotMail}`,
55
+ )
56
+ .then((res) => {
57
+ setForgotMail(null)
58
+ setMailSent(true)
59
+ setError(null)
60
+ })
61
+ } catch (err) {
62
+ setError(err.response.data.message ?? 'Server Error')
63
+ setMailSent(false)
64
+ }
65
+ }
66
+
67
+ useEffect(() => {
68
+ const restLink = window.location.pathname.split('/')[1]
69
+ if (restLink == 'reset-password') {
70
+ setResetPassword(true)
71
+ }
72
+ }, [])
73
+
33
74
  return (
34
75
  <>
35
- <form onSubmit={handleSubmit(onSubmit)}>
36
- <Stack gap={'30px'}>
37
- <Box>
76
+ {resetPassword ? (
77
+ <>
78
+ <ResetPassword />
79
+ </>
80
+ ) : forgotPassword ? (
81
+ <form onSubmit={handleSubmit(onSubmit)}>
82
+ <Stack gap={'30px'} sx={{ display: resetPassword ? 'none' : 'flex' }}>
83
+ <Box>
84
+ <FormTextField
85
+ control={control}
86
+ name="username"
87
+ label="User ID"
88
+ required
89
+ />
90
+ </Box>
91
+ <Box>
92
+ <FormTextField
93
+ control={control}
94
+ name="password"
95
+ label="Password"
96
+ type={showPassword ? 'text' : 'password'}
97
+ required
98
+ InputProps={{
99
+ endAdornment: (
100
+ <InputAdornment position="end">
101
+ <IconButton
102
+ size="small"
103
+ aria-label="toggle password visibility"
104
+ onClick={() => setShowPassword((prev) => !prev)}
105
+ edge="end"
106
+ >
107
+ {showPassword ? <VisibilityOff /> : <Visibility />}
108
+ </IconButton>
109
+ </InputAdornment>
110
+ ),
111
+ }}
112
+ />
113
+ </Box>
114
+ <ActionButton type="submit">Login</ActionButton>
115
+ <Typography
116
+ variant="h6"
117
+ align="right"
118
+ onClick={() => setForgotPassword(false)}
119
+ >
120
+ <StyledLink to="/">Forgot Password</StyledLink>
121
+ </Typography>
122
+ </Stack>
123
+ </form>
124
+ ) : (
125
+ <>
126
+ <Stack gap={'30px'}>
38
127
  <FormTextField
39
128
  control={control}
40
- name="username"
41
- label="User ID"
129
+ name="email"
130
+ label="Email"
42
131
  required
132
+ onChange={(e) => setForgotMail(e.target.value)}
43
133
  />
44
- </Box>
45
- <Box>
46
- <FormTextField
47
- control={control}
48
- name="password"
49
- label="Password"
50
- type={showPassword ? 'text' : 'password'}
51
- required
52
- InputProps={{
53
- endAdornment: (
54
- <InputAdornment position="end">
55
- <IconButton
56
- size="small"
57
- aria-label="toggle password visibility"
58
- onClick={() => setShowPassword((prev) => !prev)}
59
- edge="end"
60
- >
61
- {showPassword ? <VisibilityOff /> : <Visibility />}
62
- </IconButton>
63
- </InputAdornment>
64
- ),
134
+ <Button onClick={() => handleSendMail()}>Send Email</Button>
135
+
136
+ <Typography
137
+ variant="subtitle2"
138
+ onClick={() => {
139
+ setForgotPassword(true)
140
+ setError('')
141
+ setMailSent(false)
65
142
  }}
66
- />
67
- </Box>
68
- <ActionButton type="submit">Login</ActionButton>
69
- </Stack>
70
- </form>
143
+ align="right"
144
+ >
145
+ <StyledLink to="/">Login here</StyledLink>
146
+ </Typography>
147
+
148
+ {mailSent && (
149
+ <Alert severity="success">
150
+ Reset password link has been sent to your email.
151
+ </Alert>
152
+ )}
153
+ </Stack>
154
+ </>
155
+ )}
156
+
71
157
  {error && (
72
158
  <Alert severity="error" sx={{ marginTop: '20px' }}>
73
159
  {error}
@@ -77,4 +163,9 @@ export function LoginForm({ loginUrl }: { loginUrl?: string }) {
77
163
  )
78
164
  }
79
165
 
166
+ export const StyledLink = styled(Link)({
167
+ textDecoration: 'none',
168
+ color: 'black',
169
+ })
170
+
80
171
  export default LoginForm
@@ -0,0 +1,107 @@
1
+ import { VisibilityOff, Visibility } from '@mui/icons-material'
2
+ import { Stack, InputAdornment, IconButton, Button, Alert } from '@mui/material'
3
+ import React, { useState } from 'react'
4
+ import { FormTextField } from './HookForm'
5
+ import axios from '../config/axios'
6
+ import { useForm } from 'react-hook-form'
7
+ import { useNavigate } from 'react-router-dom'
8
+ import { toast } from 'react-toastify'
9
+
10
+ function ResetPassword() {
11
+ const searchParams = new URLSearchParams(document.location.search)
12
+ const { handleSubmit, control } = useForm()
13
+ const navigate = useNavigate()
14
+ const [error, setError] = useState('')
15
+ const [showPassword, setShowPassword] = useState(false)
16
+ const [showConfirmPassword, setShowConfirmPassword] = useState(false)
17
+
18
+ async function handleResetPassword(values) {
19
+ const token = searchParams.get('token')
20
+ values.token = token
21
+
22
+ if (values.newPassword == values.confirmNewPassword) {
23
+ try {
24
+ await axios
25
+ .post(`https://api.campx.dev/auth-server/auth/reset-password`, values)
26
+ .then((res) => {
27
+ navigate('/login')
28
+ toast.success('Password Changed Successfully')
29
+ })
30
+ } catch (err) {
31
+ if (
32
+ values.newPassword.length == 0 &&
33
+ values.confirmNewPassword.length == 0
34
+ ) {
35
+ setError('Please enter valid password')
36
+ } else if (token == null) {
37
+ setError('Invalid token')
38
+ } else {
39
+ setError(err.response.data.message ?? 'Server Error')
40
+ }
41
+ }
42
+ } else {
43
+ setError("New Password and Confirm New password doesn't match")
44
+ }
45
+ }
46
+
47
+ return (
48
+ <>
49
+ <form onSubmit={handleSubmit(handleResetPassword)}>
50
+ <Stack gap={'30px'}>
51
+ <FormTextField
52
+ control={control}
53
+ name="newPassword"
54
+ label="New Password"
55
+ type={showPassword ? 'text' : 'password'}
56
+ required
57
+ InputProps={{
58
+ endAdornment: (
59
+ <InputAdornment position="end">
60
+ <IconButton
61
+ size="small"
62
+ aria-label="toggle password visibility"
63
+ onClick={() => setShowPassword((prev) => !prev)}
64
+ edge="end"
65
+ >
66
+ {showPassword ? <VisibilityOff /> : <Visibility />}
67
+ </IconButton>
68
+ </InputAdornment>
69
+ ),
70
+ }}
71
+ />
72
+
73
+ <FormTextField
74
+ control={control}
75
+ name="confirmNewPassword"
76
+ label="Confirm Password"
77
+ type={showConfirmPassword ? 'text' : 'password'}
78
+ required
79
+ InputProps={{
80
+ endAdornment: (
81
+ <InputAdornment position="end">
82
+ <IconButton
83
+ size="small"
84
+ aria-label="toggle password visibility"
85
+ onClick={() => setShowConfirmPassword((prev) => !prev)}
86
+ edge="end"
87
+ >
88
+ {showPassword ? <VisibilityOff /> : <Visibility />}
89
+ </IconButton>
90
+ </InputAdornment>
91
+ ),
92
+ }}
93
+ />
94
+
95
+ <Button type="submit">Reset Password</Button>
96
+ </Stack>
97
+ </form>
98
+ {error && (
99
+ <Alert severity="error" sx={{ marginTop: '20px' }}>
100
+ {error}
101
+ </Alert>
102
+ )}
103
+ </>
104
+ )
105
+ }
106
+
107
+ export default ResetPassword
@@ -14,6 +14,7 @@ import { Table as StyledTable } from './Table'
14
14
  import ErrorBoundary from './ErrorBoundary'
15
15
  import FullScreenLoader from './FullScreenLoader'
16
16
  import LoginForm from './LoginForm'
17
+ import ResetPassword from './ResetPassword'
17
18
  import { SideMenuHeader } from './Layout/SideMenuHeader'
18
19
  import SideNav from './Layout/SideNav'
19
20
  import { ListItemButton } from './ListItemButton'
@@ -74,6 +75,7 @@ export {
74
75
  ErrorBoundary,
75
76
  FullScreenLoader,
76
77
  LoginForm,
78
+ ResetPassword,
77
79
  SideMenuHeader,
78
80
  ListItemButton,
79
81
  LayoutWrapper,