CFE-1 create project from the tamplate project and config project

This commit is contained in:
AmirHossein Mahmoodi
2023-09-11 11:42:24 +03:30
parent a95709a583
commit 45c9fd74ef
151 changed files with 5459 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
import CenterLayout from "@/layouts/CenterLayout";
import DashboardLayouts from "@/layouts/dashboardLayouts";
import {Button, Container, Paper, Stack, Typography,} from "@mui/material";
import {Formik} from "formik";
import * as Yup from "yup";
import {useTranslations} from "next-intl";
import PasswordField from "@/core/components/PasswordField";
import StyledForm from "@/core/components/StyledForm";
import {SET_USER_PASSWORD} from "@/core/data/apiRoutes";
import SvgChangePassword from "@/core/components/svgs/SvgChangePassword";
import useRequest from "@/lib/app/hooks/useRequest";
const DashboardChangePasswordComponent = () => {
const t = useTranslations();
const requestServer = useRequest({auth: true})
const handleSubmit = (values, {setSubmitting, resetForm}) => {
requestServer(SET_USER_PASSWORD, 'post', {
data: {
current_password: values.current_password,
new_password: values.new_password,
new_password_confirmation: values.new_password_confirmation,
},
}).then((response) => {
resetForm();
}).catch(() => {
}).finally(() => {
setSubmitting(false);
});
};
const initialValues = {
current_password: "",
new_password: "",
new_password_confirmation: "",
};
const validationSchema = Yup.object().shape({
current_password: Yup.string().required(
t("ChangePassword.error_message_required")
),
new_password: Yup.string()
.min(8, t("ChangePassword.error_message_password_length"))
.required(t("ChangePassword.error_message_required")),
new_password_confirmation: Yup.string()
.required(t("ChangePassword.error_message_required"))
.test(
t("ChangePassword.error_message_password_match"),
t("ChangePassword.error_message_password_not_match"),
function (value) {
return this.parent.new_password === value;
}
),
});
return (
<DashboardLayouts>
<CenterLayout>
<Container maxWidth="sm">
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{(props) => (
<StyledForm
onSubmit={(e) => {
e.preventDefault();
props.handleSubmit();
}}
>
<Paper elevation={0}>
<Stack spacing={3} sx={{p: 5}} component="div">
<SvgChangePassword width={300} height={200}/>
<Typography margin={2} variant="h4" textAlign="center">
{t("ChangePassword.typography_change_password")}
</Typography>
<Stack spacing={1} component="div">
<PasswordField
name="current_password"
label={t("ChangePassword.label_current_password")}
error={
props.touched.current_password &&
props.errors.current_password
? true
: false
}
helperText={
props.touched.current_password
? props.errors.current_password
: null
}
/>
</Stack>
<Stack spacing={1} component="div">
<PasswordField
name="new_password"
label={t("ChangePassword.label_new_password")}
error={
props.touched.new_password &&
props.errors.new_password
? true
: false
}
helperText={
props.touched.new_password
? props.errors.new_password
: null
}
/>
</Stack>
<Stack spacing={1} component="div">
<PasswordField
name="new_password_confirmation"
label={t("ChangePassword.label_confirm_password")}
error={
props.touched.new_password_confirmation &&
props.errors.new_password_confirmation
? true
: false
}
helperText={
props.touched.new_password_confirmation
? props.errors.new_password_confirmation
: null
}
/>
</Stack>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
size="large"
disabled={props.isSubmitting}
>
{props.isSubmitting
? t("SubmitButton.button_while_submit")
: t("SubmitButton.button_submit")}
</Button>
</Stack>
</Paper>
</StyledForm>
)}
</Formik>
</Container>
</CenterLayout>
</DashboardLayouts>
);
};
export default DashboardChangePasswordComponent;

View File

