merging feature to develop

This commit is contained in:
AmirHossein Mahmoodi
2023-12-20 10:13:29 +03:30
30 changed files with 190 additions and 816 deletions

View File

@@ -16,8 +16,8 @@
"@mui/icons-material": "^5.11.16",
"@mui/lab": "^5.0.0-alpha.152",
"@mui/material": "^5.12.0",
"@witel/webapp-builder": "^1.2.3",
"@mui/x-date-pickers": "^6.18.5",
"@witel/webapp-builder": "^1.1.0",
"axios": "^1.4.0",
"colord": "^2.9.3",
"date-fns-jalali": "^2.13.0-0",

View File

@@ -1,4 +1,5 @@
{
"middlewares": {},
"time_lines": {
"navgan_first_page": [
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

View File

@@ -12,6 +12,7 @@
"first_page": "خوش آمدید",
"powered_by_witel": "توسعه یافته توسط وایتل",
"login": "ورود",
"today": "امروز",
"pending": "درحال اجرا...",
"login_user_panel": "ورود به پنل کاربران",
"register_navy": "ثبت نام اعضای ناوگان",
@@ -52,7 +53,7 @@
"button_back_dashboard": "بازگشت به صفحه اصلی"
},
"Titles": {
"title_login_page": "صفحه ورود",
"title_login_page": "ورود به سامانه",
"title_register_page": "صفحه ثبت نام",
"title_login_navy_page": "ورود اعضای ناوگان",
"title_login_welfare_services_page": "ورود اعضای خدمات رفاهی",
@@ -131,7 +132,12 @@
"loan_request_correction": "اصلاح درخواست",
"loan_request_detail": "مشاهده جزئیات",
"request_number": "درخواست شماره",
"no_request_found": "درخواستی یافت نشد"
"no_request_found": "درخواستی یافت نشد",
"loan_unique_code": "کد یکتا",
"loan_date": "تاریخ درخواست",
"loan_status": "وضعیت",
"loan_bank_branch": "اطلاعات شعبه",
"loan_details": "نمایش"
},
"LoanRequest": {
"finish_loan_request": "درخواست شما با موفقیت ثبت شد",

View File

@@ -1,14 +1,12 @@
import DashboardLayouts from "@/layouts/dashboardLayouts";
import {
Grid,
Stack,
} from "@mui/material";
import {useEffect, useState} from "react";
import {SHOW_LOAN_REQUEST_NAVGAN} from "@/core/data/apiRoutes";
import useLoading from "@/lib/app/hooks/useLoading";
import useRequest from "@/lib/app/hooks/useRequest";
import moment from "jalali-moment";
import RequestCard from "@/components/dashboard/navgan/followUp-loan/RequestCard";
import {useLoading, useRequest} from "@witel/webapp-builder";
const LoanFollowUpComponent = () => {
const requestServer = useRequest();
@@ -34,7 +32,6 @@ const LoanFollowUpComponent = () => {
}, []);
return (
<DashboardLayouts>
<Stack
spacing={2}
sx={{
@@ -53,7 +50,6 @@ const LoanFollowUpComponent = () => {
))}
</Grid>
</Stack>
</DashboardLayouts>
);
};

View File

@@ -1,64 +1,48 @@
import {useTranslations} from "next-intl";
import {useEffect, useState} from "react";
import {useRequest} from "@witel/webapp-builder";
import TimelineManager from "@/core/components/timelines/timelineManager";
import moment from "jalali-moment";
import {Timeline} from "@mui/lab";
import {LinearProgress} from "@mui/material";
import {useConfig} from "@witel/webapp-builder";
const TimeLineDetails = () => {
const t = useTranslations();
const request = useRequest({notification: false, auth: false})
const {config} = useConfig()
const [timeLineList, setTimeLineList] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
setLoading(true)
request(process.env.NEXT_PUBLIC_CONFIG_APP_URL, 'get').then(res => {
let tempArr = []
for (const timeLine of res.data.time_lines.navgan_first_page) {
let temp = {}
temp['label'] = timeLine.label
temp['date'] = moment(timeLine.date.from, 'jYYYY/jMM/jDD').locale('fa').format('jD jMMMM')
const fromDate = moment(timeLine.date.from, 'jYYYY/jMM/jDD')
const toDate = moment(timeLine.date.to, 'jYYYY/jMM/jDD')
const today = moment()
if (today.isBetween(fromDate, toDate, null, '[]')) {
temp['status'] = 'in progress'
} else if (today.isAfter(toDate, null)) {
temp['status'] = 'done'
} else if (today.isBefore(fromDate, null)) {
temp['status'] = 'open'
}
tempArr.push(temp)
let tempArr = []
for (const timeLine of config.time_lines.navgan_first_page) {
let temp = {}
temp['label'] = timeLine.label
temp['date'] = moment(timeLine.date.from, 'jYYYY/jMM/jDD').locale('fa').format('jD jMMMM')
const fromDate = moment(timeLine.date.from, 'jYYYY/jMM/jDD')
const toDate = moment(timeLine.date.to, 'jYYYY/jMM/jDD')
const today = moment()
if (today.isBetween(fromDate, toDate, null, '[]')) {
temp['status'] = 'in progress'
} else if (today.isAfter(toDate, null)) {
temp['status'] = 'done'
} else if (today.isBefore(fromDate, null)) {
temp['status'] = 'open'
}
setTimeLineList(tempArr)
setLoading(false)
}).catch(() => {
setLoading(false)
})
tempArr.push(temp)
}
setTimeLineList(tempArr)
}, []);
return (
<>
{loading ? (
<LinearProgress/>
) : (
<Timeline position="alternate">
{timeLineList.map((timeLine, index) => (
<TimelineManager
key={index}
status={timeLine.status}
date={timeLine.date}
primaryLabel={timeLine.label.primary}
secondaryLabel={timeLine.label.secondary}
position={index === (timeLineList.length - 1) ? 'end' : ''}
/>
))
}
</Timeline>
)}
</>
<Timeline position="alternate">
{timeLineList.map((timeLine, index) => (
<TimelineManager
key={index}
status={timeLine.status}
date={timeLine.date}
primaryLabel={timeLine.label.primary}
secondaryLabel={timeLine.label.secondary}
position={index === (timeLineList.length - 1) ? 'end' : ''}
/>
))
}
</Timeline>
)
}
export default TimeLineDetails

View File

@@ -5,16 +5,16 @@ import {LinkRouting} from "@witel/webapp-builder";
const LoanRegister = () => {
const t = useTranslations();
return (
<Box sx={{backgroundColor: "primary.light"}}>
<Box sx={{backgroundSize: 'cover', backgroundImage: `url(/images/bg-firstpage-bus.png)`}}>
<Container sx={{padding: 3, color: "white"}} maxWidth="xl">
<Typography sx={{my: 3}} variant={'h3'}>
<Typography sx={{my: 3, textShadow: '1px 1px 2px #555555'}} variant={'h3'}>
{t("app_name")}
</Typography>
<Stack sx={{color: "white"}}>
<Grid sx={{py: 4}} container spacing={2}>
<Grid item xs={12} md={6}>
<Box sx={{paddingBottom: 4}}>
<Typography sx={{lineHeight: 2.7}}>
<Typography sx={{lineHeight: 2.7, textShadow: '1px 1px 2px black'}}>
وام نوسازی ناوگان به هدف رشد و پیشرفت استان های کشور از طریق ارتقای بهره وری و توسعه
اعطا میشود. برای استفاده از تسهیلات این سامانه و درخواست وام می بایست ابتدا وارد
سامانه شوید.
@@ -30,18 +30,6 @@ const LoanRegister = () => {
padding: 1
}}>
<LinkRouting underline="none" color="inherit" href={'/login'}>
<Typography variant="h6">
{t("firstPage.login_button")}
</Typography>
</LinkRouting>
</Container>
<Container maxWidth={'xs'} sx={{
backgroundColor: "primary.main",
textAlign: "center",
borderRadius: 2,
padding: 1
}}>
<LinkRouting underline="none" color="inherit" href={'/register'}>
<Typography variant="h6">
{t("firstPage.register_button")}
</Typography>

View File

@@ -10,6 +10,7 @@ import * as Yup from "yup";
import SvgLogin from "@/core/components/svgs/SvgLogin";
import {CenterLayout, FullPageLayout, LinkRouting, useRequest} from "@witel/webapp-builder";
const SendUserDataComponent = ({
setOtpToken,
setPhoneNumber,

View File

@@ -1,128 +0,0 @@
import StyledForm from "@/core/components/StyledForm";
import {SEND_OTP_TOKEN} from "@/core/data/apiRoutes";
import FingerprintIcon from "@mui/icons-material/Fingerprint";
import {Button, Container, Paper, Stack, TextField, Typography,} from "@mui/material";
import {Field, Formik} from "formik";
import {useTranslations} from "next-intl";
import {useSearchParams} from "next/navigation";
import * as Yup from "yup";
import SvgLogin from "@/core/components/svgs/SvgLogin";
import {CenterLayout, FullPageLayout, LinkRouting, useRequest} from "@witel/webapp-builder";
const RequestOtpComponent = ({
setOtpToken,
setPhoneNumber,
PhoneNumber,
setTimer,
initialTimerValue,
}) => {
const t = useTranslations();
const requestServer = useRequest();
const searchParams = useSearchParams();
const backUrlDecodedPath = searchParams.get("back_url");
const initialValues = {
phone_number: PhoneNumber,
};
const validationSchema = Yup.object().shape({
phone_number: Yup.string().required(
t("RegisterPage.error_message_phone_number")
),
});
const handleSubmit = (values, props) => {
requestServer(SEND_OTP_TOKEN, "post", {
auth: false, data: {
phone_number: values.phone_number,
}
})
.then(function (response) {
setPhoneNumber(values.phone_number);
setOtpToken(true);
setTimer(initialTimerValue);
}).catch(function (error) {
props.setSubmitting(false);
});
};
return (
<FullPageLayout sx={{p: 1}}>
<CenterLayout>
<Container maxWidth="sm">
<Paper elevation={0}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{(props) => (
<Stack spacing={2} sx={{p: 2}}>
<Stack
sx={{width: "100%"}}
alignItems='center'
>
<SvgLogin width={300} height={200}/>
</Stack>
<Typography margin={2} variant="h4" textAlign="center">
{t("Titles.title_register_page")}
</Typography>
<StyledForm sx={{width: "100%"}}>
<Stack spacing={3} sx={{p: 2}}>
<Field
as={TextField}
name="phone_number"
variant="outlined"
label={t("RegisterPage.text_field_phone_number")}
placeholder={t(
"RegisterPage.text_field_enter_your_phone_number"
)}
type={"text"}
error={
!!(props.touched.phone_number && props.errors.phone_number)
}
fullWidth
helperText={
props.touched.phone_number
? props.errors.phone_number
: null
}
/>
<Button
fullWidth
type="submit"
variant="contained"
size="large"
endIcon={<FingerprintIcon/>}
disabled={props.isSubmitting}
>
{t("RegisterPage.button_request_verification")}
</Button>
</Stack>
</StyledForm>
</Stack>
)}
</Formik>
</Paper>
</Container>
</CenterLayout>
<Stack direction="row" alignItems="center" justifyContent="center">
<LinkRouting
sx={{margin: 2}}
href={
backUrlDecodedPath
? decodeURIComponent(backUrlDecodedPath)
: "/register"
}
>
{t("RegisterPage.link_routing_back_to")}{" "}
{backUrlDecodedPath
? t("RegisterPage.link_routing_previuos_page")
: t("RegisterPage.link_routing_register")}
</LinkRouting>
</Stack>
</FullPageLayout>
);
};
export default RequestOtpComponent;

View File

@@ -1,87 +0,0 @@
import {Box, Button, Grid, Stack} from "@mui/material";
import {useTranslations} from "next-intl";
import {useSearchParams} from "next/navigation";
import SvgDashboard from "@/core/components/svgs/SvgDashboard";
import {CenterLayout, FullPageLayout, LinkRouting, NextLinkComposed, useUser} from "@witel/webapp-builder";
const RegisterComponent = () => {
const t = useTranslations();
const {isAuth} = useUser();
const searchParams = useSearchParams();
const backUrlDecodedPath = searchParams.get("back_url");
return (
<FullPageLayout sx={{p: 1}}>
<CenterLayout spacing={3}>
<SvgDashboard width={300} height={200}/>
{isAuth ? (
<Button
variant="contained"
component={NextLinkComposed}
to={{
pathname: "/dashboard",
}}
>
{t("dashboard")}
</Button>
) : (
<Box>
<Grid
container
rowSpacing={{xs: 1, sm: 0}}
sx={{
flexDirection: {xs: "column", sm: "row"},
alignItems: "center",
}}
>
<Grid item xs={12} sm={6} sx={{px: {xs: 0, sm: 1}}}>
<Button
sx={{whiteSpace: "nowrap"}}
variant="contained"
size="large"
component={NextLinkComposed}
to={{
pathname: "register/navy",
}}
>
{t("register_navy")}
</Button>
</Grid>
{/*<Grid item xs={12} sm={6} sx={{px: {xs: 0, sm: 1}}}>*/}
{/* <Button*/}
{/* sx={{whiteSpace: "nowrap"}}*/}
{/* variant="contained"*/}
{/* size="large"*/}
{/* component={NextLinkComposed}*/}
{/* to={{*/}
{/* pathname: "register/welfare-services",*/}
{/* }}*/}
{/* >*/}
{/* {t("register_welfare_services")}*/}
{/* </Button>*/}
{/*</Grid>*/}
</Grid>
</Box>
)}
</CenterLayout>
<Stack direction="row" alignItems="center" justifyContent="center">
<LinkRouting
sx={{margin: 2}}
href={
backUrlDecodedPath
? decodeURIComponent(backUrlDecodedPath)
: "/"
}
>
{t("RegisterPage.link_routing_back_to")}{" "}
{backUrlDecodedPath
? t("RegisterPage.link_routing_previuos_page")
: t("LoginPage.link_routing_main_page")}
</LinkRouting>
</Stack>
</FullPageLayout>
);
};
export default RegisterComponent;

View File

@@ -1,173 +0,0 @@
import StyledForm from "@/core/components/StyledForm";
import {REGISTER} from "@/core/data/apiRoutes";
import LoginIcon from "@mui/icons-material/Login";
import ChangeCircleIcon from "@mui/icons-material/ChangeCircle";
import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material";
import {Field, Formik} from "formik";
import {useTranslations} from "next-intl";
import * as Yup from "yup";
import ResendToken from "@/core/components/ResendToken";
import SvgRegister from "@/core/components/svgs/SvgRegister";
import AutoSubmit from "@/core/components/AutoSubmit";
import {CenterLayout, FullPageLayout, useRequest, useUser} from "@witel/webapp-builder";
const UserRegisterComponent = ({
PhoneNumber,
setOtpToken,
initialTimerValue,
timer,
setTimer,
}) => {
const t = useTranslations();
const {setToken} = useUser();
const requestServer = useRequest();
const initialValues = {
type_id: "1",
verification_code: "",
phone_number: PhoneNumber,
national_id: "",
};
const validationSchema = Yup.object().shape({
verification_code: Yup.string().required(
t("RegisterPage.error_message_verification_code")
),
national_id: Yup.string().required(
t("RegisterPage.error_message_national_id")
),
});
const handleSubmit = (values, props) => {
requestServer(REGISTER, "post", {
auth: false, data: {
type_id: values.type_id,
national_id: values.national_id,
phone_number: values.phone_number,
verification_code: values.verification_code,
}
})
.then(function (response) {
setOtpToken(true);
setToken(response.data.token);
}).catch(function (error) {
props.setSubmitting(false);
});
};
return (
<FullPageLayout sx={{p: 1}}>
<CenterLayout>
<Container maxWidth="sm">
<Paper elevation={0}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{(props) => (
<Stack spacing={2} sx={{p: 2}}>
<Stack
sx={{width: "100%"}}
alignItems='center'
>
<SvgRegister width={300} height={200}/>
</Stack>
<Typography margin={2} variant="h4" textAlign="center">
{t("register_navy")}
</Typography>
<StyledForm sx={{width: "100%"}}>
<Stack spacing={3} sx={{p: 2}}>
<Box
sx={{
display: {xs: "column", sm: "flex"},
alignItems: "center",
textAlign: {xs: "center", sm: "unset"},
justifyContent: "space-between",
}}
>
<Typography variant="button" sx={{display: "block"}}>
{t("LoginPage.sent_token_to")}: {PhoneNumber}
</Typography>
<Button
size="small"
startIcon={<ChangeCircleIcon/>}
variant="outlined"
sx={{whiteSpace: "nowrap", my: {xs: 1, sm: 0}}}
onClick={() => setOtpToken(false)}
>
{t("LoginPage.change_phone_number")}
</Button>
</Box>
<Field
as={TextField}
name="verification_code"
variant="outlined"
label={t("LoginPage.text_field_verification_code")}
placeholder={t(
"LoginPage.text_field_enter_your_verification_code"
)}
type={"number"}
error={
!!(props.touched.verification_code && props.errors.verification_code)
}
fullWidth
helperText={
props.touched.verification_code
? props.errors.verification_code
: null
}
onChange={(e) => e.target.value.length <= 6 ? props.setFieldValue("verification_code", e.target.value) : ""}
/>
<AutoSubmit/>
<ResendToken
initialTimerValue={initialTimerValue}
timer={timer}
setTimer={setTimer}
PhoneNumber={PhoneNumber}
/>
<Divider>
<Chip label={t("RegisterPage.complete_information")}/>
</Divider>
<Field
as={TextField}
name="national_id"
variant="outlined"
label={t("RegisterPage.text_field_national_id")}
placeholder={t(
"RegisterPage.text_field_enter_your_national_id"
)}
type={"text"}
error={
!!(props.touched.national_id && props.errors.national_id)
}
fullWidth
helperText={
props.touched.national_id
? props.errors.national_id
: null
}
/>
<Button
fullWidth
type="submit"
variant="contained"
size="large"
endIcon={<LoginIcon/>}
disabled={props.isSubmitting}
>
{t("RegisterPage.button_submit")}
</Button>
</Stack>
</StyledForm>
</Stack>
)}
</Formik>
</Paper>
</Container>
</CenterLayout>
</FullPageLayout>
);
};
export default UserRegisterComponent;

View File

@@ -1,37 +0,0 @@
import {useState} from "react";
import RequestOtpComponent from "../RequestOtp";
import UserRegisterComponent from "./UserRegister";
const NavyComponent = () => {
const [otpToken, setOtpToken] = useState(false);
const [PhoneNumber, setPhoneNumber] = useState("");
// For Resend Token (read ResendToken Component Doc)
const initialTimerValue = 30;
const [timer, setTimer] = useState(initialTimerValue);
// End For Resend Token
if (!otpToken) {
return (
<RequestOtpComponent
setOtpToken={setOtpToken}
PhoneNumber={PhoneNumber}
setPhoneNumber={setPhoneNumber}
setTimer={setTimer}
initialTimerValue={initialTimerValue}
/>
);
} else {
return (
<UserRegisterComponent
PhoneNumber={PhoneNumber}
setOtpToken={setOtpToken}
timer={timer}
setTimer={setTimer}
initialTimerValue={initialTimerValue}
/>
);
}
};
export default NavyComponent;

View File

@@ -1,174 +0,0 @@
import StyledForm from "@/core/components/StyledForm";
import {REGISTER} from "@/core/data/apiRoutes";
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import LoginIcon from "@mui/icons-material/Login";
import ChangeCircleIcon from "@mui/icons-material/ChangeCircle";
import {Box, Button, Chip, Container, Divider, Paper, Stack, TextField, Typography,} from "@mui/material";
import {Field, Formik} from "formik";
import {useTranslations} from "next-intl";
import * as Yup from "yup";
import ResendToken from "@/core/components/ResendToken";
import useUser from "@/lib/app/hooks/useUser";
import SvgRegister from "@/core/components/svgs/SvgRegister";
import useRequest from "@/lib/app/hooks/useRequest";
const UserRegisterComponent = ({
PhoneNumber,
setOtpToken,
initialTimerValue,
timer,
setTimer,
}) => {
const t = useTranslations();
const {setToken} = useUser();
const requestServer = useRequest();
const initialValues = {
type_id: "2",
verification_code: "",
phone_number: PhoneNumber,
national_id: "",
};
const validationSchema = Yup.object().shape({
verification_code: Yup.string().required(
t("RegisterPage.error_message_verification_code")
),
national_id: Yup.string().required(
t("RegisterPage.error_message_national_id")
),
});
const handleSubmit = (values, props) => {
requestServer(REGISTER, "post", {
auth: false, data: {
type_id: values.type_id,
national_id: values.national_id,
phone_number: values.phone_number,
verification_code: values.verification_code,
}
})
.then(function (response) {
setOtpToken(true);
setToken(response.data.token);
}).catch(function (error) {
props.setSubmitting(false);
});
};
return (
<FullPageLayout sx={{p: 1}}>
<CenterLayout>
<Container maxWidth="sm">
<Paper elevation={0}>
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{(props) => (
<Stack spacing={2} sx={{p: 2}}>
<Stack
sx={{width: "100%"}}
alignItems='center'
>
<SvgRegister width={300} height={200}/>
</Stack>
<Typography margin={2} variant="h4" textAlign="center">
{t("register_welfare_services")}
</Typography>
<StyledForm sx={{width: "100%"}}>
<Stack spacing={3} sx={{p: 2}}>
<Box
sx={{
display: {xs: "column", sm: "flex"},
alignItems: "center",
textAlign: {xs: "center", sm: "unset"},
justifyContent: "space-between",
}}
>
<Typography variant="button" sx={{display: "block"}}>
{t("LoginPage.sent_token_to")}: {PhoneNumber}
</Typography>
<Button
size="small"
startIcon={<ChangeCircleIcon/>}
variant="outlined"
onClick={() => setOtpToken(false)}
sx={{whiteSpace: "nowrap", my: {xs: 1, sm: 0}}}
>
{t("LoginPage.change_phone_number")}
</Button>
</Box>
<Field
as={TextField}
name="verification_code"
variant="outlined"
label={t("LoginPage.text_field_verification_code")}
placeholder={t(
"LoginPage.text_field_enter_your_verification_code"
)}
type={"text"}
error={
!!(props.touched.verification_code && props.errors.verification_code)
}
fullWidth
helperText={
props.touched.verification_code
? props.errors.verification_code
: null
}
/>
<ResendToken
initialTimerValue={initialTimerValue}
timer={timer}
setTimer={setTimer}
PhoneNumber={PhoneNumber}
disabled={props.isSubmitting}
/>
<Divider>
<Chip label={t("RegisterPage.complete_information")}/>
</Divider>
<Field
as={TextField}
name="national_id"
variant="outlined"
label={t("RegisterPage.text_field_national_id")}
placeholder={t(
"RegisterPage.text_field_enter_your_national_id"
)}
type={"text"}
error={
!!(props.touched.national_id && props.errors.national_id)
}
fullWidth
helperText={
props.touched.national_id
? props.errors.national_id
: null
}
/>
<Button
fullWidth
type="submit"
variant="contained"
size="large"
endIcon={<LoginIcon/>}
disabled={props.isSubmitting}
>
{t("RegisterPage.button_submit")}
</Button>
</Stack>
</StyledForm>
</Stack>
)}
</Formik>
</Paper>
</Container>
</CenterLayout>
</FullPageLayout>
);
};
export default UserRegisterComponent;

View File

@@ -1,37 +0,0 @@
import {useState} from "react";
import RequestOtpComponent from "../RequestOtp";
import UserRegisterComponent from "./UserRegister";
const WelfareServicesComponent = () => {
const [otpToken, setOtpToken] = useState(false);
const [PhoneNumber, setPhoneNumber] = useState("");
// For Resend Token (read ResendToken Component Doc)
const initialTimerValue = 30;
const [timer, setTimer] = useState(initialTimerValue);
// End For Resend Token
if (!otpToken) {
return (
<RequestOtpComponent
setOtpToken={setOtpToken}
PhoneNumber={PhoneNumber}
setPhoneNumber={setPhoneNumber}
setTimer={setTimer}
initialTimerValue={initialTimerValue}
/>
);
} else {
return (
<UserRegisterComponent
PhoneNumber={PhoneNumber}
setOtpToken={setOtpToken}
timer={timer}
setTimer={setTimer}
initialTimerValue={initialTimerValue}
/>
);
}
};
export default WelfareServicesComponent;

View File

@@ -39,14 +39,6 @@ const GlobalHead = () => {
/>
<link
rel="icon"
type="image/svg"
sizes="32x32"
href="/icons/favicon.png"
/>
<link
rel="icon"
type="image/svg"
sizes="16x16"
href="/icons/favicon.png"
/>
</Head>

View File

@@ -1,7 +1,7 @@
import {Button} from "@mui/material";
import {useTranslations} from "next-intl";
import {useEffect} from "react";
import {SEND_OTP_TOKEN} from "../data/apiRoutes";
import {LOGIN, SEND_OTP_TOKEN} from "../data/apiRoutes";
import {useDirection, useRequest} from "@witel/webapp-builder";
const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber, disabled}) => {

View File

@@ -0,0 +1,91 @@
import {useTheme} from "@mui/material";
const SvgMaintenance = ({width, height}) => {
const theme = useTheme()
const fillColor = theme.palette.primary.main
return (
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width={width} height={height}
viewBox="0 0 945 583.2243">
<path id="b0cf38c7-358d-48dc-a444-e9782686dfa5-97" data-name="Path 438"
d="M222.88482,693.5243a24.21463,24.21463,0,0,0,23.38269-4.11877c8.18977-6.87442,10.758-18.196,12.84671-28.68191l6.17972-31.01657-12.93769,8.90836c-9.30465,6.40641-18.81827,13.01866-25.26012,22.29785s-9.25222,21.94708-4.07792,31.988"
transform="translate(-127.5 -158.38785)" fill="#e6e6e6"/>
<path id="acbbaa8b-0bc2-4bc9-96d7-93dd88f90f19-98" data-name="Path 439"
d="M224.88254,733.23486c-1.6284-11.86369-3.30382-23.88079-2.15885-35.87167,1.01467-10.64933,4.26374-21.04881,10.87831-29.57938a49.20592,49.20592,0,0,1,12.62466-11.44039c1.26216-.79648,2.4241,1.20354,1.16733,1.997A46.77938,46.77938,0,0,0,228.88954,680.666c-4.02858,10.24607-4.67546,21.41582-3.98154,32.30029.41943,6.58218,1.31074,13.12121,2.20587,19.65252a1.19817,1.19817,0,0,1-.808,1.4225,1.16348,1.16348,0,0,1-1.42253-.808Z"
transform="translate(-127.5 -158.38785)" fill="#f2f2f2"/>
<path id="bed63620-84ae-4c66-a7c8-0d9b30f8c1e7-99" data-name="Path 442"
d="M236.60356,714.19841A17.82515,17.82515,0,0,0,252.135,722.217c7.8644-.37318,14.41806-5.85972,20.31713-11.07026l17.452-15.40881-11.54988-.5528c-8.30619-.39784-16.82672-.771-24.73813,1.79338s-15.20758,8.72639-16.654,16.9154"
transform="translate(-127.5 -158.38785)" fill="#e6e6e6"/>
<path id="fc4eb8ca-daad-4589-b224-2c71eec1c546-100" data-name="Path 443"
d="M220.27955,740.05454c7.83972-13.87142,16.93235-29.28794,33.1808-34.21551A37.02589,37.02589,0,0,1,267.4158,704.398c1.4819.128,1.1118,2.41174-.367,2.28454a34.39824,34.39824,0,0,0-22.27164,5.89215c-6.27994,4.27453-11.16975,10.21755-15.30781,16.51907-2.5351,3.8605-4.80576,7.88445-7.07642,11.903C221.66738,742.28125,219.54555,741.35371,220.27955,740.05454Z"
transform="translate(-127.5 -158.38785)" fill="#f2f2f2"/>
<path id="ec83fa9a-7bb4-4b90-a90b-e1cec4444963-101" data-name="Path 442"
d="M1008.35714,710.03894a17.82515,17.82515,0,0,1-17.065,3.78282c-7.50783-2.37076-12.4416-9.35006-16.813-15.89522l-12.93426-19.3574,11.30757,2.41744c8.132,1.73826,16.46493,3.55513,23.45819,8.05635s12.47224,12.32329,11.77771,20.61"
transform="translate(-127.5 -158.38785)" fill="#e6e6e6"/>
<path id="e32935a9-e392-46b4-9a67-68c65f1cc9fa-102" data-name="Path 443"
d="M1017.53074,739.20841c-4.03412-15.41439-8.88464-32.64277-23.33408-41.55944a37.026,37.026,0,0,0-13.12367-4.9599c-1.46539-.255-1.69126,2.04749-.22905,2.30247a34.39822,34.39822,0,0,1,20.02606,11.3886c4.9789,5.73758,8.18741,12.733,10.57751,19.88279,1.46425,4.38021,2.63106,8.85084,3.79926,13.31624C1015.61991,741.00647,1017.90833,740.652,1017.53074,739.20841Z"
transform="translate(-127.5 -158.38785)" fill="#f2f2f2"/>
<path
d="M858.65906,513.48057H594.33494a7.97081,7.97081,0,0,1-7.96157-7.96157V416.34942a7.97081,7.97081,0,0,1,7.96157-7.96157H858.65906a7.9707,7.9707,0,0,1,7.96157,7.96157V505.519A7.9707,7.9707,0,0,1,858.65906,513.48057Z"
transform="translate(-127.5 -158.38785)" fill="#f1f1f1"/>
<rect x="500.27353" y="273.88471" width="70.06181" height="7.96157" fill={fillColor}/>
<circle cx="662.68956" cy="278.66165" r="4.77694" fill={fillColor}/>
<circle cx="678.6127" cy="278.66165" r="4.77694" fill={fillColor}/>
<circle cx="694.53583" cy="278.66165" r="4.77694" fill={fillColor}/>
<path
d="M858.65906,626.53486H594.33494a7.97081,7.97081,0,0,1-7.96157-7.96157V529.40371a7.97081,7.97081,0,0,1,7.96157-7.96157H858.65906a7.9707,7.9707,0,0,1,7.96157,7.96157v89.16958A7.9707,7.9707,0,0,1,858.65906,626.53486Z"
transform="translate(-127.5 -158.38785)" fill="#f1f1f1"/>
<rect x="500.27353" y="386.939" width="70.06181" height="7.96157" fill={fillColor}/>
<circle cx="662.68956" cy="391.71594" r="4.77694" fill={fillColor}/>
<circle cx="678.6127" cy="391.71594" r="4.77694" fill={fillColor}/>
<circle cx="694.53583" cy="391.71594" r="4.77694" fill={fillColor}/>
<path
d="M858.65906,739.58915H594.33494a7.97081,7.97081,0,0,1-7.96157-7.96156V642.458a7.97081,7.97081,0,0,1,7.96157-7.96157H858.65906a7.9707,7.9707,0,0,1,7.96157,7.96157v89.16959A7.97069,7.97069,0,0,1,858.65906,739.58915Z"
transform="translate(-127.5 -158.38785)" fill="#f1f1f1"/>
<rect x="500.27353" y="499.99329" width="70.06181" height="7.96157" fill={fillColor}/>
<circle cx="662.68956" cy="504.77024" r="4.77694" fill={fillColor}/>
<circle cx="678.6127" cy="504.77024" r="4.77694" fill={fillColor}/>
<circle cx="694.53583" cy="504.77024" r="4.77694" fill={fillColor}/>
<path
d="M759.01179,321.31453l-.29232-.216-.007-.00528a3.57626,3.57626,0,0,0-5.00334.73888L694.21319,401.9379h-6.54562v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.90531a1.43056,1.43056,0,0,0-1.43052,1.43052v1.53783h-2.26034v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.9053a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.253v-1.53783a1.43057,1.43057,0,0,0-1.43053-1.43052h-3.9053a1.43056,1.43056,0,0,0-1.43052,1.43052v1.53783h-2.26034v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052H655.259a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.253v-1.53783a1.43057,1.43057,0,0,0-1.43053-1.43052h-3.9053a1.43034,1.43034,0,0,0-1.43052,1.43052v1.53783H642.5488v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052H637.213a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.26034v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.9053a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.253v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.9053a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.26034v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.9053a1.43057,1.43057,0,0,0-1.43053,1.43052v1.53783h-2.253v-1.53783a1.43056,1.43056,0,0,0-1.43052-1.43052h-3.90531a1.43056,1.43056,0,0,0-1.43052,1.43052v1.53783H596.858a3.57618,3.57618,0,0,0-3.57631,3.57631V408.926a3.57618,3.57618,0,0,0,3.57631,3.57631h96.76151a5.32944,5.32944,0,0,0,5.21778-4.24744l.037.02751L759.74521,326.325l.00559-.00707A3.57671,3.57671,0,0,0,759.01179,321.31453Z"
transform="translate(-127.5 -158.38785)" fill="#3f3d56"/>
<polygon points="255.504 550.825 267.523 556.976 296.966 513.544 279.228 504.466 255.504 550.825"
fill="#ffb7b7"/>
<path
d="M381.94612,703.72021l23.66983,12.113.001.00049a16.94563,16.94563,0,0,1,7.3641,22.8037l-.25087.49017-38.75427-19.83265Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<polygon points="394.317 567.652 407.819 567.652 414.242 515.575 394.315 515.575 394.317 567.652"
fill="#ffb7b7"/>
<path
d="M518.37323,721.632l26.58922-.00107h.00107a16.94563,16.94563,0,0,1,16.94473,16.94446v.55063l-43.53421.00162Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<path
d="M458.66285,301.26058s-9.0412-6.9268-9.0412,9.99291l-1.42756,55.91271,15.94107,52.81966,9.27913-17.1307-3.80682-37.11652Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<path
d="M555.37734,454.19165s10.48418,51.058-2.79579,92.95976l-7.33892,161.10695-26.90941-2.09684-9.43576-119.51969-9.0863-59.41037-18.87153,54.16828L418.73348,696.02681l-28.65677-22.36625s31.75629-86.64916,55.2167-104.84184l11.76615-134.011Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<circle cx="523.48018" cy="202.31369" r="30.68251"
transform="translate(-32.63308 406.2144) rotate(-61.33685)" fill="#ffb7b7"/>
<path
d="M521.30883,208.82157c3.67807.47856,6.45254-3.28467,7.73937-6.76336s2.2673-7.5286,5.46514-9.40772c4.36891-2.56725,9.95872.52048,14.95479-.32655,5.64211-.95654,9.31053-6.93607,9.598-12.65146s-1.987-11.21239-4.21862-16.48193l-.77911,6.54884a12.98679,12.98679,0,0,0-5.67512-11.35154l1.00419,9.60941A10.199,10.199,0,0,0,537.6641,159.558l.15814,5.72564c-6.51663-.77489-13.09021-1.55087-19.62615-.96052s-13.11751,2.65828-18.0712,6.96269c-7.40994,6.43874-10.11621,17.04088-9.20765,26.81529s4.94341,18.95675,9.14865,27.827c1.058,2.23177,2.52146,4.75016,4.97491,5.03445,2.20445.25544,4.22155-1.58732,4.90683-3.698a13.40422,13.40422,0,0,0-.0595-6.58474c-.62-3.2946-1.40155-6.6621-.81863-9.96346s2.9579-6.56372,6.28582-6.96831,6.73322,3.3994,5.13321,6.34537Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<polygon points="429.776 309.458 327.357 302.85 335.066 270.913 428.674 291.838 429.776 309.458"
fill="#cbcbcb"/>
<path
d="M494.11389,244.15824l6.424-8.91878s7.18028,2.44014,26.40983,12.01183l1.35857,8.35615L561.685,460.9092,501.01375,458.292l-16.5219-.35153-5.4068-12.12-6.66725,11.86313-16.13421-.34328-16.41693-9.51706,16.179-49.48869,5.23438-45.206-8.0895-42.58883s-10.17937-39.10848,29.027-60.19538Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<path
d="M630.86271,399.57305a10.48605,10.48605,0,0,1-13.04108-9.40577L581.82654,380.526l14.48005-12.85707,31.9616,11.12669a10.54289,10.54289,0,0,1,2.59452,20.77747Z"
transform="translate(-127.5 -158.38785)" fill="#ffb7b7"/>
<path
d="M614.74112,394.13009a6.14221,6.14221,0,0,1-4.987.39563l-59.21317-22.47383a63.2273,63.2273,0,0,1-34.03214-28.68449l-24.6929-44.04893a19.76509,19.76509,0,1,1,29.49118-26.323L564.04672,340.737l53.7869,31.53448a6.15547,6.15547,0,0,1,2.61747,6.54608l-2.67464,11.33426a6.1431,6.1431,0,0,1-1.86626,3.15032A6.07364,6.07364,0,0,1,614.74112,394.13009Z"
transform="translate(-127.5 -158.38785)" fill="#2f2e41"/>
<path d="M1071.5,741.38785h-943a1,1,0,0,1,0-2h943a1,1,0,0,1,0,2Z" transform="translate(-127.5 -158.38785)"
fill="#cbcbcb"/>
</svg>
)
}
export default SvgMaintenance

View File

@@ -20,7 +20,7 @@ const sidebarMenu = [
route: "/dashboard/navgan/add-request-loan",
icon: <DataSaverOnIcon sx={{width: 'inherit', height: 'inherit'}}/>,
selected: false,
permission: "can_request_a_new_loan"
permission: "can_request_navgan_loan"
},
{
key: "sidebar.followUp-loan",

View File

@@ -0,0 +1,12 @@
import {parse} from "next-useragent";
export const globalServerProps = async ({req, locale}) => {
const {isBot} = parse(req.headers["user-agent"]);
return {
config: (await import(`&/config.json`)).default,
messages: (await import(`&/locales/${locale}/app.json`)).default,
isBot,
locale,
}
}

View File

@@ -2,20 +2,24 @@ import {DashboardLayout as DashboardLayoutPure, useUser} from "@witel/webapp-bui
import headerProfileItems from "@/core/data/headerProfileItems";
import sidebarMenu from "@/core/data/sidebarMenu";
import {GET_SIDEBAR_NOTIFICATION} from "@/core/data/apiRoutes";
import UserInfo from "@/middlewares/UserInfo";
import {useTranslations} from "next-intl";
import moment from "jalali-moment";
const DashboardLayout = (props) => {
const {user} = useUser()
const middlewaresProps = props.middlewaresProps || {}
const t = useTranslations()
return (
<>
<DashboardLayoutPure
middlewares={{list: [], props: {...middlewaresProps}}}
loginUrl={'/login'}
user_introduction={user.type_name}
middlewares={{list: [UserInfo], props: {...middlewaresProps,loginUrl:'/login'}}}
user_introduction={user.phone_number}
headerProfileItems={headerProfileItems}
headerSubtitle={`${t('today')} ${moment().locale('fa').format('LL')}`}
sidebarMenu={sidebarMenu}
urlNotification={GET_SIDEBAR_NOTIFICATION}
BC_segmentsToRemove={[]}
BC_segmentsToRemove={['navgan']}
{...props}
/>
</>

View File

@@ -0,0 +1,9 @@
import {useUser} from "@witel/webapp-builder";
const UserInfo = ({children}) => {
const {user} = useUser();
const userAccess = user.profile_completed;
return userAccess ? <>{children}</> : '';
};
export default UserInfo;

View File

@@ -2,10 +2,12 @@ import "&/global.scss";
import "moment/locale/fa";
import {
AppLayout,
ConfigProvider,
LanguageProvider,
LoadingProvider,
MuiLayout,
NetworkProvider,
PageMiddleware,
ToastProvider,
UserProvider
} from "@witel/webapp-builder";
@@ -18,8 +20,8 @@ import GlobalHead from "@/core/components/GlobalHead";
import Layout from "@/layouts";
const App = ({Component, pageProps}) => {
return (
<>
return (<>
<ConfigProvider config={pageProps.config || {}}>
<UserProvider urlGetUser={GET_USER} schemaGetUser={(data) => data}>
<LanguageProvider defaultLanguage={process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE}
languageList={languageList}>
@@ -31,7 +33,9 @@ const App = ({Component, pageProps}) => {
<AppLayout headComponent={GlobalHead} isBot={pageProps.isBot}>
<NetworkProvider>
<Layout layout={pageProps.layout}>
<Component {...pageProps} />
<PageMiddleware>
<Component {...pageProps} />
</PageMiddleware>
</Layout>
</NetworkProvider>
</AppLayout>
@@ -41,8 +45,8 @@ const App = ({Component, pageProps}) => {
</NextIntlProvider>
</LanguageProvider>
</UserProvider>
</>
);
</ConfigProvider>
</>);
};
export default App;

View File

@@ -1,5 +1,5 @@
import FirstComponent from "@/components/dashboard/first";
import {parse} from "next-useragent";
import {globalServerProps} from "@/core/utils/globalServerProps";
export default function Dashboard() {
return (
@@ -8,13 +8,10 @@ export default function Dashboard() {
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
...await globalServerProps({req, locale}),
title: "Dashboard.dashboard_page",
isBot,
locale,
layout: {name: 'DashboardLayout'}
},
};

View File

@@ -1,5 +1,5 @@
import {parse} from "next-useragent";
import LoanRequestComponent from "@/components/dashboard/navgan/add-request-loan";
import {globalServerProps} from "@/core/utils/globalServerProps";
export default function AddLoanRequest() {
return (
@@ -8,14 +8,11 @@ export default function AddLoanRequest() {
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
...await globalServerProps({req, locale}),
title: "LoanRequest.loan_request_page",
isBot,
locale,
layout: {name: 'DashboardLayout'}
layout: {name: 'DashboardLayout', permissions: ["can_request_navgan_loan"]}
},
};
}

View File

@@ -1,5 +1,5 @@
import {parse} from "next-useragent";
import LoanFollowUpComponent from "@/components/dashboard/navgan/followUp-loan";
import {globalServerProps} from "@/core/utils/globalServerProps";
export default function FollowUpLoan() {
return (
@@ -8,13 +8,10 @@ export default function FollowUpLoan() {
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
...await globalServerProps({req, locale}),
title: "LoanRequest.loan_request_page",
isBot,
locale,
layout: {name: 'DashboardLayout'}
},
};

View File

@@ -1,5 +1,5 @@
import FirstComponent from "@/components/first";
import {parse} from "next-useragent";
import {globalServerProps} from "@/core/utils/globalServerProps";
export default function Home() {
return (
@@ -10,12 +10,10 @@ export default function Home() {
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
...await globalServerProps({req, locale}),
title: "first_page",
isBot,
},
};
}

View File

@@ -1,22 +1,20 @@
import LoginComponent from "@/components/login";
import {parse} from "next-useragent";
import {WithoutAuthMiddleware} from "@witel/webapp-builder";
import {globalServerProps} from "@/core/utils/globalServerProps";
export default function Login() {
return (
<WithoutAuthMiddleware defaultUrl={'/'}>
<WithoutAuthMiddleware defaultUrl={'/dashboard'}>
<LoginComponent/>
</WithoutAuthMiddleware>
);
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
...await globalServerProps({req, locale}),
title: "Titles.title_login_page",
isBot,
},
};
}

View File

@@ -1,22 +0,0 @@
import RegisterComponent from "@/components/register";
import {parse} from "next-useragent";
import {WithoutAuthMiddleware} from "@witel/webapp-builder";
export default function Register() {
return (
<WithoutAuthMiddleware defaultUrl={'/'}>
<RegisterComponent/>
</WithoutAuthMiddleware>
);
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Titles.title_register_page",
isBot,
},
};
}

View File

@@ -1,22 +0,0 @@
import NavyComponent from "@/components/register/navy";
import {parse} from "next-useragent";
import {WithoutAuthMiddleware} from "@witel/webapp-builder";
export default function Register() {
return (
<WithoutAuthMiddleware>
<NavyComponent/>
</WithoutAuthMiddleware>
);
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Titles.title_register_navy_page",
isBot,
},
};
}

View File

@@ -1,21 +0,0 @@
import WithoutAuthMiddleware from "@/middlewares/WithoutAuth";
import {parse} from "next-useragent";
export default function Register() {
return (
<WithoutAuthMiddleware>
{/*<WelfareServicesComponent/>*/}
</WithoutAuthMiddleware>
);
}
export async function getServerSideProps({req, locale}) {
const {isBot} = parse(req.headers["user-agent"]);
return {
props: {
messages: (await import(`&/locales/${locale}/app.json`)).default,
title: "Titles.title_register_welfare_services_page",
isBot,
},
};
}