reza added basic profile

master
RezaAshrafi77 3 years ago
parent 1a994a6a10
commit f2cebef2bf
  1. 1
      package.json
  2. 25
      src/components/Input/index.js
  3. 4
      src/components/Navbar/index.scss
  4. 7
      src/components/Select/index.tsx
  5. 10
      src/components/Textarea/index.scss
  6. 26
      src/custom.scss
  7. 21
      src/redux/actions-type/file.tsx
  8. 2
      src/redux/actions-type/index.tsx
  9. 61
      src/redux/actions-type/public.tsx
  10. 22
      src/redux/actions/file.js
  11. 2
      src/redux/actions/index.tsx
  12. 4
      src/redux/actions/public.tsx
  13. 27
      src/redux/reducers/file.tsx
  14. 2
      src/redux/reducers/index.tsx
  15. 7
      src/redux/reducers/public.tsx
  16. 4
      src/router.js
  17. 8
      src/views/Auth/Login/index.tsx
  18. 61
      src/views/Auth/Profile/Birthdate/index.js
  19. 85
      src/views/Auth/Profile/Birthdate/index.scss
  20. 111
      src/views/Auth/Profile/Document/index.js
  21. 28
      src/views/Auth/Profile/Document/index.scss
  22. 28
      src/views/Auth/Profile/GenderSwitch/index.js
  23. 44
      src/views/Auth/Profile/GenderSwitch/index.scss
  24. 96
      src/views/Auth/Profile/MultipleSelector/index.js
  25. 10
      src/views/Auth/Profile/MultipleSelector/index.scss
  26. 29
      src/views/Auth/Profile/Upload/index.js
  27. 55
      src/views/Auth/Profile/Upload/index.scss
  28. 422
      src/views/Auth/Profile/index.scss
  29. 456
      src/views/Auth/Profile/index.tsx
  30. 18
      src/views/Auth/SignUp/index.tsx
  31. 4
      src/views/Contact/index.tsx
  32. 4
      src/views/Home/Courses/index.tsx
  33. 115
      yarn.lock

@ -49,6 +49,7 @@
"fs-extra": "^9.0.1",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jalali-moment": "^3.3.10",
"jest": "26.6.0",
"jest-circus": "26.6.0",
"jest-resolve": "26.6.0",

