update login dan password

This commit is contained in:
2024-06-27 14:43:01 +07:00
parent 32a45814b8
commit 4ceaf41a7d
5 changed files with 189 additions and 74 deletions

View File

@@ -8,6 +8,7 @@ use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\View;
@@ -16,7 +17,8 @@ class AuthController extends Controller
public function login(Request $request)
{
$request->validate([
'phoneOrEmail' => 'required'
'phoneOrEmail' => 'required',
'password' => 'required'
]);
$user = User::query()
@@ -32,45 +34,61 @@ class AuthController extends Controller
return Helper::responseJson(statusCode: Response::HTTP_NOT_FOUND, message: $message);
}
$token = rand(1000, 9999); // Menghasilkan angka acak antara 100000 dan 999999
if($request->phoneOrEmail == 'manager+one@gmail.com' || $request->phoneOrEmail == 'manager+two@gmail.com')
{
$token = 4444;
}
if (filter_var($request->phoneOrEmail, FILTER_VALIDATE_EMAIL)) {
User::query()->find($user->id)->update([
'email' => $request->phoneOrEmail,
'otp' => $token,
'otp_created_at' => now()
]);
} else {
User::query()->find($user->id)->update([
'phone' => $request->phoneOrEmail,
'otp' => $token,
'otp_created_at' => now()
]);
// $token = rand(1000, 9999); // Menghasilkan angka acak antara 100000 dan 999999
// if($request->phoneOrEmail == 'manager+one@gmail.com' || $request->phoneOrEmail == 'manager+two@gmail.com')
// {
// $token = 4444;
// }
// if (filter_var($request->phoneOrEmail, FILTER_VALIDATE_EMAIL)) {
// User::query()->find($user->id)->update([
// 'email' => $request->phoneOrEmail,
// 'otp' => $token,
// 'otp_created_at' => now()
// ]);
// } else {
// User::query()->find($user->id)->update([
// 'phone' => $request->phoneOrEmail,
// 'otp' => $token,
// 'otp_created_at' => now()
// ]);
// }
// // TODO Send the OTP
// if (filter_var($request->phoneOrEmail, FILTER_VALIDATE_EMAIL)) {
// // Send Email
// //send to alarm
// if($request->phoneOrEmail != 'manager+one@gmail.com' && $request->phoneOrEmail != 'manager+two@gmail.com')
// {
// $nameTo = 'User';
// $dataEmail = [
// 'email' => $request->phoneOrEmail,
// 'name' => $nameTo,
// 'subject' => 'OTP Login Client Portal Tanggal '. date('Y-m-d H:i:s'),
// 'body' => View::make('email/forgot_password', ['token' => $token])->render(),
// ];
// Helper::sendEmail($dataEmail);
// }
// } else {
// // Send Whatsapp
// }
// return Helper::responseJson(message: 'OTP Terkirim');
if (!Hash::check($request->password, $user->password)) {
return response(['message' => 'Password Salah'], 403);
}
// TODO Send the OTP
if (filter_var($request->phoneOrEmail, FILTER_VALIDATE_EMAIL)) {
// Send Email
//send to alarm
if($request->phoneOrEmail != 'manager+one@gmail.com' && $request->phoneOrEmail != 'manager+two@gmail.com')
{
$nameTo = 'User';
$dataEmail = [
'email' => $request->phoneOrEmail,
'name' => $nameTo,
'subject' => 'OTP Login Client Portal Tanggal '. date('Y-m-d H:i:s'),
'body' => View::make('email/forgot_password', ['token' => $token])->render(),
];
Helper::sendEmail($dataEmail);
}
} else {
// Send Whatsapp
}
return Helper::responseJson(
data: [
'token' => $user->createToken('app')->plainTextToken,
'user' => $user,
],
message: 'Selamat Datang'
);
return Helper::responseJson(message: 'OTP Terkirim');
}
public function validateOtp(Request $request)

View File

@@ -26,7 +26,7 @@ export type JWTContextType = {
isInitialized: boolean;
user: AuthUser;
method: 'jwt';
login: (phoneOrEmail: string) => Promise<void>;
login: (phoneOrEmail: string, password: string, rememberMe: boolean) => Promise<void>;
validateOtp: (phoneOrEmail: string, otp: string) => Promise<void>
logout: () => void;
};

