Merge branch 'feature/TF-94_upload_system' into 'develop'

TF-94 Implementation of File Uploader Component

See merge request witel3/loan-facilities-user!25
This commit is contained in:
AmirHossein Mahmoodi
2023-09-03 13:08:46 +00:00
14 changed files with 95 additions and 141 deletions

View File

@@ -2,6 +2,9 @@
const nextConfig = {
reactStrictMode: true,
images: {
domains: ['loan.witel.ir', /* other domains */],
},
i18n: {
defaultLocale: 'fa',
locales: ['fa'],

View File

@@ -1,66 +1,37 @@
import DashboardLayouts from "@/layouts/dashboardLayouts";
import useUser from "@/lib/app/hooks/useUser";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import {
Avatar,
Card,
CardActions,
CardContent,
CardHeader,
Collapse,
Grid,
IconButton,
Stack,
Typography
} from "@mui/material";
import {styled} from "@mui/material/styles";
import {useTranslations} from "next-intl";
import {useState} from "react";
const ExpandMore = styled((props) => {
const {expand, ...other} = props;
return <IconButton {...other} />;
})(({theme, expand}) => ({
transform: !expand ? "rotate(0deg)" : "rotate(180deg)",
marginLeft: "auto",
transition: theme.transitions.create("transform", {
duration: theme.transitions.duration.shortest,
}),
}));
const data = [
{
name: "جان دو",
date: "۱۳۹۹/۰۴/۲۵",
description:
"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.",
},
{
name: "جین اسمیت",
date: "۱۳۹۹/۰۴/۲۶",
description: "نُلا ویته الیت لیبرو آ، آ فارِترا آوگوه.",
},
{
name: "مایک جانسون",
date: "۱۳۹۹/۰۴/۲۷",
description:
"دوئیس مولیس، است نُن کُمُدو لُکتوس، نیسی ارات پورتیتور لیگولا.",
},
];
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";
const LoanFollowUpComponent = () => {
const t = useTranslations();
const {token} = useUser();
const [expanded, setExpanded] = useState([]);
const handleExpandClick = (index) => {
setExpanded((prevExpanded) => {
const newExpanded = [...prevExpanded];
newExpanded[index] = !newExpanded[index];
return newExpanded;
});
};
const requestServer = useRequest();
const {setLoadingPage} = useLoading();
const [requestsList, setRequestsList] = useState([]);
// get form data
useEffect(() => {
setLoadingPage(true)
requestServer(SHOW_LOAN_REQUEST_NAVGAN, "get", {auth: true, notification: false})
.then(function ({data}) {
const items = data.data;
const formattedData = items.map((item, index) => ({
id: item.id,
latest_history_created_at: moment(item.latest_history_created_at).locale("fa").format("HH:mm | YYYY/MM/DD"),
state_id: item.state_id,
loan_state: item.loan_state,
}));
setRequestsList(formattedData);
setLoadingPage(false)
})
.catch(function (error) {
})
}, []);
return (
<DashboardLayouts>
@@ -77,42 +48,8 @@ const LoanFollowUpComponent = () => {
rowSpacing={2}
sx={{alignItems: "start", justifyContent: "center"}}
>
{data.map((item, index) => (
<Grid item xs={12} md={6} lg={4} key={index}>
<Card sx={{width: "100%"}}>
<CardHeader
avatar={
<Avatar
sx={{bgcolor: "primary.main"}}
aria-label="recipe"
></Avatar>
}
title={item.name}
subheader={item.date}
/>
<CardContent>
<Typography variant="body2" color="text.secondary">
متن تست
</Typography>
</CardContent>
<CardActions disableSpacing>
<ExpandMore
expand={expanded[index]}
onClick={() => handleExpandClick(index)}
aria-expanded={expanded[index]}
aria-label="show more"
>
<ExpandMoreIcon/>
</ExpandMore>
</CardActions>
<Collapse in={expanded[index]} timeout="auto" unmountOnExit>
<CardContent>
<Typography paragraph>اطلاعات تکمیلی:</Typography>
<Typography paragraph>{item.description}</Typography>
</CardContent>
</Collapse>
</Card>
</Grid>
{requestsList.map((item, index) => (
<RequestCard item={item} key={item.id}/>
))}
</Grid>
</Stack>

View File

@@ -69,7 +69,7 @@ const AddFormComponent = () => {
shenasname_image: Yup.mixed().required(t("LoanRequest.error_message_shenasname_image")),
payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
const formData = new FormData();
formData.append("name", values.name);
formData.append("phone_number", values.phone_number);

View File

@@ -63,8 +63,9 @@ const EditFormComponent = () => {
}
setInitialValues(formattedData);
setLoadingPage(false)
}).catch(() => {
})
})
.catch(() => {
})
}, [provinceList]);
// validation and request action of form
@@ -84,7 +85,7 @@ const EditFormComponent = () => {
payan_khedmat_image: Yup.mixed().required(t("LoanRequest.error_message_payan_khedmat_image")),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
const formData = new FormData();
formData.append("name", values.name);
formData.append("phone_number", values.phone_number);

View File

@@ -34,7 +34,7 @@ const SendTokenComponent = ({
),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
requestServer(LOGIN, "post", {
auth: false, data: {
phone_number: values.phone_number,
@@ -130,6 +130,7 @@ const SendTokenComponent = ({
timer={timer}
setTimer={setTimer}
PhoneNumber={PhoneNumber}
disabled={props.isSubmitting}
/>
</Stack>
</StyledForm>

View File

@@ -33,7 +33,7 @@ const SendUserDataComponent = ({
phone_number: Yup.string().required(t("LoginPage.error_message_phone_number")),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
requestServer(SEND_OTP_TOKEN, "post", {
auth: false, data: {
phone_number: values.phone_number,
@@ -101,7 +101,7 @@ const SendUserDataComponent = ({
<LinkRouting href={"/register"}>
<Button
fullWidth
type="submit"
type="button"
variant="outlined"
size="large"
endIcon={<PersonAddIcon/>}

View File

@@ -34,7 +34,7 @@ const RequestOtpComponent = ({
),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
requestServer(SEND_OTP_TOKEN, "post", {
auth: false, data: {
phone_number: values.phone_number,

View File

@@ -42,7 +42,7 @@ const UserRegisterComponent = ({
navgan_id: Yup.string().required(t("RegisterPage.error_message_navgan_id")),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
requestServer(REGISTER, "post", {
auth: false, data: {
type_id: values.type_id,

View File

@@ -40,7 +40,7 @@ const UserRegisterComponent = ({
),
});
const handleSubmit = async (values, props) => {
const handleSubmit = (values, props) => {
requestServer(REGISTER, "post", {
auth: false, data: {
type_id: values.type_id,
@@ -125,6 +125,7 @@ const UserRegisterComponent = ({
timer={timer}
setTimer={setTimer}
PhoneNumber={PhoneNumber}
disabled={props.isSubmitting}
/>
<Divider>
<Chip label={t("RegisterPage.complete_information")}/>

View File

@@ -4,12 +4,13 @@ import {Button} from "@mui/material";
import axios from "axios";
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 useRequest from "@/lib/app/hooks/useRequest";
const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber}) => {
const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber, disabled}) => {
const t = useTranslations();
const {directionApp} = useDirection();
const requestServer = useRequest();
// Countdown Timer
useEffect(() => {
let interval;
@@ -26,21 +27,17 @@ const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber}) => {
// End Countdown Timer
// Handle Resend Token
const handleResendClick = async () => {
// work on it
const handleResendClick = () => {
if (timer != 0) return;
Notifications(t, undefined);
await axios
.post(SEND_OTP_TOKEN, {
requestServer(SEND_OTP_TOKEN, "post", {
auth: false, data: {
phone_number: PhoneNumber,
})
}
})
.then(function (response) {
Notifications(t, response);
setTimer(initialTimerValue);
})
.catch(function (error) {
Notifications(t, error.response);
});
}).catch(function (error) {
});
};
// End Handle Resend Token
@@ -60,6 +57,7 @@ const ResendToken = ({initialTimerValue, timer, setTimer, PhoneNumber}) => {
<Button
color="success"
sx={{width: "120px", alignSelf: "center", mt: 0}}
disabled={disabled}
onClick={handleResendClick}
>
{t("resend_code")}

View File

@@ -16,7 +16,6 @@ const UploadSystem = ({
}) => {
const t = useTranslations();
const fileInputRef = useRef(null);
const [selectedImage, setSelectedImage] = useState(default_image || "/images/upload-image.svg");
const [fileType, setFileType] = useState(null);
const [fileName, setFileName] = useState("");
@@ -39,16 +38,12 @@ const UploadSystem = ({
border: "1px dashed #d32f2f",
borderRadius: "5px",
padding: "5px",
width: '200px',
height: '200px'
} : {
cursor: "pointer",
objectFit: "contain",
border: "1px dashed #e1e1e1",
borderRadius: "5px",
padding: "5px",
width: '200px',
height: '200px'
}
const handleClick = () => {
@@ -72,13 +67,16 @@ const UploadSystem = ({
>
{label}
</Typography>
{selectedImage === "/images/upload-image.svg" ? (
<Box sx={{position: "relative"}}>
</Box>
{selectedImage === "/images/upload-image.svg" || selectedImage === default_image ? (
<Image
src={selectedImage}
priority
alt={imageAlt}
width={0}
height={0}
width={200}
height={200}
onClick={handleClick}
style={uploadBoxStyle}
/>
@@ -87,8 +85,8 @@ const UploadSystem = ({
src={selectedImage}
priority
alt={imageAlt}
width={0}
height={0}
width={200}
height={200}
onClick={handleClick}
style={uploadBoxStyle}
/>

View File

@@ -7,6 +7,7 @@ export const SEND_OTP_TOKEN = BASE_URL + "/otp";
export const REGISTER = BASE_URL + "/register";
export const USER_INFO = BASE_URL + "/profile/info";
export const SEND_LOAN_REQUEST_NAVGAN = BASE_URL + "/navgan/loan/store";
export const SHOW_LOAN_REQUEST_NAVGAN = BASE_URL + "/navgan/loan/index"
export const SHOW_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/index";
export const SEND_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/store";
export const UPDATE_LOAN_REQUEST_WELFARE = BASE_URL + "/refahi/loan/update/";

View File

@@ -11,6 +11,7 @@ const sidebarMenu = [
icon: <SpaceDashboardIcon/>,
userType: 0,
selected: false,
permission_name: "all"
},
{
key: "sidebar.add-request-loan",
@@ -19,6 +20,7 @@ const sidebarMenu = [
icon: <DataSaverOnIcon/>,
userType: 1,
selected: false,
permission_name: "can_request_a_new_loan"
},
{
key: "sidebar.followUp-loan",
@@ -27,6 +29,7 @@ const sidebarMenu = [
icon: <BookmarkAddedIcon/>,
userType: 1,
selected: false,
permission_name: "all"
},
{
key: "sidebar.add-request-loan",
@@ -35,6 +38,7 @@ const sidebarMenu = [
icon: <DataSaverOnIcon/>,
userType: 2,
selected: false,
permission_name: "can_request_a_new_loan"
},
{
key: "sidebar.followUp-loan",
@@ -43,6 +47,7 @@ const sidebarMenu = [
icon: <BookmarkAddedIcon/>,
userType: 2,
selected: false,
permission_name: "all"
},
],
];

View File

@@ -41,20 +41,29 @@ export default function SidebarList({handleDrawerToggle}) {
return (
<List>
{itemMenu.map((itemArr, index) => (
<Fragment key={index}>
{itemArr.map((item) =>
(item.userType === user.type_id || item.userType === 0) ? (
<SidebarListItem
item={item}
dispatch={dispatch}
key={item.key}
handleDrawerToggle={handleDrawerToggle}
/>
) : null
)}
<Divider/>
</Fragment>
))}
<Fragment key={index}>
{itemArr.map((item) => {
if (
(item.userType === user.type_id || item.userType === 0) &&
(user[item.permission_name] || item.permission_name === "all")
) {
return (
<SidebarListItem
item={item}
dispatch={dispatch}
key={item.key}
handleDrawerToggle={handleDrawerToggle}
/>
);
} else {
return null;
}
})}
<Divider/>
</Fragment>
)
)}
</List>
);
)
;
}