@ -2,7 +2,16 @@ import React from "react";
import TextField from "@mui/material/TextField";
import { makeStyles } from "@mui/styles";
export default function FormPropsTextFields(props) {
export default function FormPropsTextFields({
defaultValue,
maxLength,
inputMode,
onInput,
onChange,
align,
label,
name,
}) {
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiTextField-root": {
@ -10,8 +19,8 @@ export default function FormPropsTextFields(props) {
position: "relative",
marginRight: 10,
"& input": {
textAlign: props.align,
direction: props.align === "right" ? "rtl" : "ltr",
textAlign: align,
direction: align === "right" ? "rtl" : "ltr",
},
fontFamily: "numeralLight",
},
@ -19,18 +28,16 @@ export default function FormPropsTextFields(props) {
}));
const classes = useStyles();
const { defaultValue, maxLength, inputMode, onInput, variant, onChange } =
props;
return (
<form className={classes.root} noValidate autoComplete="off">
<div>
<TextField
id="outlined-basic"
name={props.name}
label={props.label}
variant={variant || "outlined"}
name={name}
label={label}
variant={"outlined"}
onChange={(e) => onChange(e)}
defaultValue={defaultValue[props.name] || ""}
defaultValue={defaultValue[name] || ""}
inputProps={{ maxLength }}
onInput={
onInput

@ -1,12 +1,12 @@
.nav{
width: 100%;
background-color: #292929;
background-color: black;
height: 60px;
padding: 0px 10px;
position: fixed !important;
top: 0px !important;
left: 0px;
z-index: 100;
z-index: 150;
&__container{
width: 100%;
font-family: numeralLight;

@ -32,9 +32,10 @@ export default function CustomizedSelects({
labelId="demo-simple-select-label"
id="demo-simple-select"
value={selectedOptions}
onChange={(e: any) => onChange(e)}
onChange={(e: any) => onChange(name, e.target.value)}
>
{options.map((option: any, i: any) => (
{options?.map((option: any, i: any) => (
<MenuItem key={i} value={option.name}>
{option.name}
</MenuItem>
@ -45,7 +46,7 @@ export default function CustomizedSelects({
style={{
position: "absolute",
left: 5,
top: 25,
top: 19,
fontSize: 30,
color: "#a5a5a5",
}}

@ -4,7 +4,7 @@
color: white;
border-radius: 10px;
border: 1px solid #707070;
background-color: #272727;
background-color: black;
margin-top: 10px;
&::placeholder{
color: #a2a2a2;
@ -20,18 +20,18 @@
@media screen and (min-width: 1441px){
.custom-textarea{
font-size: 20px;
font-size: 16px;
&::placeholder{
font-size: 20px;
font-size: 16px;
}
}
}
@media screen and (min-width: 1008px) and (max-width: 1440px) {
.custom-textarea{
font-size: calc(100vw / 85);
font-size: calc(100vw / 110);
&::placeholder{
font-size: calc(100vw / 85);
font-size: calc(100vw / 110);
}
}
}

@ -84,21 +84,7 @@
}
.main {
background: linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
background: -moz-linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
background: -webkit-linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
background: black;
width: 100%;
overflow-x: hidden;
padding-top: 60px;
@ -186,6 +172,11 @@
}
@media screen and (min-width: 641px) and (max-width: 1007px) {
.main{
main {
max-width: 900px;
}
}
.desktop{
display: none !important;
}
@ -195,6 +186,11 @@
}
@media screen and (max-width: 640px) {
.main{
main {
max-width: 500px;
}
}
.desktop{
display: none !important;
}

@ -0,0 +1,21 @@
interface fileUpload {
type : "file/upload"
data : any
params : any
}
interface error{
type : "file/error"
data : undefined
params : any
}
interface loading{
type : "file/loading"
data : undefined
params : any
}
type FileAction = fileUpload | loading | error;
export default FileAction;

@ -5,6 +5,8 @@ export type { default as BookAction } from "./book";
export type { default as BlogAction } from "./blog";
export type { default as productAction } from "./product";
export type { default as FaqAction } from "./faq";
export type { default as FileAction } from "./file";

@ -1,44 +1,61 @@
interface getHomeData {
type : "public/homePage"
data : any
type: "public/homePage";
data: any;
}
interface getBlogList{
type : "public/blogList"
data : any
interface getBlogList {
type: "public/blogList";
data: any;
}
interface getBlogInfo{
type : "public/blogInfo"
data : any
interface getBlogInfo {
type: "public/blogInfo";
data: any;
}
interface setFaqActive{
type : "public/faq/activate"
data : any
interface setFaqActive {
type: "public/faq/activate";
data: any;
}
interface setSubscribe{
type: "public/setSubscribe"
data: any
interface setSubscribe {
type: "public/setSubscribe";
data: any;
}
interface error{
type : "error"
data : undefined
interface getProvince {
type: "public/province";
data: any;
}
interface loading{
type : "loading"
data : undefined
interface getCity {
type: "public/city";
data: any;
}
interface error {
type: "error";
data: undefined;
}
interface loading {
type: "loading";
data: undefined;
}
// interface filterNewProducts{
// }
type PublicAction = getBlogList | getBlogInfo | setSubscribe | getHomeData | setFaqActive | loading | error;
type PublicAction =
| getBlogList
| getBlogInfo
| setSubscribe
| getHomeData
| setFaqActive
| getProvince
| getCity
| loading
| error;
export default PublicAction;

@ -0,0 +1,22 @@
import proxy from "../proxy";
const file = {
upload:
(data = {}) =>
async (dispatch) => {
var formData = new FormData();
for (let key in data) formData.append(key, data[key]);
return await proxy.post(
"file/upload",
formData,
{
dispatch,
headers: {
"Content-Type": "multipart/form-data",
},
},
data
);
},
};
export default file;

@ -8,6 +8,8 @@ export { default as userFactor } from "./userFactor";
export { default as userProduct } from "./userProduct";
export { default as content } from "./content";
export { default as faq } from "./faq";
export { default as file } from "./file";

@ -28,6 +28,10 @@ const publicApi = {
await proxy.get("public/blogInfo", data, { dispatch }),
setSubscribe : (data: Object) => async (dispatch: Dispatch) =>
await dispatch({type : "public/setSubscribe", data : data}),
getProvince: (data = {}) => async (dispatch : Dispatch) =>
await proxy.get("public/province", data, { dispatch }),
getCity: (data = {}) => async (dispatch : Dispatch) =>
await proxy.get("public/city", data, { dispatch }),
// filterNewProducts: (data: Object) => async (dispatch: Dispatch) =>
// await dispatch({ type: "public/filter", data: data }),
};

@ -0,0 +1,27 @@
import {FileAction} from '../actions-type';
const initialState = {
loading: false,
error: null,
uploads: {},
lastUpload: null,
};
export default function file(state = initialState, action : FileAction) {
let { type, data, params } = action;
switch (type) {
case "file/upload":
return {
...state,
loading: false,
error: null,
uploads: { ...state.uploads, [params?.target || "last"]: data.id },
lastUpload: data.id,
};
case "file/loading":
return { ...state, loading: true };
case "file/error":
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -5,3 +5,5 @@ export { default as book } from "./book";
export { default as blog } from "./blog";
export { default as product } from "./product";
export { default as faq } from "./faq";
export { default as file } from "./file";

@ -1,7 +1,6 @@
import { PublicAction } from "../actions-type";
import proxy from '../proxy';
const initialState = {
status : proxy.status(),
homeData: [],
newProducts: [],
levels: [],
@ -11,6 +10,8 @@ const initialState = {
arList: [],
blogList: [],
blog: null,
province : null,
city : null,
mockSubscribes: [
{
id: 0,
@ -261,6 +262,10 @@ export default function publicApi(state = initialState, action: PublicAction) {
return { ...state, loading: false, error: null, blog: data };
case "public/setSubscribe":
return { ...state, loading: false, error: null, selectedSubscribe : data };
case "public/province":
return { ...state, loading: false, error: null, province: data };
case "public/city":
return { ...state, loading: false, error: null, city: data };
case "loading":
return { ...state, loading: true };
case "error":

@ -19,7 +19,7 @@ import proxy from "./redux/proxy";
function router({ status }) {
const home = (
<Route path="/">{proxy.status() ? <Home /> : <Auth page="signup" />}</Route>
<Route exact path="/">{status ? <Home /> : <Auth page="signup" />}</Route>
);
return (
<Router>
@ -62,5 +62,5 @@ function router({ status }) {
}
export default connect((state) => ({
status: state.publicApi.status,
status: state.user.status,
}))(router);

@ -27,8 +27,8 @@ function Login(props: any) {
const onChange = (name: string, value: string) => {
setSignUpFiels({ ...loginFields, [name]: value });
};
const usernameInput = useRef<any>();
const passwordInput = useRef<any>();
// const usernameInput = useRef<any>();
// const passwordInput = useRef<any>();
useEffect(() => {
@ -57,7 +57,7 @@ function Login(props: any) {
align="left"
onInput={onInput.englishAndNumberWithoutSpace}
onChange={onChange}
ref={usernameInput}
// ref={usernameInput}
/>
<Input
name="password"
@ -65,7 +65,7 @@ function Login(props: any) {
align="left"
onInput={onInput.englishAndNumberWithoutSpace}
onChange={onChange}
ref={passwordInput}
// ref={passwordInput}
/>
<div className="login__options d-flex justify-content-between align-items-center">
<div className="d-flex align-items-center">

@ -0,0 +1,61 @@
import React, { useState } from "react";
import onInput from "~/util/onInput";
import Input from "../../../../components/Input/index";
import "./index.scss";
import moment from "jalali-moment";
export default function Birthdate(props) {
const { defaultValue, parent, name } = props;
let momentDate = moment(defaultValue[name]);
let isvalid = momentDate.isValid();
const day = isvalid ? momentDate.format("jDD") : null,
month = isvalid ? momentDate.format("jMM") : null,
year = isvalid ? momentDate.format("jYYYY") : null;
const [state, setState] = useState({ day, month, year });
const onChange = (_name, value) => {
let _state = { ...state, [_name]: value };
setState(_state);
parent.onChange(
name,
moment
.from(`${_state.year}/${_state.month}/${_state.day}`, "fa", "YYYY/M/D")
.locale("en")
);
};
return (
<div className="birthdate d-flex justify-content-between align-items-center">
<label>تاریخ تولد</label>
<div className="mobile-birthdate__date d-flex align-items-center">
<Input
variant="standard"
name="day"
placeholder="روز"
maxLength={2}
onInput={onInput.dayHandler}
parent={{ onChange }}
defaultValue={state}
/>
<span>/</span>
<Input
variant="standard"
name="month"
placeholder="ماه"
maxLength={2}
onInput={onInput.monthHandler}
parent={{ onChange }}
defaultValue={state}
/>
<span>/</span>
<Input
variant="standard"
name="year"
placeholder="سال"
maxLength={4}
onInput={onInput.yearHandler}
parent={{ onChange }}
defaultValue={state}
/>
</div>
</div>
);
}

@ -0,0 +1,85 @@
.birthdate {
width: 100%;
border-radius: 10px;
padding: 0px 10px;
border: 1px solid #777;
margin: 10px 0px;
label {
width: fit-content;
color: #ccc;
font-weight: 100;
}
span {
color: #bfbfbf;
}
input {
border: 0px;
background-color: rgba(204, 204, 204, 0.098);
font-family: numeralLight;
color: #84de56;
max-width: 40px;
text-align: center !important;
direction: ltr;
margin: 0px 5px;
border: none;
&:focus {
outline: 0px;
border: 0px;
}
&::placeholder {
color: #bfbfbf;
}
}
}
@media screen and (max-width: 1000px) {
span {
font-size: 14px;
}
input {
font-size: 14px;
&::placeholder {
font-size: 15px;
}
}
}
@media screen and (min-width: 6401px) and (max-width: 1007px) {
.birthdate {
label {
font-size: calc(100vw / 40) !important;
}
span {
font-size: calc(100vw / 35);
}
input {
font-size: calc(100vw / 20);
margin: 0px 5px !important;
&::placeholder {
font-size: calc(100vw / 30);
}
}
}
}
@media screen and (max-width: 640px) {
.birthdate {
label {
font-size: calc(100vw / 35) !important;
}
span {
font-size: calc(100vw / 35);
}
input {
font-size: calc(100vw / 20);
&::placeholder {
font-size: calc(100vw / 30);
}
}
}
}

@ -0,0 +1,111 @@
import React from "react";
import "./index.scss";
const maxDesktopSize = 1250;
const maxMobileSize = 550;
const fontSize = {
desktop: {
span: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 80,
},
mobile: {
span: window.innerWidth > maxMobileSize ? 14 : window.innerWidth / 30,
},
};
export default function Document(props) {
const { parent, name } = props;
return (
<>
{window.innerWidth < 1000 ? (
<div className="mobile-auth-profile__document d-flex justify-content-center align-items-center mb-3">
{parent.state[name] === "" ? (
<>
<input
type="file"
// parent.onChange(e.target.name, e.target.value)
name={name}
onChange={(e) =>
parent.onChange(e.target.name, e.target.files[0])
}
/>
<span style={{ fontSize: fontSize.mobile.span }}>
گواهی تدریس خود را آپلود کنید.
</span>
</>
) : (
<>
<input
type="file"
name="file"
onChange={(e) =>
parent.onChange(e.target.name, e.target.files[0])
}
/>
<span
style={{
fontSize: fontSize.mobile.span,
width: "100%",
textAlign: "center",
margin: "auto",
}}
>
{parent.state[name].name ||
"گواهی تدریس ثبت شده و درحال بررسی می باشد"}
</span>
</>
)}
</div>
) : null}
{window.innerWidth > 1000 ? (
<div className="mobile-auth-profile__document d-flex justify-content-center-align-items-center">
{parent.state[name] === "" ? (
<>
<input
type="file"
// parent.onChange(e.target.name, e.target.value)
name={name}
onChange={(e) =>
parent.onChange(e.target.name, e.target.files[0])
}
/>
<span
style={{
fontSize: fontSize.mobile.span,
width: "100%",
textAlign: "center",
margin: "auto",
}}
>
گواهی تدریس خود را آپلود کنید.
</span>
</>
) : (
<>
<input
label={props.label}
onChange={(e) =>
parent.onChange(e.target.name, e.target.files[0])
}
name={props.name}
defaultValue=""
type="file"
/>
<span
style={{
fontSize: fontSize.mobile.span,
width: "100%",
textAlign: "center",
margin: "auto",
}}
>
{parent.state[name].name ||
"گواهی تدریس ثبت شده و درحال بررسی می باشد"}
</span>
</>
)}
</div>
) : null}
</>
);
}

@ -0,0 +1,28 @@
.mobile-auth-profile {
&__document {
margin: 10px auto;
width: 100%;
height: 50px;
border-radius: 10px;
border: 2px dashed rgb(209, 209, 209);
position: relative;
input {
width: 100%;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
opacity: 0;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
span {
color: #afafaf;
font-family: numeralLight;
}
}
}

@ -0,0 +1,28 @@
import React from "react";
import "./index.scss";
export default function GenderSwitch({
onChange,
name,
options,
selectedOption,
label,
}) {
return (
<div className="gender d-flex justify-content-between align-items-center">
<div
className={selectedOption === 2 && "gender__active"}
onClick={() => onChange(name, 2)}
>
{options[0]}
</div>
<div
className={selectedOption === 1 && "gender__active"}
onClick={() => onChange(name, 1)}
>
{options[1]}
</div>
</div>
);
}

@ -0,0 +1,44 @@
.gender {
width: 100%;
margin-bottom: 10px;
div {
border-radius: 10px;
font-family: numeralLight;
padding: 13px 0px;
width: 45%;
text-align: center;
cursor: pointer;
color: #ccc;
background-color: black;
border: 1px solid #777;
}
&__active{
background-color: #84de56 !important;
color: white !important;
border: none !important;
}
}
@media screen and (min-width: 1441px) {
.gender{
font-size: 16px;
}
}
@media screen and (min-width: 1008px) and (max-width: 1440px) {
.gender{
font-size: calc(100vw / 90);
}
}
@media screen and (min-width: 641px) and (max-width: 1007px) {
.gender{
font-size: calc(100vw / 40);
}
}
@media screen and (max-width: 640px) {
.gender{
font-size: calc(100vw / 30);
}
}

@ -0,0 +1,96 @@
import React from "react";
import Select from "@mui/material/Select";
import { makeStyles } from "@mui/styles";
import Input from "@mui/material/Input";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import "./index.scss";
export default function MultipleSelector(props) {
const useStyles = makeStyles((theme) => ({
root: {
"& .MuiTextField-root": {
width: "100%",
position: "relative",
marginRight: 10,
"& input": {
textAlign: props.align,
direction: props.align === "right" ? "rtl" : "ltr",
},
},
},
}));
const classes = useStyles();
const { parent, defaultValue, name, label, options, selectedOptions } = props;
return (
<>
{window.innerWidth < 1000 ? (
<FormControl
variant="outlined"
className={`${classes.formControl} mobile-multiple-selector`}
>
<InputLabel id="demo-mutiple-name-label">{label}</InputLabel>
<Select
labelId="demo-mutiple-name-label"
id="demo-mutiple-name"
multiple
value={selectedOptions.split(",")}
onChange={(e) => parent.onChange(name, e.target.value.join(","))}
input={<Input />}
variant="outlined"
>
{options.map((name, i) => (
<MenuItem key={name} value={i}>
{name}
</MenuItem>
))}
</Select>
<KeyboardArrowDownIcon
style={{
position: "absolute",
left: 5,
top: 10,
fontSize: 30,
color: "#a5a5a5",
}}
/>
</FormControl>
) : null}
{window.innerWidth > 1000 ? (
<FormControl
variant="outlined"
className={`${classes.formControl} mobile-multiple-selector`}
>
<InputLabel id="demo-mutiple-name-label">{label}</InputLabel>
<Select
labelId="demo-mutiple-name-label"
id="demo-mutiple-name"
multiple
value={selectedOptions.split(",")}
onChange={(e) => parent.onChange(name, e.target.value.join(","))}
input={<Input />}
variant="outlined"
>
{options.map((name, i) => (
<MenuItem key={name} value={i}>
{name}
</MenuItem>
))}
</Select>
<KeyboardArrowDownIcon
style={{
position: "absolute",
left: 5,
top: 15,
fontSize: 30,
color: "#a5a5a5",
}}
/>
</FormControl>
) : null}
</>
);
}

@ -0,0 +1,10 @@
.mobile-multiple-selector {
width: 100%;
border-radius: 10px;
padding: 9px 10px;
border: 1px solid #ccc !important;
margin: 0px !important;
.MuiInput-formControl {
margin: 9px 0px 8px !important;
}
}

@ -0,0 +1,29 @@
import React from "react";
import AddAPhotoIcon from "@mui/icons-material/AddAPhoto";
import './index.scss';
export default function Upload({ name, value, onChange, label }) {
return (
<div className="profile-upload d-flex justify-content-center align-items-center mb-3">
<>
{value === null ? (
<AddAPhotoIcon style={{ width: 35, height: 35, color: "white" }} />
) : (
<img
src={
value.name
? URL.createObjectURL(value)
: window.baseURL + "file/" + value
}
alt={"کاربر"}
/>
)}
<input
type="file"
name={name}
onChange={(e) => onChange(e.target.name, e.target.files[0])}
/>
</>
</div>
);
}

@ -0,0 +1,55 @@
.profile-upload {
width: 100px;
height: 100px;
border-radius: 50%;
margin-top: 15px auto 0px;
// border: 2px dotted #ccc;
position: relative;
background-color: #272727;
input {
width: 100%;
height: 100%;
opacity: 0;
position: absolute;
left: 0px;
top: 0px;
z-index: 50;
}
span {
color: #505a82;
font-family: numeralLight;
height: 20px;
position: absolute;
left: 0px;
top: calc(50% - 10px);
width: 100%;
text-align: center;
z-index: 10;
}
}
@media screen and (min-width: 1441px) {
.profile-upload {
}
}
@media screen and (min-width: 1008px) and (max-width: 1440px) {
.profile-upload {
}
}
@media screen and (min-width: 641px) and (max-width: 1007px) {
.profile-upload {
width: 80px;
height: 80px;
}
}
@media screen and (max-width: 640px) {
.profile-upload {
width : 80px;
height : 80px;
}
}

@ -0,0 +1,422 @@
.MuiOutlinedInput-input {
font-family: numeralLight !important;
}
.profile {
scrollbar-width: 0px;
padding: 50px 20px 0px;
&::-webkit-scrollbar {
display: none;
}
header {
margin: 30px 0px;
h1 {
margin-top: 15px;
font-family: numeralMedium;
color: white;
letter-spacing: -1px;
}
p {
font-family: numeralLight;
color: white;
text-align: justify;
}
}
&__box {
width: 100%;
border: 1px solid #777;
border-radius: 20px;
&--section {
width: 45%;
}
.MuiMenu-list,
.MuiFormControl-root {
width: 100%;
margin: 10px auto !important;
scrollbar-width: 0px !important;
&::-webkit-scrollbar {
display: none !important;
width: 0px !important;
}
option {
font-family: numeralLight !important;
}
.MuiSelect-iconOutlined {
display: none;
}
.MuiSelect-outlined.MuiSelect-outlined {
padding-right: 15px;
}
color: #797979 !important;
}
button {
margin-top: 20px;
margin-bottom: 50px;
font-family: numeralLight;
border: 0px;
background-color: #00cc69;
border-radius: 7px;
color: white;
padding: 12px 0px;
width: 100%;
}
}
}
@media screen and (min-width: 1441px) {
.profile {
button {
font-size: 21px;
}
header {
}
&__box {
flex-direction: row;
justify-content: space-around;
padding: 30px 10px;
}
}
.MuiFormControl-root {
width: 100%;
margin: 10px auto !important;
.MuiSelect-iconOutlined {
display: none;
}
.MuiSelect-outlined.MuiSelect-outlined {
padding-right: 15px;
}
color: #797979 !important;
}
.MuiOutlinedInput-notchedOutline {
top: 0px !important;
}
.MuiOutlinedInput-notchedOutline {
border-color: #666666 !important;
border-width: 1px !important;
color: green !important;
border-radius: 10px !important;
}
.MuiOutlinedInput-input {
padding: 15px 14px !important;
font-family: numeralLight;
font-size: 20px;
color: #84de56 !important;
&:focus {
border: 0.2px solid #84de56 !important;
border-radius: 10px;
transform: translateY(0.5px);
border-radius: 10px !important;
}
}
.MuiInputLabel-outlined {
font-family: numeralLight !important;
display: inline !important;
position: absolute;
text-align: right !important;
right: 15px !important;
top: 50% !important;
padding: 0px !important;
transform: translate(0px, -50%) scale(1) !important;
}
.MuiInputLabel-shrink {
text-align: center !important;
display: inline;
position: absolute;
right: 0px !important;
top: -8px !important;
transform: translate(0px, 0px) scale(0.85) !important;
padding: 0px 10px !important;
}
label {
background-color: black;
width: fit-content;
text-align: center;
color: #b5b5b5 !important;
letter-spacing: -1px;
font-size: 14px !important;
}
.Mui-focused {
color: rgba(0, 0, 0, 1) !important;
border-color: #84de56 !important;
// background-color: white;
color: #84de56 !important;
}
.MuiInputBase-input {
height: auto !important;
}
}
@media screen and (min-width: 1008px) and (max-width: 1440px) {
.profile {
button {
font-size: calc(100vw / 70);
}
&__box {
padding: 30px 10px;
flex-direction: row;
justify-content: space-around;
}
}
.MuiFormControl-root {
width: 100%;
margin: 10px auto !important;
.MuiSelect-iconOutlined {
display: none;
}
.MuiSelect-outlined.MuiSelect-outlined {
padding-right: 15px;
}
color: #797979 !important;
}
.MuiOutlinedInput-notchedOutline {
top: 0px !important;
}
.MuiOutlinedInput-notchedOutline {
border-color: #666666 !important;
border-width: 1px !important;
color: green !important;
border-radius: 10px !important;
}
.MuiOutlinedInput-input {
padding: 15px 14px !important;
font-family: numeralLight;
font-size: calc(100vw / 80) !important;
color: #84de56 !important;
&:focus {
border: 0.2px solid #84de56 !important;
border-radius: 10px;
transform: translateY(0px);
z-index: 100;
border-radius: 10px !important;
}
}
.MuiInputLabel-outlined {
font-family: numeralLight !important;
display: inline !important;
position: absolute;
text-align: right !important;
right: 10px !important;
top: 50% !important;
padding: 0px !important;
transform: translate(0px, -50%) scale(1) !important;
}
.MuiInputLabel-shrink {
text-align: center !important;
display: inline;
position: absolute;
right: 0px !important;
top: -5px !important;
transform: translate(0px, 0px) scale(0.85) !important;
padding: 0px 10px !important;
z-index: 120 !important;
}
label {
background-color: black;
width: fit-content;
text-align: center;
color: #b5b5b5 !important;
letter-spacing: -1px;
font-size: calc(100vw / 110) !important;
z-index: 120;
}
.Mui-focused {
color: rgba(0, 0, 0, 1) !important;
border-color: #84de56 !important;
// background-color: white;
color: #84de56 !important;
}
.MuiInputBase-input {
height: auto !important;
}
}
@media screen and (min-width: 641px) and (max-width: 1007px) {
.profile {
padding: 50px 100px 10px;
header {
margin: 0px;
margin-top: 30px;
}
&__box {
flex-direction: column;
border: none;
&--section {
width: 100%;
}
}
.MuiFormControl-root {
width: 100%;
margin: 10px auto !important;
.MuiSelect-iconOutlined {
display: none;
}
.MuiSelect-outlined.MuiSelect-outlined {
padding-right: 15px;
}
color: #797979 !important;
}
.MuiOutlinedInput-notchedOutline {
top: 0px !important;
}
.MuiOutlinedInput-notchedOutline {
border-color: #666666 !important;
border-width: 1px !important;
color: green !important;
border-radius: 10px !important;
}
.MuiOutlinedInput-input {
padding: 15px 14px !important;
font-family: numeralLight;
font-size: calc(100vw / 40);
background-color: inherit;
color: #84de56;
&:focus {
border: 0.2px solid #84de56 !important;
border-radius: 10px;
transform: translateY(0px);
z-index: 100;
border-radius: 10px !important;
}
}
.MuiInputLabel-outlined {
font-family: numeralLight !important;
display: inline !important;
position: absolute;
text-align: right !important;
right: 15px;
top: calc(50%);
padding: 0px !important;
transform: translate(0px, -50%) scale(1) !important;
}
.MuiInputLabel-shrink {
text-align: center !important;
display: inline;
position: absolute;
right: 0px;
top: -10px;
transform: translate(0px, 0px) scale(0.85) !important;
padding: 0px 10px !important;
}
label {
background-color: black;
width: fit-content;
text-align: center;
color: #b5b5b5 !important;
letter-spacing: -1px;
font-size: calc(100vw / 40);
z-index: 110;
}
.Mui-focused {
color: rgba(0, 0, 0, 1) !important;
border-color: #84de56 !important;
// background-color: white;
color: #84de56 !important;
}
.MuiInputBase-input {
height: auto !important;
}
}
}
@media screen and (max-width: 640px) {
.profile {
padding: 0px 10px;
header {
margin: 0px;
margin-top: 70px;
}
&__box {
flex-direction: column;
border: none;
&--section {
width: 100%;
}
}
.MuiFormControl-root {
width: 100%;
margin: 10px auto !important;
.MuiSelect-iconOutlined {
display: none;
}
.MuiSelect-outlined.MuiSelect-outlined {
padding-right: 15px;
}
color: #797979 !important;
}
.MuiOutlinedInput-notchedOutline {
top: 0px !important;
}
.MuiOutlinedInput-notchedOutline {
border-color: #666666 !important;
border-width: 1px !important;
color: green !important;
border-radius: 10px !important;
}
.MuiOutlinedInput-input {
padding: 15px 14px !important;
font-family: numeralLight;
font-size: calc(100vw / 30);
background-color: inherit;
border-radius: 10px;
color: #84de56 !important;
&:focus {
border: 0.2px solid #84de56 !important;
border-radius: 10px;
transform: translateY(0px);
z-index: 100;
}
}
.MuiInputLabel-outlined {
font-family: numeralLight !important;
display: inline !important;
position: absolute;
text-align: right !important;
right: 15px;
top: calc(50%);
padding: 0px !important;
transform: translate(0px, -50%) scale(1) !important;
}
.MuiInputLabel-shrink {
text-align: center !important;
display: inline;
position: absolute;
right: 0px;
top: -10px;
transform: translate(0px, 0px) scale(0.7) !important;
padding: 0px 10px !important;
}
label {
background-color: black;
width: fit-content;
text-align: center;
color: #b5b5b5 !important;
letter-spacing: -1px;
font-size: calc(100vw / 25);
z-index: 110;
}
.Mui-focused {
color: rgba(0, 0, 0, 1) !important;
border-color: #84de56 !important;
// background-color: white;
color: #84de56 !important;
}
.MuiInputBase-input {
height: auto !important;
}
}
}

@ -1,9 +1,459 @@
import React from 'react'
import React, { useState, useEffect } from "react";
import onInput from "../../../util/onInput";
import { user, file, publicApi } from "../../../redux/actions";
import { connect } from "react-redux";
import Select from "../../../components/Select/index";
import Input from "../../../components/Input/index";
import TextArea from "../../../components/Textarea/index";
import Upload from "./Upload/index";
import Gender from "./GenderSwitch/index";
import Birthdate from "./Birthdate/index";
import MultipleSelector from "./MultipleSelector/index";
import Document from "./Document/index";
import "./index.scss";
import { useHistory } from "react-router-dom";
import Navbar from "../../../components/Navbar/index";
import Footer from "../../Home/Footer/index";
function Navigate({ path }: any) {
let history = useHistory();
return <>{history.push(path)}</>;
}
const maxDesktopSize = 1250;
const maxMobileSize = 550;
const fontSize = {
desktop: {
h1: window.innerWidth > maxDesktopSize ? 25 : window.innerWidth / 55,
p: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 90,
},
mobile: {
h1: window.innerWidth > maxMobileSize ? 20 : window.innerWidth / 18,
p: window.innerWidth > maxMobileSize ? 14 : window.innerWidth / 28,
},
};
function Profile({
profile,
uploads,
getProvince,
getCity,
setDone,
upload,
setProfile,
province,
provinceList,
cityList,
}: any) {
const [render, setRender] = useState(false);
const [formData, setFormData] = useState({
file: uploads["file"] || profile.picFileId || null,
picFileId: uploads["file"] || profile.picFileId || null,
docFileIds: uploads["docFileIds"] || profile.docFileIds || "",
firstName: "",
lastName: "",
password: "",
username: "",
address: "",
email: "",
birthDate: "",
gender: profile.gender || 1,
status: profile.status || 1,
nationalId: "",
phone: "",
schools: null,
zoneId: "",
schoolId: "",
postalCode: "",
gradeIds: profile.gradeIds,
provinceId: profile.provinceId,
cityId: profile.cityId,
});
useEffect(() => {
getProvince();
getCity({ provinceId: profile.provinceId });
}, []);
const grades= [
{
name : 'پیش دبستانی',
value : 0,
},
{
name: "اول",
value: 1,
},
{
name: "دوم",
value: 2,
},
{
name: "سوم",
value: 3,
},
{
name: "چهارم",
value: 4,
},
{
name: "پنجم",
value: 5,
},
{
name: "ششم",
value: 6,
},
{
name: "هفتم",
value: 7,
},
{
name: "هشتم",
value: 8,
},
{
name: "نهم",
value: 9,
},
{
name: "دهم",
value: 10,
},
{
name: "یازدهم",
value: 11,
},
{
name: "دوازدهم",
value: 12,
},
];
const onChange = (name: string, value: any) => {
if (name === "provinceId") {
getCity({ provinceId: value });
setFormData({ ...formData, cityId: null, [name]: value });
} else if (name === "status") {
setFormData({
...formData,
gradeIds: formData.gradeIds.slice(0, 1) || [],
[name]: value,
});
} else if (name === "docFileIds") {
upload({ file: value, target: name });
setFormData({ ...formData, [name]: value });
} else if (name === "file") {
upload({ file: value, target: name });
setFormData({ ...formData, [name]: value });
} else {
setFormData({ ...formData, [name]: value });
}
};
const onSubmit = async () => {
const {
firstName,
lastName,
username,
//cellphone,
password,
postalCode,
address,
email,
phone,
picFileId,
gender,
nationalId,
birthDate,
schools,
gradeIds,
status,
provinceId,
cityId,
docFileIds,
} = formData;
const data = {
firstName: firstName || profile.firstName,
lastName: lastName || profile.lastName,
username: username || profile.username,
cellphone: profile.cellphone,
password: password || profile.password,
postalCode: postalCode || profile.postalCode,
address: address || profile.address,
email: email || profile.email,
phone: phone || profile.phone,
nationalId: nationalId || profile.nationalId,
picFileId: String(uploads["file"] || picFileId || profile.picFileId),
gender: gender || profile.gender,
birthDate: birthDate || profile.birthDate,
schools: schools || profile.schools,
gradeIds: String(gradeIds || profile.gradeIds),
status: status || profile.status,
provinceId: provinceId || profile.provinceId,
cityId: cityId || profile.cityId,
docFileIds: String(
uploads["docFileIds"] || docFileIds || profile.docFileIds
),
};
await setProfile(data);
};
// if (setDone) return <Navigate path="/" />;
export default function Profile() {
return (
<div className="profile main d-flex justify-content-center">
<Navbar />
<main>
<header className="d-flex align-items-center justify-content-between">
<div>
<h1>حساب کاربری</h1>
<p>لطفا مشخصات خود را به صورت کامل نمایید.</p>
</div>
<div className="mobile justify-content-center">
<Upload
name="file"
value={formData.file}
onChange={onChange}
label="فایل"
/>
</div>
</header>
<div className="profile__box d-flex" onSubmit={(e) => onSubmit()}>
<div className="profile__box--section">
<div className="mb-2 desktop justify-content-center">
<Upload
name="file"
value={formData.file}
onChange={onChange}
label="فایل"
/>
</div>
<div className="mb-2">
<Input
name="firstName"
label="نام"
align="right"
onInput={onInput.persianOnly}
defaultValue={profile}
onChange={onChange}
// ref={usernameInput}
/>
</div>
<div className="mb-2">
<Input
name="lastName"
label="نام خانوادگی"
align="right"
defaultValue={profile}
onChange={onChange}
onInput={onInput.persianOnly}
/>
</div>
<div className="mb-2">
<Input
name="username"
label="نام کاربری"
defaultValue={profile}
onChange={onChange}
align="left"
onInput={onInput.englishAndNumberWithoutSpace}
/>
</div>
<div className="mb-2">
<Gender
options={["دختر", "پسر"]}
name="gender"
selectedOption={formData.gender}
onChange={onChange}
label=""
/>
</div>
<div className="mb-2">
<Input
name="nationalId"
label="کد ملی/اتباع"
align="left"
maxLength={13}
defaultValue={profile}
onChange={onChange}
onInput={onInput.numberOnly}
/>
</div>
<div className="mb-2">
<Birthdate
defaultValue={profile}
name="birthDate"
onChange={onChange}
/>
</div>
<div className="mb-2">
<Input
name="password"
label="رمز عبور"
onChange={onChange}
align="left"
onInput={onInput.englishAndNumberWithoutSpace}
/>
</div>
</div>
<div className="profile__box--section">
<div className="mb-2" style={{ minWidth: "100%" }}>
<Gender
options={["معلم", "دانش آموز"]}
name="status"
label={"عنوان"}
selectedOption={formData.status}
onChange={onChange}
/>
</div>
{formData.status === 1 ? (
<div className="mb-2">
<Select
options={grades}
name="gradeIds"
label={"پایه تحصیلی"}
selectedOptions={formData.gradeIds}
onChange={onChange}
/>
</div>
) : null}
{formData.status === 2 ? (
<div className="mb-2">
<MultipleSelector
options={grades}
name="gradeIds"
label={"پایه تحصیلی"}
selectedOptions={formData.gradeIds}
onChange={onChange}
/>
</div>
) : null}
{formData.status === "دانش آموز" && formData.gradeIds > 9 ? (
<div className="mb-2">
<Select
options={[
"ریاضی",
"تجربی",
"انسانی",
"فنی حرفهای",
"کاردانش",
"معارف",
]}
name="field"
label={"رشته تحصیلی"}
selectedOptions={formData.gradeIds}
onChange={onChange}
/>
</div>
) : null}
{console.log(province)}
<div className="mb-2" style={{ minWidth: "100%" }}>
<Select
options={provinceList}
name="provinceId"
label={"استان"}
selectedOptions={formData.provinceId}
onChange={onChange}
/>
</div>
<div className="mb-2">
<Select
options={cityList}
name="cityId"
label={"شهرستان"}
selectedOptions={formData.cityId}
onChange={onChange}
/>
</div>
{/* <div className="mb-2">
<Select
options={["chaharbagh", "mahalat"]}
name="zoneId"
label={"شهر/روستا"}
/>
</div> */}
{formData.status == 1 ? (
<div className="mb-2">
<Input
name="schools"
label={"نام مدرسه"}
defaultValue={profile}
onInput={onInput.persianOnly}
onChange={onChange}
/>
</div>
)
) : null}
{formData.status == 2 ? (
<div className="mb-2">
<Input
name="schools"
label={"محل تدریس"}
defaultValue={profile}
onInput={onInput.persianOnly}
onChange={onChange}
/>
</div>
) : null}
{formData.status == 2 ? <Document name="docFileIds" /> : null}
<div className="mb-2">
<Input
name="postalCode"
label={"کد پستی"}
align="left"
onChange={onChange}
maxLength={10}
inputMode="numeric"
defaultValue={profile}
onInput={onInput.numberOnly}
/>
</div>
<div className="mb-2">
<TextArea
placeholder={"آدرس محل سکونت"}
name="address"
defaultValue={profile}
onChange={onChange}
/>
</div>
<div className="profile__box--form__footer d-flex justify-content-center">
<button onClick={() => onSubmit()}>ذخیره</button>
</div>
</div>
</div>
<Footer />
</main>
</div>
);
}
export default connect(
(state: any) => ({
profile: state.user.status,
setDone: state.user.setDone,
loading: state.user.loading,
uploading: state.file.loading,
uploads: state.file.uploads,
provinceList: state.publicApi.province,
cityList: state.publicApi.city,
}),
{
getProfile: user.getProfile,
setProfile: user.setProfile,
upload: file.upload,
getProvince: publicApi.getProvince,
getCity: publicApi.getCity,
}
)(Profile);
Profile.defaultProps = {
user: {
name: "اکبر",
icon: "",
description: "",
},
};

@ -35,6 +35,7 @@ function SignUp({ sendOtp, sendPhoneNumber }: any) {
signUpFields?.cellphone.length === 11
) {
setLevel("otp");
setResend(false);
sendPhoneNumber({ cellphone: signUpFields?.cellphone });
setError(undefined);
} else {
@ -63,6 +64,17 @@ function SignUp({ sendOtp, sendPhoneNumber }: any) {
numberInput.current.focus();
}, []);
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();
@ -143,9 +155,15 @@ function SignUp({ sendOtp, sendPhoneNumber }: any) {
<button type="submit" onClick={() => checkOtp()}>
ادامه
</button>
{!resend ? (
<p className="signup__info d-flex justify-content-center">
ارسال مجدد کد در <Timer seconds={60} refresh={setResend} /> دیگر
</p>
) : (
<p className="signup__info d-flex justify-content-center" onClick={() => checkPhoneNumber()}>
دوباره ارسال کنید
</p>
)}
</section>
)}
<Footer />

@ -76,7 +76,7 @@ function Contact({ departmans, selectedDepartman, contactData }: any) {
name="name"
label="نام"
align="right"
// onInput={onInput.englishAndNumberWithoutSpace}
onInput={onInput.persianOnly()}
onChange={onChange}
/>
</div>
@ -112,7 +112,7 @@ function Contact({ departmans, selectedDepartman, contactData }: any) {
name="name"
label="نام"
align="right"
// onInput={onInput.englishAndNumberWithoutSpace}
onInput={onInput.persianOnly()}
onChange={onChange}
/>
</div>

@ -37,13 +37,13 @@ function Courses({number, courses, selectedSort} : any) {
showArrows={true}
pagination={false}
>
{courses.map((item: Object, i: Number) => (
{courses?.map((item: Object, i: Number) => (
<Course data={item} key={i} />
))}
</Carousel>
) : (
<div className="home-courses__list d-flex">
{courses.map((item: Object, i: Number) => (
{courses?.map((item: Object, i: Number) => (
<Course data={item} key={i} />
))}
</div>

@ -3857,6 +3857,11 @@ char-regex@^1.0.2:
resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz"
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
check-types@^11.1.1:
version "11.1.2"
resolved "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz"
@ -3973,6 +3978,18 @@ clean-stack@^2.0.0:
resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz"
integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==
cli-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
dependencies:
restore-cursor "^3.1.0"
cli-width@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
cliui@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz"
@ -4085,6 +4102,11 @@ commander@^4.1.1:
resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commander@^7.0.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
common-tags@^1.8.0:
version "1.8.0"
resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz"
@ -5619,6 +5641,15 @@ extend@~3.0.2:
resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
external-editor@^3.0.3:
version "3.1.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
dependencies:
chardet "^0.7.0"
iconv-lite "^0.4.24"
tmp "^0.0.33"
extglob@^2.0.4:
version "2.0.4"
resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz"
@ -5696,6 +5727,13 @@ figgy-pudding@^3.5.1:
resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz"
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
figures@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
dependencies:
escape-string-regexp "^1.0.5"
file-entry-cache@^6.0.0:
version "6.0.1"
resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz"
@ -6478,7 +6516,7 @@ hyphenate-style-name@^1.0.3:
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
iconv-lite@0.4.24:
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@ -6618,6 +6656,25 @@ ini@^1.3.5:
resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
inquirer@^7.1.0:
version "7.3.3"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003"
integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==
dependencies:
ansi-escapes "^4.2.1"
chalk "^4.1.0"
cli-cursor "^3.1.0"
cli-width "^3.0.0"
external-editor "^3.0.3"
figures "^3.0.0"
lodash "^4.17.19"
mute-stream "0.0.8"
run-async "^2.4.0"
rxjs "^6.6.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
through "^2.3.6"
internal-ip@^4.3.0:
version "4.3.0"
resolved "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz"
@ -7054,6 +7111,15 @@ istanbul-reports@^3.0.2:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
jalali-moment@^3.3.10:
version "3.3.10"
resolved "https://registry.yarnpkg.com/jalali-moment/-/jalali-moment-3.3.10.tgz#10cb4c2080925a41ee8c72862ba63f6b5fb04743"
integrity sha512-hyNsDJXB23MHLnZWPXY+Mu0zsrp+B+KzabyqPP0oGcMsEGp8yMpeVledOY+B/DrIOVeRY7JLz8b3lyJ3/vajsQ==
dependencies:
commander "^7.0.0"
inquirer "^7.1.0"
moment "^2.26.0"
jest-changed-files@^26.6.2:
version "26.6.2"
resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz"
@ -8284,6 +8350,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.26.0:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz"
@ -8334,6 +8405,11 @@ murmurhash-js@^1.0.0:
resolved "https://registry.yarnpkg.com/murmurhash-js/-/murmurhash-js-1.0.0.tgz#b06278e21fc6c37fa5313732b0412bcb6ae15f51"
integrity sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E=
mute-stream@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
nan@^2.12.1:
version "2.15.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
@ -8725,6 +8801,11 @@ os-browserify@^0.3.0:
resolved "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
p-each-series@^2.1.0:
version "2.2.0"
resolved "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz"
@ -10583,6 +10664,14 @@ resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.1
is-core-module "^2.2.0"
path-parse "^1.0.6"
restore-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
dependencies:
onetime "^5.1.0"
signal-exit "^3.0.2"
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz"
@ -10683,6 +10772,11 @@ rsvp@^4.8.4:
resolved "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz"
integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==
run-async@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
@ -10707,6 +10801,13 @@ rw@~0.1.4:
resolved "https://registry.yarnpkg.com/rw/-/rw-0.1.4.tgz#4903cbd80248ae0ede685bf58fd236a7a9b29a3e"
integrity sha1-SQPL2AJIrg7eaFv1j9I2p6mymj4=
rxjs@^6.6.0:
version "6.6.7"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
dependencies:
tslib "^1.9.0"
safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
@ -11674,6 +11775,11 @@ through2@^2.0.0:
readable-stream "~2.3.6"
xtend "~4.0.1"
through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
thunky@^1.0.2:
version "1.1.0"
resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz"
@ -11706,6 +11812,13 @@ tinyqueue@^2.0.3:
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08"
integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
dependencies:
os-tmpdir "~1.0.2"
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz"

Loading…
Cancel
Save