@@ -0,0 +1,223 @@
import StyledForm from "@/core/components/StyledForm";
import CenterLayout from "@/layouts/CenterLayout";
import DashboardLayouts from "@/layouts/dashboardLayouts";
import useUser from "@/lib/app/hooks/useUser";
import {Box, Container, Grid, Paper, Stack, TextField, Typography,} from "@mui/material";
import * as Yup from "yup";
import {Field, Formik} from "formik";
import {useTranslations} from "next-intl";
import AvatarUpload from "@/core/components/AvatarUpload";
import axios from "axios";
import {UPDATE_AVATAR} from "@/core/data/apiRoutes";
import useDirection from "@/lib/app/hooks/useDirection";
import Notifications from "@/core/components/notifications";
import ImageResizer from "@/core/components/ImageConvertor";
const DashboardEditProfile = () => {
const t = useTranslations();
const {user, token, getUser, changeUser} = useUser();
const {directionApp} = useDirection();
const editAvatar = async (avatar) => {
Notifications(t);
try {
const formData = new FormData();
if (avatar != null) {
var resizedAvatar;
resizedAvatar = await ImageResizer(avatar);
formData.append("avatar", resizedAvatar);
}
await axios.post(UPDATE_AVATAR, formData, {
headers: {
authorization: `Bearer ${token}`,
"Content-Type": "multipart/form-data",
},
});
} catch (error) {
Notifications(t, error.response);
throw error;
}
};
const handleSubmit = (values, {setSubmitting}) => {
};
const initialValues = {
expert_avatar: null,
username: user.username,
name: user.name,
email: user.email,
province_name: user.province_name,
position: user.position,
};
const validationSchema = Yup.object().shape({});
return (
<DashboardLayouts>
<CenterLayout>
<Container maxWidth="sm">
<Formik
initialValues={initialValues}
onSubmit={handleSubmit}
validationSchema={validationSchema}
>
{(props) => (
<StyledForm
onSubmit={(e) => {
e.preventDefault();
props.handleSubmit();
}}
>
<Paper elevation={0}>
<Stack spacing={3} sx={{p: 5}} component="div">
<Typography margin={2} variant="h4" textAlign="center">
{t("UpdateProfile.typography_edit_profile")}
</Typography>
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}
>
<AvatarUpload
user={user}
setFieldValue={props.setFieldValue}
valueAvatar="expert_avatar"
changeFlag="change_avatar"
/>
</Box>
<Grid container spacing={2} sx={{pb: 2}}>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="username"
label={t("UpdateProfile.text_field_username")}
variant="outlined"
margin="normal"
size="small"
disabled={true}
error={
props.touched.username && props.errors.username
? true
: false
}
helperText={
props.touched.username
? props.errors.username
: null
}
sx={{
width: "100%",
}}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="name"
label={t("UpdateProfile.text_field_name")}
variant="outlined"
margin="normal"
size="small"
disabled={true}
error={
props.touched.name && props.errors.name
? true
: false
}
helperText={
props.touched.name ? props.errors.name : null
}
sx={{
width: "100%",
}}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="email"
label={t("UpdateProfile.text_field_email")}
variant="outlined"
margin="normal"
size="small"
disabled={true}
error={
props.touched.email && props.errors.email
? true
: false
}
helperText={
props.touched.email ? props.errors.email : null
}
sx={{
width: "100%",
}}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="province_name"
label={t("UpdateProfile.text_field_province_name")}
variant="outlined"
margin="normal"
size="small"
disabled={true}
error={
props.touched.province_name &&
props.errors.province_name
? true
: false
}
helperText={
props.touched.province_name
? props.errors.province_name
: null
}
sx={{
width: "100%",
}}
/>
</Grid>
<Grid item xs={12} sm={6}>
<Field
as={TextField}
name="position"
label={t("UpdateProfile.text_field_position")}
variant="outlined"
margin="normal"
size="small"
disabled={true}
error={
props.touched.position && props.errors.position
? true
: false
}
helperText={
props.touched.position
? props.errors.position
: null
}
sx={{
width: "100%",
}}
/>
</Grid>
</Grid>
</Stack>
</Paper>
</StyledForm>
)}
</Formik>
</Container>
</CenterLayout>
</DashboardLayouts>
);
};
export default DashboardEditProfile;

View File

