New Product Component Made And Cmpleted Categories Sorted With Mr.Khajis Component Redux Changes Cart Remove Or Decrease OTP is Ready To use But Not Mergedmain
parent
e2508e1f6f
commit
b6501aad7f
14 changed files with 921 additions and 217 deletions
@ -0,0 +1,292 @@ |
||||
import React, { useState, useRef, useEffect } from "react"; |
||||
import { useNavigate } from "react-router-dom"; |
||||
import Input from "../../../components/Input"; |
||||
import Button from "../../../components/Button"; |
||||
import Timer from "../../../components/Timer"; |
||||
import onInput from "../../../utils/onInput"; |
||||
import { Link } from "react-router-dom"; |
||||
|
||||
import { connect } from "react-redux"; |
||||
import { user, publicApi } from "../../../redux/actions"; |
||||
import _ from "lodash"; |
||||
//assets
|
||||
import logoIcon from "./assets/logo.svg"; |
||||
|
||||
function SignUp({ |
||||
sendOtp, |
||||
sendPhoneNumber, |
||||
loginFlag, |
||||
theme, |
||||
headerOptions, |
||||
setHeaderOptions, |
||||
}) { |
||||
const [level, setLevel] = useState("phonenumber"); |
||||
const [signUpFields, setSignUpFiels] = useState({});
|
||||
const [error, setError] = useState(""); |
||||
const [resend, setResend] = useState(false); |
||||
const navigate = useNavigate(); |
||||
|
||||
const otp1 = useRef(); |
||||
const otp2 = useRef(); |
||||
const otp3 = useRef(); |
||||
const otp4 = useRef(); |
||||
|
||||
const onChange = (name, value) => { |
||||
setSignUpFiels({ ...signUpFields, [name]: value }); |
||||
switch (name) { |
||||
case "otp1": |
||||
if (value) { |
||||
otp2.current.focus(); |
||||
} |
||||
break; |
||||
case "otp2": |
||||
if (value) { |
||||
otp3.current.focus(); |
||||
} else { |
||||
otp1.current.focus(); |
||||
} |
||||
break; |
||||
case "otp3": |
||||
if (value) { |
||||
otp4.current.focus(); |
||||
} else { |
||||
otp2.current.focus(); |
||||
} |
||||
break; |
||||
case "otp4": |
||||
if (value) { |
||||
checkOtp(); |
||||
} else { |
||||
otp3.current.focus(); |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
}; |
||||
|
||||
const checkPhoneNumber = (e) => { |
||||
if ( |
||||
signUpFields?.cellphone?.slice(0, 2) === "09" && |
||||
signUpFields?.cellphone.length === 11 |
||||
) { |
||||
setLevel("otp"); |
||||
setResend(false); |
||||
sendPhoneNumber({ cellphone: signUpFields?.cellphone }); |
||||
setError(undefined); |
||||
} else { |
||||
setError("شماره موبایل خود را چک کنید."); |
||||
} |
||||
}; |
||||
|
||||
const checkOtp = () => { |
||||
if ( |
||||
signUpFields?.otp1 && |
||||
signUpFields?.otp2 && |
||||
signUpFields?.otp3 && |
||||
signUpFields?.otp4 |
||||
) { |
||||
sendOtp({ |
||||
cellphone: signUpFields?.cellphone, |
||||
otp: |
||||
signUpFields?.otp1 + |
||||
signUpFields?.otp2 + |
||||
signUpFields?.otp3 + |
||||
signUpFields?.otp4, |
||||
userToken: "2", |
||||
applicationToken: "22", |
||||
}); |
||||
setError(undefined); |
||||
} else { |
||||
setError("کد وارد شده را چک کنید."); |
||||
} |
||||
}; |
||||
|
||||
const numberInput = useRef(); |
||||
|
||||
useEffect(() => { |
||||
// numberInput.current.focus();
|
||||
setHeaderOptions(headerOptions); |
||||
}, []); |
||||
|
||||
useEffect(() => { |
||||
if (signUpFields?.otp?.length === 4) { |
||||
sendOtp({ |
||||
cellphone: signUpFields?.cellphone, |
||||
otp: signUpFields?.otp, |
||||
userToken: "2", |
||||
applicationToken: "22", |
||||
}); |
||||
} |
||||
}, [signUpFields]); |
||||
|
||||
useEffect(() => { |
||||
if (level === "phonenumber") { |
||||
// numberInput.current.focus();
|
||||
} else { |
||||
// otpInput.current.focus();
|
||||
} |
||||
}, [level]); |
||||
|
||||
useEffect(() => { |
||||
if (loginFlag) { |
||||
navigate("/"); |
||||
} |
||||
}, [loginFlag]); |
||||
const light = theme === "light"; |
||||
return ( |
||||
<div |
||||
className="w-screen overflow-x-hidden flex flex-row transform -translate-y-10 relative" |
||||
style={{ height: "calc(100vh - 160px)" }} |
||||
> |
||||
<div |
||||
className={`flex flex-col items-center justify-center h-full w-full p-4 transition transform duration-300 absolute top-0 left-0 ${ |
||||
level === "phonenumber" ? "translate-x-0" : "-translate-x-full" |
||||
}`}
|
||||
> |
||||
<img src={logoIcon} alt="" className="" /> |
||||
<strong className="w-full leading-6 dark:text-white mt-10"> |
||||
سلام <br /> خوش برگشتی! |
||||
</strong> |
||||
<div className="w-full flex flex-col mt-10"> |
||||
<Input |
||||
label={"شماره موبایل"} |
||||
name="cellphone" |
||||
regex={onInput.numberOnly} |
||||
onChange={(name, value) => onChange(name, value)} |
||||
value={signUpFields?.cellphone} |
||||
align="text-center" |
||||
maxLength="11" |
||||
direction="ltr" |
||||
/> |
||||
<span className="text-red-500 text-xs">{error}</span> |
||||
<br /> |
||||
<Button |
||||
title="ادامه" |
||||
backgroundColor="bg-blueC0" |
||||
border={{ color: "#196EC055", width: "1px" }} |
||||
width="100%" |
||||
color="text-white" |
||||
onClick={(e) => checkPhoneNumber(e)} |
||||
/> |
||||
</div> |
||||
</div> |
||||
<div |
||||
className={`flex flex-col items-center justify-center w-full h-full p-4 transition transform duration-300 absolute top-0 left-0 ${ |
||||
level === "otp" ? "translate-x-0" : "translate-x-full" |
||||
}`}
|
||||
> |
||||
<img src={logoIcon} alt="" className="" /> |
||||
{!resend && ( |
||||
<div className="w-full leading-6 dark:text-white mt-10 text-xs text-gray1"> |
||||
یک کد چهار رقمی تا {" "} |
||||
<Timer seconds={120} refresh={setResend} /> دیگر برای شماره |
||||
{" "} |
||||
<span className="text-greenBA text-sm"> |
||||
{signUpFields?.cellphone} |
||||
</span>{" "} |
||||
ارسال خواهد شد. |
||||
</div> |
||||
)} |
||||
|
||||
<div className="w-full flex flex-col mt-5"> |
||||
<div className="w-full flex flex-row-reverse justify-center"> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp1" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp1} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp2" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp2} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp3" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp3} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp4" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.englishAndNumberWithoutSpace(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp4} |
||||
/> |
||||
</div> |
||||
<br /> |
||||
<Button |
||||
title="ادامه فرایند خرید" |
||||
backgroundColor="bg-blueC0" |
||||
border={{ color: "#196EC055", width: "1px" }} |
||||
width="100%" |
||||
color="text-white" |
||||
onClick={(e) => |
||||
level === "phonenumber" ? checkPhoneNumber(e) : checkOtp(e) |
||||
} |
||||
/> |
||||
<div className="mt-10 flex flex-row text-center w-full justify-center"> |
||||
<div className="text-xs text-gray1"> |
||||
شماره خود را اشتباه وارد کردید؟{" "} |
||||
<button |
||||
className="bg-transparent border-none text-greenBA font-medium" |
||||
onClick={() => setLevel("phonenumber")} |
||||
> |
||||
اصلاح شماره تلفن |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
const mapStateToProps = (state) => ({ |
||||
loginFlag : state.user.status, |
||||
}); |
||||
|
||||
const mapDispatchToProps = { |
||||
sendOtp: user.otp_login, |
||||
sendPhoneNumber: user.otp, |
||||
setHeaderOptions: publicApi.setHeaderOptions, |
||||
}; |
||||
|
||||
export default connect( |
||||
mapStateToProps, |
||||
mapDispatchToProps |
||||
)(SignUp); |
@ -0,0 +1,292 @@ |
||||
import React, { useState, useRef, useEffect } from "react"; |
||||
import { useNavigate } from "react-router-dom"; |
||||
import Input from "../../../components/Input"; |
||||
import Button from "../../../components/Button"; |
||||
import Timer from "../../../components/Timer"; |
||||
import onInput from "../../../utils/onInput"; |
||||
import { Link } from "react-router-dom"; |
||||
|
||||
import { connect } from "react-redux"; |
||||
import { user, publicApi } from "../../../redux/actions"; |
||||
import _ from "lodash"; |
||||
//assets
|
||||
import logoIcon from "./assets/logo.svg"; |
||||
|
||||
function SignUp({ |
||||
sendOtp, |
||||
sendPhoneNumber, |
||||
loginFlag, |
||||
theme, |
||||
headerOptions, |
||||
setHeaderOptions, |
||||
}) { |
||||
const [level, setLevel] = useState("phonenumber"); |
||||
const [signUpFields, setSignUpFiels] = useState({});
|
||||
const [error, setError] = useState(""); |
||||
const [resend, setResend] = useState(false); |
||||
const navigate = useNavigate(); |
||||
|
||||
const otp1 = useRef(); |
||||
const otp2 = useRef(); |
||||
const otp3 = useRef(); |
||||
const otp4 = useRef(); |
||||
|
||||
const onChange = (name, value) => { |
||||
setSignUpFiels({ ...signUpFields, [name]: value }); |
||||
switch (name) { |
||||
case "otp1": |
||||
if (value) { |
||||
otp2.current.focus(); |
||||
} |
||||
break; |
||||
case "otp2": |
||||
if (value) { |
||||
otp3.current.focus(); |
||||
} else { |
||||
otp1.current.focus(); |
||||
} |
||||
break; |
||||
case "otp3": |
||||
if (value) { |
||||
otp4.current.focus(); |
||||
} else { |
||||
otp2.current.focus(); |
||||
} |
||||
break; |
||||
case "otp4": |
||||
if (value) { |
||||
checkOtp(); |
||||
} else { |
||||
otp3.current.focus(); |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
}; |
||||
|
||||
const checkPhoneNumber = (e) => { |
||||
if ( |
||||
signUpFields?.cellphone?.slice(0, 2) === "09" && |
||||
signUpFields?.cellphone.length === 11 |
||||
) { |
||||
setLevel("otp"); |
||||
setResend(false); |
||||
sendPhoneNumber({ cellphone: signUpFields?.cellphone }); |
||||
setError(undefined); |
||||
} else { |
||||
setError("شماره موبایل خود را چک کنید."); |
||||
} |
||||
}; |
||||
|
||||
const checkOtp = () => { |
||||
if ( |
||||
signUpFields?.otp1 && |
||||
signUpFields?.otp2 && |
||||
signUpFields?.otp3 && |
||||
signUpFields?.otp4 |
||||
) { |
||||
sendOtp({ |
||||
cellphone: signUpFields?.cellphone, |
||||
otp: |
||||
signUpFields?.otp1 + |
||||
signUpFields?.otp2 + |
||||
signUpFields?.otp3 + |
||||
signUpFields?.otp4, |
||||
userToken: "2", |
||||
applicationToken: "22", |
||||
}); |
||||
setError(undefined); |
||||
} else { |
||||
setError("کد وارد شده را چک کنید."); |
||||
} |
||||
}; |
||||
|
||||
const numberInput = useRef(); |
||||
|
||||
useEffect(() => { |
||||
// numberInput.current.focus();
|
||||
setHeaderOptions(headerOptions); |
||||
}, []); |
||||
|
||||
useEffect(() => { |
||||
if (signUpFields?.otp?.length === 4) { |
||||
sendOtp({ |
||||
cellphone: signUpFields?.cellphone, |
||||
otp: signUpFields?.otp, |
||||
userToken: "2", |
||||
applicationToken: "22", |
||||
}); |
||||
} |
||||
}, [signUpFields]); |
||||
|
||||
useEffect(() => { |
||||
if (level === "phonenumber") { |
||||
// numberInput.current.focus();
|
||||
} else { |
||||
// otpInput.current.focus();
|
||||
} |
||||
}, [level]); |
||||
|
||||
useEffect(() => { |
||||
if (loginFlag) { |
||||
navigate("/"); |
||||
} |
||||
}, [loginFlag]); |
||||
const light = theme === "light"; |
||||
return ( |
||||
<div |
||||
className="w-screen overflow-x-hidden flex flex-row transform -translate-y-10 relative" |
||||
style={{ height: "calc(100vh - 160px)" }} |
||||
> |
||||
<div |
||||
className={`flex flex-col items-center justify-center h-full w-full p-4 transition transform duration-300 absolute top-0 left-0 ${ |
||||
level === "phonenumber" ? "translate-x-0" : "-translate-x-full" |
||||
}`}
|
||||
> |
||||
<img src={logoIcon} alt="" className="" /> |
||||
<strong className="w-full leading-6 dark:text-white mt-10"> |
||||
سلام <br /> خوش برگشتی! |
||||
</strong> |
||||
<div className="w-full flex flex-col mt-10"> |
||||
<Input |
||||
label={"شماره موبایل"} |
||||
name="cellphone" |
||||
regex={onInput.numberOnly} |
||||
onChange={(name, value) => onChange(name, value)} |
||||
value={signUpFields?.cellphone} |
||||
align="text-center" |
||||
maxLength="11" |
||||
direction="ltr" |
||||
/> |
||||
<span className="text-red-500 text-xs">{error}</span> |
||||
<br /> |
||||
<Button |
||||
title="ادامه" |
||||
backgroundColor="bg-blueC0" |
||||
border={{ color: "#196EC055", width: "1px" }} |
||||
width="100%" |
||||
color="text-white" |
||||
onClick={(e) => checkPhoneNumber(e)} |
||||
/> |
||||
</div> |
||||
</div> |
||||
<div |
||||
className={`flex flex-col items-center justify-center w-full h-full p-4 transition transform duration-300 absolute top-0 left-0 ${ |
||||
level === "otp" ? "translate-x-0" : "translate-x-full" |
||||
}`}
|
||||
> |
||||
<img src={logoIcon} alt="" className="" /> |
||||
{!resend && ( |
||||
<div className="w-full leading-6 dark:text-white mt-10 text-xs text-gray1"> |
||||
یک کد چهار رقمی تا {" "} |
||||
<Timer seconds={120} refresh={setResend} /> دیگر برای شماره |
||||
{" "} |
||||
<span className="text-greenBA text-sm"> |
||||
{signUpFields?.cellphone} |
||||
</span>{" "} |
||||
ارسال خواهد شد. |
||||
</div> |
||||
)} |
||||
|
||||
<div className="w-full flex flex-col mt-5"> |
||||
<div className="w-full flex flex-row-reverse justify-center"> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp1" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp1} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp2" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp2} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp3" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.numberOnly(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp3} |
||||
/> |
||||
<input |
||||
inputMode="numeric" |
||||
style={{ direction: "ltr" }} |
||||
name="otp4" |
||||
className="bg-grayF9 rounded-md p-4 w-16 text-md text-center text-blueC0 mx-1" |
||||
onChange={(e) => |
||||
onChange( |
||||
e.target.name, |
||||
(e.target.value = onInput.englishAndNumberWithoutSpace(e.target.value)) |
||||
) |
||||
} |
||||
maxlength="1" |
||||
ref={otp4} |
||||
/> |
||||
</div> |
||||
<br /> |
||||
<Button |
||||
title="ادامه فرایند خرید" |
||||
backgroundColor="bg-blueC0" |
||||
border={{ color: "#196EC055", width: "1px" }} |
||||
width="100%" |
||||
color="text-white" |
||||
onClick={(e) => |
||||
level === "phonenumber" ? checkPhoneNumber(e) : checkOtp(e) |
||||
} |
||||
/> |
||||
<div className="mt-10 flex flex-row text-center w-full justify-center"> |
||||
<div className="text-xs text-gray1"> |
||||
شماره خود را اشتباه وارد کردید؟{" "} |
||||
<button |
||||
className="bg-transparent border-none text-greenBA font-medium" |
||||
onClick={() => setLevel("phonenumber")} |
||||
> |
||||
اصلاح شماره تلفن |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
const mapStateToProps = (state) => ({ |
||||
loginFlag : state.user.status, |
||||
}); |
||||
|
||||
const mapDispatchToProps = { |
||||
sendOtp: user.otp_login, |
||||
sendPhoneNumber: user.otp, |
||||
setHeaderOptions: publicApi.setHeaderOptions, |
||||
}; |
||||
|
||||
export default connect( |
||||
mapStateToProps, |
||||
mapDispatchToProps |
||||
)(SignUp); |
@ -0,0 +1,70 @@ |
||||
import React from "react"; |
||||
import Button from "../../../components/Button"; |
||||
|
||||
const servicePopUp = ({ |
||||
content, |
||||
closeOnClick, |
||||
addToCartFunction |
||||
}) => { |
||||
return ( |
||||
<div className="flex justify-center w-full items-center fixed text-right z-30 backdrop-blur" style={{ background: 'rgba(0,0,0,0.1)', height: 'calc(100vh - 6.5vh)', top: '8.5vh' }}> |
||||
<div className="bg-white flex flex-col w-1/2 rounded-2xl py-6 px-10" > |
||||
<div className="w-full"> |
||||
<div className="w-8 h-8 text-white text-sm rounded-full cursor-pointer flex justify-center items-center bg-red52" onClick={closeOnClick}> |
||||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 15.044 15.044"> |
||||
<g id="vuesax_linear_card-remove" data-name="vuesax/linear/card-remove" transform="translate(-252.46 -511.461)"> |
||||
<g id="card-remove" transform="translate(253.309 512.31)"> |
||||
<path id="Vector" d="M0,13.347,13.347,0" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2" /> |
||||
<path id="Vector-2" data-name="Vector" d="M13.347,13.347,0,0" fill="none" stroke="#fff" stroke-linecap="round" stroke-width="2" /> |
||||
</g> |
||||
</g> |
||||
</svg> |
||||
</div> |
||||
</div> |
||||
<div className="flex justify-between mb-20"> |
||||
<div className="w-1/2 my-4 p-2"> |
||||
<h1 className="text-red25 font-black text-md">کلاس آنلاین {content.title}</h1> |
||||
<p className="text-red26 text-sm my-2"> |
||||
{content.description} |
||||
</p> |
||||
<div className="w-full flex flex-col"> |
||||
<div className="flex mb-2"> |
||||
<div className="bg-gray-100 rounded w-40 px-4 py-2 ml-2 text-red52">نام کلاس</div> |
||||
<div className="bg-gray-100 rounded w-full px-4 py-2 ml-2 text-red26">{content.title}</div> |
||||
</div> |
||||
<div className="flex mb-2"> |
||||
<div className="bg-gray-100 rounded w-40 px-4 py-2 ml-2 text-red52"> استاد </div> |
||||
<div className="bg-gray-100 rounded w-full px-4 py-2 ml-2 text-red26">{content.teacher}</div> |
||||
</div> |
||||
<div className="flex mb-2"> |
||||
<div className="bg-gray-100 rounded w-40 px-4 py-2 ml-2 text-red52">زمان کلاس</div> |
||||
<div className="bg-gray-100 rounded w-full px-4 py-2 ml-2 text-red26">
|
||||
{content.classHour} ساعت و {content.classMinute} دقیقه |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
</div> |
||||
|
||||
</div> |
||||
<video className="w-1/2 rounded-md" controls> |
||||
<source |
||||
src={`https://dnvn.ir/api/v1/file/20540`} |
||||
type="video/mp4" |
||||
/> |
||||
</video> |
||||
</div> |
||||
<div className="flex w-full items-center justify-start mb-8" style={{direction: 'ltr'}}> |
||||
<Button title='افزودن به سبد خرید' onClick={addToCartFunction} className="w-40"/> |
||||
|
||||
<h1 className="text-xl font-bold text-red52 p-2 mt-3"> |
||||
مبلغ کل : {content.price} تومان |
||||
</h1> |
||||
|
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default servicePopUp; |
Loading…
Reference in new issue