View File

@@ -1,11 +1,12 @@
import { createContext, ReactNode, useEffect, useReducer } from 'react';
// utils
import axios from '../utils/axios';
import { setSession, getSession } from '../utils/token';
import { setSession, getSession, setUser, getUser, getCookie } from '../utils/token';
// @types
import { ActionMap, AuthState, AuthUser, JWTContextType } from '../@types/auth';
// ----------------------------------------------------------------------
import { Navigate, useLocation } from 'react-router-dom';
enum Types {
Initial = 'INITIALIZE',
@@ -19,7 +20,9 @@ type JWTAuthPayload = {
isAuthenticated: boolean;
user: AuthUser;
};
[Types.Login]: undefined;
[Types.Login]: {
user: AuthUser;
};
[Types.ValidateOtp]: {
user: AuthUser;
};
@@ -45,8 +48,8 @@ const JWTReducer = (state: AuthState, action: JWTActions) => {
case 'LOGIN':
return {
...state,
isAuthenticated: false,
user: null,
isAuthenticated: true,
user: action.payload.user,
};
case 'VALIDATE-OTP':
return {
@@ -75,7 +78,46 @@ type AuthProviderProps = {
function AuthProvider({ children }: AuthProviderProps) {
const [state, dispatch] = useReducer(JWTReducer, initialState);
let location = useLocation();
const accessToken = getSession();
// useEffect(() => {
// (async () => {
// try {
// // const accessToken = getSession();
// if (accessToken) {
// setSession(accessToken);
// const response = await axios.get('/user');
// const user = response.data;
// dispatch({
// type: Types.Initial,
// payload: {
// isAuthenticated: true,
// user,
// },
// });
// } else {
// dispatch({
// type: Types.Initial,
// payload: {
// isAuthenticated: false,
// user: null,
// },
// });
// }
// } catch (err) {
// dispatch({
// type: Types.Initial,
// payload: {
// isAuthenticated: false,
// user: null,
// },
// });
// }
// })();
// }, [accessToken]);
useEffect(() => {
(async () => {
@@ -116,12 +158,28 @@ function AuthProvider({ children }: AuthProviderProps) {
})();
}, [accessToken]);
const login = async (phoneOrEmail: string) =>
const headers = {
headers: {
'Accept': 'application/json',
'Content-Type' : 'application/json',
'Accept-Language': localStorage.getItem('currentLocale') ?? 'id-ID',
},
};
const login = async (phoneOrEmail: string, password: string, remember:boolean) =>
axios
.post('/login', { phoneOrEmail })
.then(() => {
.post('/login', { phoneOrEmail, password }, headers)
.then((response) => {
const { user, token } = response.data.data;
setSession(token);
setUser(user);
dispatch({
type: Types.Login,
payload: {
user,
}
});
})
.catch((error) => {

View File

@@ -97,7 +97,7 @@ export default function Login() {
</video>
</Grid>
<Grid item xs={6} sx={{ padding: 3 }}>
{loginOrVerifyCode && emailOrPhone ? (
{/* {loginOrVerifyCode && emailOrPhone ? (
<>
<Stack direction="column" sx={{ mb: 5 }}>
<Stack direction="row" alignItems="center">
@@ -138,7 +138,7 @@ export default function Login() {
>Kirim Ulang Kode OTP</Link>
</Stack>
</>
) : (
) : ( */}
<>
<Stack direction="row" alignItems="center" sx={{ mb: 5 }}>
<Logo sx={{ width: 90, height: 90 }} />
@@ -152,19 +152,16 @@ export default function Login() {
</Box>
</Stack>
{emailOrPhoneForm ? (
{/* {emailOrPhoneForm ? (
<LoginPhoneForm
setEmailOrPhone={setEmailOrPhone}
setLoginOrVerifyCode={setLoginOrVerifyCode}
/>
) : (
<LoginEmailForm
setEmailOrPhone={setEmailOrPhone}
setLoginOrVerifyCode={setLoginOrVerifyCode}
/>
)}
) : ( */}
<LoginEmailForm/>
{/* )} */}
</>
)}
{/* )} */}
{/* <Divider sx={{ marginTop: 5 }}>Atau</Divider>

View File

@@ -1,42 +1,52 @@
/* ----------------------------------- yup ---------------------------------- */
import * as Yup from 'yup';
import React, { useContext, useRef, useState, useEffect } from 'react';
/* ---------------------------------- form ---------------------------------- */
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
/* ---------------------------------- @mui ---------------------------------- */
import { Stack, Alert } from '@mui/material';
import { LoadingButton } from '@mui/lab';
import { Link, Stack, Alert, IconButton, InputAdornment } from '@mui/material';
/* ---------------------------------- hooks --------------------------------- */
import useAuth from '../../../hooks/useAuth';
import useIsMountedRef from '../../../hooks/useIsMountedRef';
/* ------------------------------- components ------------------------------- */
import { FormProvider, RHFTextField } from '../../../components/hook-form';
import Iconify from '../../../components/Iconify';
import { FormProvider, RHFTextField, RHFCheckbox } from '../../../components/hook-form';
import { enqueueSnackbar } from 'notistack';
import { useNavigate } from 'react-router-dom';
/* ---------------------------------- types --------------------------------- */
type LoginFormProps = {
setEmailOrPhone: Function;
setLoginOrVerifyCode: Function;
};
// type LoginFormProps = {
// setEmailOrPhone: Function;
// setLoginOrVerifyCode: Function;
// };
type FormValuesProps = {
email: string;
password: string;
remember: boolean;
afterSubmit?: string;
};
/* -------------------------------------------------------------------------- */
export default function LoginForm({ setEmailOrPhone, setLoginOrVerifyCode }: LoginFormProps) {
export default function LoginForm() {
const { login } = useAuth();
const navigate = useNavigate();
const isMountedRef = useIsMountedRef();
const [showPassword, setShowPassword] = useState(false);
const LoginSchema = Yup.object().shape({
email: Yup.string().email('Email must be a valid email address').required('Email is required'),
email: Yup.string().email('Format email tidak valid').required('Email harus diisi'),
password: Yup.string().required('Password harus diisi'),
});
const defaultValues = {
const defaultValues = {
email: '',
password: '',
remember: true,
};
const methods = useForm<FormValuesProps>({
@@ -51,17 +61,34 @@ export default function LoginForm({ setEmailOrPhone, setLoginOrVerifyCode }: Log
formState: { errors, isSubmitting },
} = methods;
// const onSubmit = async (data: FormValuesProps) => {
// try {
// const loginResult = await login(data.email, data.password, data.remember);
// // setEmailOrPhone(data.email);
// // setLoginOrVerifyCode(true);
// // reset();
// console.log('test');
// navigate('/dashboard');
// // enqueueSnackbar('Kode OTP telah dikirim, silahkan cek email dan spam folder', {
// // variant: 'success',
// // autoHideDuration: 5000,
// // });
// } catch (error: any) {
// reset();
// console.log(error, 'test');
// if (isMountedRef.current) {
// setError('afterSubmit', { ...error, message: error.data.message });
// }
// }
// };
const onSubmit = async (data: FormValuesProps) => {
try {
await login(data.email);
setEmailOrPhone(data.email);
setLoginOrVerifyCode(true);
reset();
enqueueSnackbar('Kode OTP telah dikirim, silahkan cek email dan spam folder', {
variant: 'success',
autoHideDuration: 5000,
});
} catch (error: any) {
const loginResult = await login(data.email, data.password, data.remember);
navigate('/dashboard');
} catch (error) {
reset();
if (isMountedRef.current) {
@@ -73,10 +100,25 @@ export default function LoginForm({ setEmailOrPhone, setLoginOrVerifyCode }: Log
return (
<FormProvider methods={methods} onSubmit={handleSubmit(onSubmit)}>
<Stack spacing={3}>
<Alert severity="info">Masukkan akun yang telah terdaftar</Alert>
<Alert severity="info">Masukan Email atau Username dan Password</Alert>
{!!errors.afterSubmit && <Alert severity="error">{errors.afterSubmit.message}</Alert>}
<RHFTextField name="email" label="Email address" />
<RHFTextField
name="password"
label="Password"
type={showPassword ? 'text' : 'password'}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton onClick={() => setShowPassword(!showPassword)} edge="end">
<Iconify icon={showPassword ? 'eva:eye-fill' : 'eva:eye-off-fill'} />
</IconButton>
</InputAdornment>
),
}}
required
/>
</Stack>
<LoadingButton