@@ -0,0 +1,7 @@
import DashboardLayouts from "@/layouts/dashboardLayouts";
const DashboardFirstComponent = () => {
return <DashboardLayouts></DashboardLayouts>;
};
export default DashboardFirstComponent;

View File

@@ -0,0 +1,37 @@
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import {Button, Typography} from "@mui/material";
import {NextLinkComposed} from "@/core/components/LinkRouting";
import {useTranslations} from "next-intl";
import TitlePage from "@/core/components/TitlePage";
import Svg403 from "@/core/components/svgs/Svg403";
const UnAuthorizedComponent = () => {
const t = useTranslations();
return (
<>
<TitlePage text="Titles.title_custom_403"/>
<FullPageLayout sx={{p: 1}}>
<CenterLayout spacing={3}>
<Svg403 width={300} height={200}/>
<Typography margin={2} variant="h6" textAlign="center">
{t("ErrorPage.custom_403")}
</Typography>
<Button
variant="contained"
component={NextLinkComposed}
to={{
pathname: "/",
}}
>
{t("ErrorPage.link_routing_back_to")}{" "}
{t("ErrorPage.link_routing_main_page")}
</Button>
</CenterLayout>
</FullPageLayout>
</>
);
};
export default UnAuthorizedComponent;

View File

@@ -0,0 +1,37 @@
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import {Button, Typography} from "@mui/material";
import {NextLinkComposed} from "@/core/components/LinkRouting";
import {useTranslations} from "next-intl";
import TitlePage from "@/core/components/TitlePage";
import Svg404 from "@/core/components/svgs/Svg404";
const NotFoundComponent = () => {
const t = useTranslations();
return (
<>
<TitlePage text="Titles.title_custom_404"/>
<FullPageLayout sx={{p: 1}}>
<CenterLayout spacing={3}>
<Svg404 width={300} height={200}/>
<Typography margin={2} variant="h6" textAlign="center">
{t("ErrorPage.custom_404")}
</Typography>
<Button
variant="contained"
component={NextLinkComposed}
to={{
pathname: "/",
}}
>
{t("ErrorPage.link_routing_back_to")}{" "}
{t("ErrorPage.link_routing_main_page")}
</Button>
</CenterLayout>
</FullPageLayout>
</>
);
};
export default NotFoundComponent;

View File

@@ -0,0 +1,48 @@
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import {Box, Button, Container, Stack, Typography} from "@mui/material";
import {NextLinkComposed} from "@/core/components/LinkRouting";
import {useTranslations} from "next-intl";
import Image from "next/image";
import TitlePage from "@/core/components/TitlePage";
const ServerErrorComponent = () => {
const t = useTranslations();
return (
<>
<TitlePage text="Titles.title_custom_500"/>
<FullPageLayout sx={{p: 1}}>
<CenterLayout>
<Container maxWidth="sm">
<Stack spacing={4} sx={{p: 4}}>
<Box sx={{position: "relative", width: "100%", height: 200}}>
<Image
fill
src="/images/500.svg"
alt={t("app_name")}
priority
/>
</Box>
<Typography margin={2} variant="h6" textAlign="center">
{t("ErrorPage.custom_500")}
</Typography>
<Button
variant="contained"
component={NextLinkComposed}
to={{
pathname: "/",
}}
>
{t("ErrorPage.link_routing_back_to")}{" "}
{t("ErrorPage.link_routing_main_page")}
</Button>
</Stack>
</Container>
</CenterLayout>
</FullPageLayout>
</>
);
};
export default ServerErrorComponent;

View File

