From aedeb62849ee9542d01f056ce37268638b4fb48c Mon Sep 17 00:00:00 2001 From: Mohammad Jalali Date: Wed, 18 Dec 2024 11:34:21 +0330 Subject: [PATCH] work on car code --- .../Forms/CreatePatrol/PatrolDetail.jsx | 32 +++++++ .../Forms/CreatePatrol/PatrolForms.jsx | 5 +- .../Forms/CreatePatrol/PhoneValidation.jsx | 49 ++++++++--- src/core/components/CarCode.jsx | 86 +++++++++++++++++++ src/core/utils/formatCounter.js | 5 ++ src/core/utils/routes.js | 3 + src/lib/hooks/useRequest.js | 9 +- 7 files changed, 168 insertions(+), 21 deletions(-) create mode 100644 src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx create mode 100644 src/core/components/CarCode.jsx create mode 100644 src/core/utils/formatCounter.js diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx new file mode 100644 index 0000000..38631e5 --- /dev/null +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolDetail.jsx @@ -0,0 +1,32 @@ +"use client"; + +import {Box, Slide} from "@mui/material"; +import {useState} from "react"; +import CarCode from "@/core/components/CarCode"; + +const PatrolDetail = ({tabState, setTabState}) => { + const [patrolFounded, setPatrolFounded] = useState(false); + const [carCode, setCarCode] = useState(null); + + return ( + + + + + + + + + + ); +}; + +export default PatrolDetail; \ No newline at end of file diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx index 4146808..4d51f65 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PatrolForms.jsx @@ -10,6 +10,7 @@ import HandymanIcon from '@mui/icons-material/Handyman'; import VerifiedIcon from '@mui/icons-material/Verified'; import PatrolTimeLine from "./PatrolTimeLine"; import PhoneValidation from "./PhoneValidation"; +import PatrolDetail from "./PatrolDetail"; function TabPanel(props) { const {children, value, index} = props; @@ -53,10 +54,10 @@ const PatrolForms = () => { - + - <>moshakhasat gasht + <>moshakhasat rahdar diff --git a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx index 0310d02..a60ba22 100644 --- a/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx +++ b/src/components/dashboard/roadPatrols/operator/Forms/CreatePatrol/PhoneValidation.jsx @@ -5,15 +5,18 @@ import React, {useEffect, useState} from "react"; import ForwardToInboxIcon from '@mui/icons-material/ForwardToInbox'; import QrCodeIcon from '@mui/icons-material/QrCode'; import useRequest from "@/lib/hooks/useRequest"; -import {GET_OTP_TOKEN} from "@/core/utils/routes"; +import {GET_OTP_TOKEN, VERIFY_OTP} from "@/core/utils/routes"; +import {formatCounter} from "@/core/utils/formatCounter"; -const PhoneValidation = () => { +const PhoneValidation = ({tabState, setTabState}) => { const requestServer = useRequest({auth: true}); const [phoneNumber, setPhoneNumber] = useState(""); + const [verificationCode, setVerificationCode] = useState(""); const [validPhone, setValidPhone] = useState(false); const [delayPerRequest, setDelayPerRequest] = useState(false); const [counter, setCounter] = useState(120); const [otpSended, setOtpSended] = useState(false); + const [readyToVerify, setReadyToVerify] = useState(false); const handleNumericInput = (e) => { e.target.value = e.target.value.replace(/[^0-9]/g, ''); @@ -21,18 +24,22 @@ const PhoneValidation = () => { useEffect(() => { if (phoneNumber.length === 11) { - setValidPhone(true) + setValidPhone(true); } else { - setValidPhone(false) + setValidPhone(false); } - }, [phoneNumber]); + if (verificationCode.length === 6 && phoneNumber.length === 11) { + setReadyToVerify(true); + } else { + setReadyToVerify(false); + } + }, [phoneNumber, verificationCode]); useEffect(() => { if (counter === 0) { setDelayPerRequest(false); return; } - if (delayPerRequest && counter > 0) { const timer = setInterval(() => { setCounter(prevCounter => prevCounter - 1); @@ -55,12 +62,23 @@ const PhoneValidation = () => { setDelayPerRequest(true); }; - // Format counter as MM:SS - const formatCounter = (counter) => { - const minutes = Math.floor(counter / 60).toString().padStart(2, '0'); - const seconds = (counter % 60).toString().padStart(2, '0'); - return `${minutes}:${seconds}`; - }; + const phoneRegister = () => { + const formData = new FormData(); + formData.append("phone_number", phoneNumber); + formData.append("verification_code", verificationCode); + + for (var pair of formData.entries()) { + console.log(pair[0] + ', ' + pair[1]); + } + setTabState(tabState + 1) + requestServer(VERIFY_OTP, "post", { + data: formData, + }) + .then(() => { + }) + .catch(() => { + }); + } return ( { autoComplete="off" size="small" fullWidth - type="text" + value={verificationCode} + onChange={(e) => setVerificationCode(e.target.value)} onInput={handleNumericInput} + type="text" inputProps={{ maxLength: 6, inputMode: "numeric", @@ -118,7 +138,8 @@ const PhoneValidation = () => { }} /> - diff --git a/src/core/components/CarCode.jsx b/src/core/components/CarCode.jsx new file mode 100644 index 0000000..503a826 --- /dev/null +++ b/src/core/components/CarCode.jsx @@ -0,0 +1,86 @@ +"use client"; + +import {Autocomplete, CircularProgress, TextField} from "@mui/material"; +import {useEffect, useState} from "react"; +import useRequest from "@/lib/hooks/useRequest"; +import {debounce} from "@mui/material/utils"; + +const CarCode = ({carCode, setCarCode}) => { + const [inputValue, setInputValue] = useState(''); + const [options, setOptions] = useState([]); + const [loading, setLoading] = useState(false); + const requestServer = useRequest(); + + const fetchCarCodes = (inputValue, controller) => { + const debouncer = debounce((query) => { + if (query.length < 2) { + setOptions([]); + return; + } + setLoading(true); + requestServer(`car-code/api?${query}`, "get", { + requestOptions: {signal: controller.signal} + }) + .then((response) => { + setOptions(response || []); + }) + .catch(() => { + setOptions([]); + }) + .finally(() => { + setLoading(false); + }); + }, 500) + debouncer(inputValue) + } + + useEffect(() => { + const controller = new AbortController(); + fetchCarCodes(inputValue, controller); + return () => controller.abort(); + }, [inputValue]); + + return ( + { + setCarCode(newValue); + }} + inputValue={inputValue} + onInputChange={(event, newInputValue) => { + setInputValue(newInputValue); + }} + options={options} + getOptionLabel={(option) => + typeof option === 'string' ? option : option.name || option.code + } + loading={loading} + loadingText="درحال جستجوی کد خودرو" + noOptionsText={ + inputValue.length < 2 + ? "حداقل دو رقم از کد خودرو را وارد کنید" + : "کد خودرویی یافت نشد" + } + sx={{width: 300}} + renderInput={(params) => ( + + {loading ? : null} + {params.InputProps.endAdornment} + + ), + }} + /> + )} + /> + ); +}; + +export default CarCode; \ No newline at end of file diff --git a/src/core/utils/formatCounter.js b/src/core/utils/formatCounter.js new file mode 100644 index 0000000..72b021a --- /dev/null +++ b/src/core/utils/formatCounter.js @@ -0,0 +1,5 @@ +export const formatCounter = (counter) => { + const minutes = Math.floor(counter / 60).toString().padStart(2, '0'); + const seconds = (counter % 60).toString().padStart(2, '0'); + return `${minutes}:${seconds}`; +}; \ No newline at end of file diff --git a/src/core/utils/routes.js b/src/core/utils/routes.js index c9ee515..1cd95f7 100644 --- a/src/core/utils/routes.js +++ b/src/core/utils/routes.js @@ -31,4 +31,7 @@ export const GET_OPERATOR_LIST = "/v3/api/fake-operator-list"; export const EXPORT_OPERATOR_LIST = "https://rms.rmto.ir/v2/road_patrols/operator/cartable/report"; export const GET_SUPERVISOR_LIST = "/v3/api/fake-supervisor-list"; export const EXPORT_SUPERVISOR_LIST = "https://rms.rmto.ir/v2/road_patrols/supervisor/cartable/report"; + +////**** mohammad check here ****//// export const GET_OTP_TOKEN = "https://rms.rmto.ir/v2/get_otp_token"; +export const VERIFY_OTP = "https://rms.rmto.ir/v2/verify_otp"; diff --git a/src/lib/hooks/useRequest.js b/src/lib/hooks/useRequest.js index eb30a18..1efa7de 100644 --- a/src/lib/hooks/useRequest.js +++ b/src/lib/hooks/useRequest.js @@ -1,7 +1,7 @@ -import { errorResponse } from "@/core/utils/errorResponse"; -import { successRequest } from "@/core/utils/successRequest"; +import {errorResponse} from "@/core/utils/errorResponse"; +import {successRequest} from "@/core/utils/successRequest"; import axios from "axios"; -import { useAuth } from "../contexts/auth"; +import {useAuth} from "../contexts/auth"; const defaultOptions = { data: {}, @@ -16,13 +16,12 @@ const defaultOptions = { }; const useRequest = (initOptions) => { - const { logout } = useAuth(); + const {logout} = useAuth(); const _options = Object.assign({}, defaultOptions, initOptions); return async (url = "", method = "get", options) => { const mergedOptions = Object.assign({}, _options, options); - try { const response = await axios({ url,