@@ -0,0 +1,55 @@
import {NextLinkComposed} from "@/core/components/LinkRouting";
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import useUser from "@/lib/app/hooks/useUser";
import {Button, Stack, Typography} from "@mui/material";
import {useTranslations} from "next-intl";
import SvgDashboard from "@/core/components/svgs/SvgDashboard";
const FirstComponent = () => {
const t = useTranslations();
const {isAuth} = useUser();
return (
<FullPageLayout sx={{p: 1}}>
<CenterLayout spacing={3}>
<SvgDashboard width={300} height={200}/>
<Typography variant="h5" sx={{textAlign: "center"}}>
{t("app_name")}
</Typography>
{isAuth ? (
<Button
variant="outlined"
component={NextLinkComposed}
to={{
pathname: "/dashboard",
}}
>
{t("dashboard")}
</Button>
) : (
<Button
sx={{mx: 2}}
variant="contained"
component={NextLinkComposed}
to={{
pathname: "/login-expert",
}}
>
{t("login_expert")}
</Button>
)}
</CenterLayout>
<Stack direction="row" alignItems="center" justifyContent="center">
<Typography variant={"caption"}
sx={{
color: 'primary.main',
fontFamily: 'Arial',
fontWeight: 'bold'
}}>v{process.env.NEXT_PUBLIC_API_VERSION}</Typography>
</Stack>
</FullPageLayout>
);
};
export default FirstComponent;

View File

@@ -0,0 +1,153 @@
import LinkRouting from "@/core/components/LinkRouting";
import PasswordField from "@/core/components/PasswordField";
import StyledForm from "@/core/components/StyledForm";
import {GET_USER_TOKEN} from "@/core/data/apiRoutes";
import CenterLayout from "@/layouts/CenterLayout";
import FullPageLayout from "@/layouts/FullPageLayout";
import useUser from "@/lib/app/hooks/useUser";
import LoginIcon from "@mui/icons-material/Login";
import {Box, 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 useDirection from "@/lib/app/hooks/useDirection";
import SvgLogin from "@/core/components/svgs/SvgLogin";
import useRequest from "@/lib/app/hooks/useRequest";
const LoginComponent = () => {
const t = useTranslations();
const {directionApp} = useDirection(); // should delete because we don't have direction anymore
const {setToken} = useUser(); // pass token to set token
const requestServer = useRequest()
// getting url query
const searchParams = useSearchParams();
const backUrlDecodedPath = searchParams.get("back_url");
//formik properties
const handleSubmit = (values, props) => {
requestServer(GET_USER_TOKEN, 'post', {
data: {
username: values.username,
password: values.password,
},
success: {
notification: {show: false}
}
}).then((response) => {
setToken(response.data.token)
}).catch(() => {
props.setSubmitting(false)
})
};
const initialValues = {
username: "",
password: "",
};
const validationSchema = Yup.object().shape({
username: Yup.string().required(t("LoginPage.error_message_required")),
password: Yup.string().required(t("LoginPage.error_message_required")),
});
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("login_expert")}
</Typography>
<StyledForm sx={{width: "100%"}}>
<Stack spacing={3} sx={{p: 2}}>
<Field
as={TextField}
name="username"
variant="outlined"
label={t("LoginPage.text_field_user_name")}
placeholder={t(
"LoginPage.text_field_enter_your_username"
)}
type={"text"}
error={
props.touched.username && props.errors.username
? true
: false
}
fullWidth
helperText={
props.touched.username ? props.errors.username : null
}
/>
<PasswordField
name="password"
label={t("LoginPage.text_field_password")}
error={
props.touched.password && props.errors.password
? true
: false
}
helperText={
props.touched.password ? props.errors.password : null
}
placeholder={t(
"LoginPage.text_field_enter_your_password"
)}
/>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
}}
>
<Button
type="submit"
variant="contained"
fullWidth
size="medium"
endIcon={<LoginIcon/>}
disabled={props.isSubmitting}
>
{t("LoginPage.button_submit")}
</Button>
</Box>
</Stack>
</StyledForm>
</Stack>
)}
</Formik>
</Paper>
</Container>
</CenterLayout>
<Stack direction="row" alignItems="center" justifyContent="center">
<LinkRouting
sx={{margin: 2}}
href={
backUrlDecodedPath ? decodeURIComponent(backUrlDecodedPath) : "/"
}
>
{t("LoginPage.link_routing_back_to")}{" "}
{backUrlDecodedPath
? t("LoginPage.link_routing_previuos_page")
: t("LoginPage.link_routing_main_page")}
</LinkRouting>
</Stack>
</FullPageLayout>
);
};
export default LoginComponent;