英文姓名
diff --git a/src/pages/extra-pages/LoadingComponent.js b/src/pages/extra-pages/LoadingComponent.js
new file mode 100644
index 0000000..f5b30c3
--- /dev/null
+++ b/src/pages/extra-pages/LoadingComponent.js
@@ -0,0 +1,17 @@
+import {Box, CircularProgress, Grid} from "@mui/material";
+
+const LoadingComponent = () => {
+ return (
+
+
+
+
+
+ )
+}
+export default LoadingComponent;
diff --git a/src/pages/extra-pages/LogoutPage.js b/src/pages/extra-pages/LogoutPage.js
new file mode 100644
index 0000000..4c30923
--- /dev/null
+++ b/src/pages/extra-pages/LogoutPage.js
@@ -0,0 +1,27 @@
+// material-ui
+import {
+ Grid
+} from '@mui/material';
+import {useEffect} from "react";
+import {handleLogoutFunction} from "../../auth";
+import {useDispatch} from "react-redux";
+import {useNavigate} from "react-router-dom";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const LogoutPage = () => {
+ const dispatch = useDispatch()
+ const navigate = useNavigate()
+
+ useEffect(() =>{
+ dispatch(handleLogoutFunction());
+ navigate('/login');
+ },[])
+
+ return (
+
+
+ );
+};
+
+export default LogoutPage;
diff --git a/src/pages/pnspsPasswordPolicyPage/index.js b/src/pages/pnspsPasswordPolicyPage/index.js
new file mode 100644
index 0000000..a2683bd
--- /dev/null
+++ b/src/pages/pnspsPasswordPolicyPage/index.js
@@ -0,0 +1,292 @@
+// material-ui
+import {
+ Button,
+ CardContent, Divider, FormControlLabel,
+ Grid, InputAdornment, Switch, TextField
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import {useForm} from "react-hook-form";
+import {useState} from "react";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const PasswordPolicyPage = () => {
+
+ const { reset, register, handleSubmit } = useForm()
+ const [aNonA, setANonA] = useState(false);
+ const [needSpecialCharacter, setNeedSpecialCharacter] = useState(false);
+ const [noUsernameAsPart, setNoUsernameAsPart] = useState(false);
+ const [noIdenticalChar, setNoIdenticalChar] = useState(false);
+
+ const onSubmit = (data) => {
+ console.log(data);
+ console.log(aNonA)
+ };
+
+ function resetForm(){
+ setANonA(false);
+ reset();
+ }
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default PasswordPolicyPage;
diff --git a/src/pages/pnspsSettingPage/index.js b/src/pages/pnspsSettingPage/index.js
new file mode 100644
index 0000000..4362224
--- /dev/null
+++ b/src/pages/pnspsSettingPage/index.js
@@ -0,0 +1,177 @@
+// material-ui
+import {
+ Button,
+ CardContent, Divider,
+ Grid, InputAdornment, TextField
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import {useForm} from "react-hook-form";
+import Radio from '@mui/material/Radio';
+import RadioGroup from '@mui/material/RadioGroup';
+import FormControlLabel from '@mui/material/FormControlLabel';
+import FormControl from '@mui/material/FormControl';
+import {useState} from "react";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const SettingPage = () => {
+
+ const [notificationType, setNotificationType] = useState(null);
+
+ const { reset, register, handleSubmit } = useForm()
+ const onSubmit = (data) => {
+ console.log(data);
+ console.log(notificationType);
+ };
+
+ function resetForm(){
+ setNotificationType(null);
+ reset();
+ }
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default SettingPage;
diff --git a/src/pages/pnspsUserDetailPage/UserAuthTable.js b/src/pages/pnspsUserDetailPage/UserAuthTable.js
new file mode 100644
index 0000000..bb4592d
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/UserAuthTable.js
@@ -0,0 +1,80 @@
+// material-ui
+import {
+ DataGrid,
+} from "@mui/x-data-grid";
+import {useEffect, useState} from "react";
+import axios from "axios";
+import {apiPath} from "../../auth/utils";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+import * as React from "react";
+import {GET_AUTH_LIST} from "../../utils/ApiPathConst";
+
+// ==============================|| EVENT TABLE ||============================== //
+
+export default function UserAuthTable({setSelectedRow, userAuth}) {
+ const [authData, setAuthData] = useState([]);
+ const [onReady, setOnReady] = useState(false);
+ const [currentSelectedRow, setCurrentSelectedRow] = useState(userAuth);
+
+ useEffect(() => {
+ axios.get(`${apiPath}${GET_AUTH_LIST}`)
+ .then((response) => {
+ if (response.status === 200) {
+ setAuthData(response.data.records);
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
+ }, []);
+
+ useEffect(() => {
+ //if state data are ready and assign to different field
+ if (authData.length > 0) {
+ setOnReady(true);
+ }
+ }, [authData]);
+
+ const columns = [
+ {
+ id: 'module',
+ field: 'module',
+ headerName: 'Module',
+ flex: 1,
+ },
+ {
+ id: 'authority',
+ field: 'name',
+ headerName: 'Authority',
+ flex: 2,
+ },
+ ];
+
+ return (
+ !onReady ?
+
+ :
+
+ {
+ console.log(ids);
+ setSelectedRow(ids);
+ setCurrentSelectedRow(ids);
+ }}
+ autoHeight
+ />
+
+ );
+}
diff --git a/src/pages/pnspsUserDetailPage/UserAuthorityCard.js b/src/pages/pnspsUserDetailPage/UserAuthorityCard.js
new file mode 100644
index 0000000..cf1c83d
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/UserAuthorityCard.js
@@ -0,0 +1,60 @@
+// material-ui
+import {
+ Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import * as React from "react";
+import {useEffect, useState} from "react";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+import UserAuthTable from "./UserAuthTable";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+const UserAuthorityCard = ({isCollectData, updateUserAuthList,userData}) => {
+ const [currentAuthData, setCurrentAuthData] = React.useState({});
+ const [onReady, setOnReady] = useState(false);
+ const [selectedRow, setSelectedRow] = useState([]);
+
+ useEffect(() => {
+ //if user data from parent are not null
+ if (Object.keys(userData).length > 0 && userData !== undefined) {
+ setCurrentAuthData(userData.data);
+ setSelectedRow(userData.authIds);
+ }
+ }, [userData]);
+
+ useEffect(() => {
+ //if state data are ready and assign to different field
+ if (Object.keys(userData).length > 0 && currentAuthData !== undefined) {
+ setOnReady(true);
+ }
+ }, [currentAuthData]);
+
+ useEffect(() => {
+ //upload latest data to parent
+ updateUserAuthList(selectedRow);
+ }, [isCollectData]);
+
+
+ return (
+ !onReady ?
+
+ :
+
+
+ User Authority
+
+
+
+
+ );
+};
+
+export default UserAuthorityCard;
diff --git a/src/pages/pnspsUserDetailPage/UserGroupCard.js b/src/pages/pnspsUserDetailPage/UserGroupCard.js
new file mode 100644
index 0000000..b85343b
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/UserGroupCard.js
@@ -0,0 +1,59 @@
+// material-ui
+import {
+ Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import * as React from "react";
+import {useEffect, useState} from "react";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+import UserGroupTable from "./UserGroupTable";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+const UserGroupCard = ({isCollectData, updateUserGroupList,userData}) => {
+ const [currentUserData, setCurrentUserData] = React.useState({});
+ const [onReady, setOnReady] = useState(false);
+ const [selectedRow, setSelectedRow] = useState([]);
+
+ useEffect(() => {
+ //if user data from parent are not null
+ if (Object.keys(userData).length > 0 && userData !== undefined) {
+ setCurrentUserData(userData.data);
+ setSelectedRow(userData.groupIds);
+ }
+ }, [userData]);
+
+ useEffect(() => {
+ //if state data are ready and assign to different field
+ if (Object.keys(userData).length > 0 &¤tUserData !== undefined) {
+ setOnReady(true);
+ }
+ }, [currentUserData]);
+
+ useEffect(() => {
+ //upload latest data to parent
+ updateUserGroupList(selectedRow);
+ }, [isCollectData]);
+
+
+ return (
+ !onReady ?
+
+ :
+
+
+ Group(s)
+
+
+
+ );
+};
+
+export default UserGroupCard;
diff --git a/src/pages/pnspsUserDetailPage/UserGroupTable.js b/src/pages/pnspsUserDetailPage/UserGroupTable.js
new file mode 100644
index 0000000..12090f0
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/UserGroupTable.js
@@ -0,0 +1,76 @@
+// material-ui
+import {
+ DataGrid,
+} from "@mui/x-data-grid";
+import {useEffect, useState} from "react";
+import axios from "axios";
+import {apiPath} from "../../auth/utils";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+import * as React from "react";
+import {GET_GROUP_COMBO_PATH} from "../../utils/ApiPathConst";
+
+// ==============================|| EVENT TABLE ||============================== //
+
+export default function UserGroupTable({setSelectedRow, userGroup}) {
+ const [groupData, setGroupData] = useState([]);
+ const [onReady, setOnReady] = useState(false);
+ const [currentSelectedRow, setCurrentSelectedRow] = useState(userGroup);
+
+ useEffect(() => {
+ axios.get(`${apiPath}${GET_GROUP_COMBO_PATH}`)
+ .then((response) => {
+ if (response.status === 200) {
+ setGroupData(response.data.records);
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
+ }, []);
+
+ useEffect(() => {
+ //if state data are ready and assign to different field
+ console.log(groupData.length)
+ if (groupData !== "" && groupData !== undefined) {
+ setOnReady(true);
+ }
+ }, [groupData]);
+
+ const columns = [
+ {
+ id: 'group',
+ field: 'name',
+ headerName: 'Group',
+ flex: 1,
+ editable: true,
+ },
+ ];
+
+ return (
+ !onReady ?
+
+ :
+
+ {
+ console.log(ids);
+ setSelectedRow(ids);
+ setCurrentSelectedRow(ids);
+ }}
+ autoHeight
+ />
+
+ );
+}
diff --git a/src/pages/pnspsUserDetailPage/UserInformationCard.js b/src/pages/pnspsUserDetailPage/UserInformationCard.js
new file mode 100644
index 0000000..59ede65
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/UserInformationCard.js
@@ -0,0 +1,321 @@
+// material-ui
+import {
+ Grid, TextField, Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import * as React from "react";
+import {useForm} from "react-hook-form";
+import Autocomplete from "@mui/material/Autocomplete";
+import {
+ subDivision1,
+ subDivision2,
+ subDivision3,
+ subDivision4,
+ subDivision5,
+ subDivision6
+} from "../pnspsUserSettingPage/DummyComboRecord";
+import {useEffect, useState} from "react";
+import Checkbox from "@mui/material/Checkbox";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+//import {useParams} from "react-router-dom";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+const subDivisionArray = [
+ ...subDivision1,
+ ...subDivision2,
+ ...subDivision3,
+ ...subDivision4,
+ ...subDivision5,
+ ...subDivision6
+];
+
+
+const UserInformationCard = ({isCollectData, updateUserObject,userData}) => {
+ //const params = useParams();
+ const [currentUserData, setCurrentUserData] = React.useState({});
+ const [subDivision, setSubDivision] = useState(null);
+ const [locked, setLocked] = useState(false);
+ const [isLotusNoteUser, setIsLotusNoteUser] = useState(false);
+ const [lotusNoteUserList, setLotusNoteUserList] = useState([])
+ const [selectedLotusUser, setSelectedLotusUser] = useState(null);
+
+ const [onReady, setOnReady] = useState(false);
+ const {register, getValues} = useForm()
+
+ useEffect(() => {
+ //TODO: Get lotus note user list
+ setLotusNoteUserList([
+ {
+ key: 1,
+ label: "user01",
+ account: "user123456"
+ },
+ {
+ key: 2,
+ label: "user02",
+ account: "userabcde1"
+ },
+ {
+ key: 3,
+ label: "user03",
+ account: "user2001"
+ },
+ {
+ key: 4,
+ label: "user04",
+ account: "user2000"
+ },
+ {
+ key: 5,
+ label: "user05",
+ account: "user1999"
+ },
+ ])
+ }, []);
+
+ useEffect(() => {
+ //if user data from parent are not null
+ if (Object.keys(userData).length > 0 && userData !== undefined) {
+ setCurrentUserData(userData.data);
+ }
+ }, [userData]);
+
+ useEffect(() => {
+ //if state data are ready and assign to different field
+ if (Object.keys(userData).length > 0 &¤tUserData !== undefined) {
+ setLocked(currentUserData.locked);
+ setOnReady(true);
+ }
+ }, [currentUserData]);
+
+ useEffect(() => {
+ //upload latest data to parent
+ const values = getValues();
+ const objectData ={
+ ...values,
+ selectedLotusUser: selectedLotusUser,
+ subDivision: subDivision,
+ locked: locked,
+ }
+ updateUserObject(objectData);
+ }, [isCollectData]);
+
+
+ return (
+ !onReady ?
+
+ :
+
+
+ Information
+
+
+
+
+
+ );
+};
+
+export default UserInformationCard;
diff --git a/src/pages/pnspsUserDetailPage/index.js b/src/pages/pnspsUserDetailPage/index.js
new file mode 100644
index 0000000..b6fab10
--- /dev/null
+++ b/src/pages/pnspsUserDetailPage/index.js
@@ -0,0 +1,135 @@
+// material-ui
+import {
+ Button,
+ Grid, Typography
+} from '@mui/material';
+import {useEffect, useState} from "react";
+import * as React from "react";
+import axios from "axios";
+import {apiPath} from "../../auth/utils";
+import {useParams} from "react-router-dom";
+import UserInformationCard from "./UserInformationCard";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+import UserGroupCard from "./UserGroupCard";
+import UserAuthorityCard from "./UserAuthorityCard";
+import {GET_USER_PATH} from "../../utils/ApiPathConst";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+const UserMaintainPage = () => {
+ const params = useParams();
+ const [userData, setUserData] = React.useState({});
+ const [onReady, setOnReady] = useState(false);
+ const [isCollectData, setIsCollectData] = useState(false);
+ const [editedCustomerData, setEditedCustomerData] = useState({});
+ const [userGroupData,setUserGroupData] = useState([]);
+ const [userAuthData,setUserAuthData] = useState([]);
+ const [userConfirm, setUserConfirm] = useState(false);
+
+ function updateUserObject(userData) {
+ setEditedCustomerData(userData);
+ }
+
+ function updateUserGroupList(userGroupData){
+ setUserGroupData(userGroupData);
+ }
+
+ function updateUserAuthList(userAuthData){
+ setUserAuthData(userAuthData);
+ }
+
+ const submitData = () => {
+ setUserConfirm(true);
+ setIsCollectData(!isCollectData);
+ }
+
+ useEffect(() => {
+
+ axios.get(`${apiPath}${GET_USER_PATH}/${params.id}`)
+ .then((response) => {
+ if (response.status === 200) {
+ setUserData(response.data);
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
+ }, []);
+
+ useEffect(() => {
+ setOnReady(true);
+ }, [userData]);
+
+ useEffect(() => {
+ if(userConfirm && onReady){
+ console.log("update in parents");
+ console.log(editedCustomerData);
+ console.log(userGroupData);
+ console.log(userAuthData);
+ }
+ setUserConfirm(false);
+ }, [editedCustomerData,userGroupData,userAuthData]);
+
+ return (
+ !onReady ?
+
+ :
+
+
+ Maintain User
+
+ {/*col 1*/}
+
+
+
+
+
+
+
+
+
+
+
+ {/*col 2*/}
+
+
+
+
+ {/*bottom button*/}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UserMaintainPage;
diff --git a/src/pages/pnspsUserGroupSearchPage/UserGroupSearchForm.js b/src/pages/pnspsUserGroupSearchPage/UserGroupSearchForm.js
new file mode 100644
index 0000000..6a73bab
--- /dev/null
+++ b/src/pages/pnspsUserGroupSearchPage/UserGroupSearchForm.js
@@ -0,0 +1,93 @@
+// material-ui
+import {
+ Button,
+ CardContent,
+ Grid, TextField,
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import {useForm} from "react-hook-form";
+import * as React from "react";
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const UserGroupSearchForm = ({applySearch}) => {
+
+ const { reset, register, handleSubmit } = useForm()
+ const onSubmit = (data) => {
+ console.log(data)
+ applySearch(data);
+ };
+
+ function resetForm(){
+ reset();
+ }
+
+ return (
+
+
+
+
+ );
+};
+
+export default UserGroupSearchForm;
diff --git a/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js b/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js
new file mode 100644
index 0000000..e5f8741
--- /dev/null
+++ b/src/pages/pnspsUserGroupSearchPage/UserGroupTable.js
@@ -0,0 +1,75 @@
+// material-ui
+import * as React from 'react';
+import {
+ DataGrid,
+ GridActionsCellItem,
+} from "@mui/x-data-grid";
+import EditIcon from '@mui/icons-material/Edit';
+import {useEffect} from "react";
+import {useNavigate} from "react-router-dom";
+// ==============================|| EVENT TABLE ||============================== //
+
+export default function UserGroupTable({recordList}) {
+ const [rows, setRows] = React.useState(recordList);
+ const [rowModesModel] = React.useState({});
+ const navigate = useNavigate()
+
+ useEffect(() => {
+ setRows(recordList);
+ }, [recordList]);
+
+ const handleEditClick = (id) => () => {
+ navigate('/userGroup/'+ id);
+ };
+
+ const columns = [
+ {
+ field: 'actions',
+ type: 'actions',
+ headerName: 'Actions',
+ width: 100,
+ cellClassName: 'actions',
+ getActions: ({id}) => {
+ return [
+ }
+ label="Edit"
+ className="textPrimary"
+ onClick={handleEditClick(id)}
+ color="primary"
+ />]
+ },
+ },
+ {
+ id: 'groupName',
+ field: 'groupName',
+ headerName: 'User Group Name',
+ flex: 1,
+ },
+ {
+ id: 'description',
+ field: 'description',
+ headerName: 'User Group Description',
+ flex: 1,
+ },
+ ];
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pnspsUserGroupSearchPage/index.js b/src/pages/pnspsUserGroupSearchPage/index.js
new file mode 100644
index 0000000..401fa9f
--- /dev/null
+++ b/src/pages/pnspsUserGroupSearchPage/index.js
@@ -0,0 +1,78 @@
+// material-ui
+import {
+ Grid, Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import UserGroupSearchForm from "./UserGroupSearchForm";
+import UserGroupTable from "./UserGroupTable";
+import {useEffect, useState} from "react";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+
+const UserGroupSearchPanel = () => {
+
+ const [record] = useState([]);
+ const [searchCriteria, setSearchCriteria] = useState({});
+ const [sortedRecord, setSortedRecord] = useState([]);
+
+ const filterSearchName = (array) => {
+ return array.filter((item) => item.name.toLowerCase().includes(searchCriteria.eventName));
+ };
+
+ const filterSearchType = (array) => {
+ return array.filter((item) => item.category.includes(searchCriteria.type));
+ };
+
+ function sortData(record){
+ let sortedRecord = record;
+ sortedRecord = filterSearchName(sortedRecord);
+ sortedRecord = filterSearchType(sortedRecord);
+ return sortedRecord;
+ }
+
+ function applySearch(input){
+ setSearchCriteria(input);
+ //console.log("Apply Search: ");
+ //console.log(input);
+ }
+
+ useEffect(() => {
+ //console.log(searchCriteria);
+ if(Object.keys(searchCriteria).length !== 0){
+ const tempSortedRecord = sortData(record);
+ console.log(tempSortedRecord);
+ setSortedRecord(tempSortedRecord);
+ }else{
+ setSortedRecord(record);
+ }
+ }, [searchCriteria]);
+
+ return (
+
+
+ View User Group
+
+ {/*row 1*/}
+
+
+
+ {/*row 2*/}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UserGroupSearchPanel;
diff --git a/src/pages/pnspsUserSearchPage/UserSearchForm.js b/src/pages/pnspsUserSearchPage/UserSearchForm.js
new file mode 100644
index 0000000..6d25b6f
--- /dev/null
+++ b/src/pages/pnspsUserSearchPage/UserSearchForm.js
@@ -0,0 +1,229 @@
+// material-ui
+import {
+ Button,
+ CardContent, FormControlLabel,
+ Grid, TextField,
+ Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import {useForm} from "react-hook-form";
+
+import {useEffect, useState} from "react";
+import Autocomplete from '@mui/material/Autocomplete';
+import {
+ subDivision1,
+ subDivision2,
+ subDivision3,
+ subDivision4,
+ subDivision5,
+ subDivision6
+} from "pages/pnspsUserSettingPage/DummyComboRecord";
+import Checkbox from "@mui/material/Checkbox";
+import * as React from "react";
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const subDivisionArray =[
+ ...subDivision1,
+ ...subDivision2,
+ ...subDivision3,
+ ...subDivision4,
+ ...subDivision5,
+ ...subDivision6
+];
+
+const UserSearchForm = ({applySearch}) => {
+
+ const [type, setType] = useState([]);
+ const [division, setDivision] = useState(null);
+ const [subDivision, setSubDivision] = useState(null);
+ const [isLotusNoteUser, setIsLotusNoteUser] = useState(false);
+ const [locked, setLocked] = useState(false);
+
+
+ const { reset, register, handleSubmit } = useForm()
+ const onSubmit = (data) => {
+
+ let typeArray = [];
+
+ for(let i =0; i < type.length; i++){
+ typeArray.push(type[i].label);
+ }
+
+ const temp = {
+ username: data.userName,
+ fullName: data.fullName,
+ post: data.post,
+ subDivision: subDivision,
+ email: data.email,
+ phone: data.phone,
+ isLotusNoteUser: isLotusNoteUser,
+ locked: locked,
+ };
+ applySearch(temp);
+ };
+
+ useEffect(() => {
+ if(division != null){
+ setSubDivision(subDivisionArray[division.type-1][0]);
+ }
+
+ }, [division]);
+
+ function resetForm(){
+ setType([]);
+ setDivision(null);
+ setSubDivision(null);
+ setIsLotusNoteUser(false);
+ setLocked(false);
+ reset();
+ }
+
+ return (
+
+
+
+
+ );
+};
+
+export default UserSearchForm;
diff --git a/src/pages/pnspsUserSearchPage/UserTable.js b/src/pages/pnspsUserSearchPage/UserTable.js
new file mode 100644
index 0000000..ed2ab25
--- /dev/null
+++ b/src/pages/pnspsUserSearchPage/UserTable.js
@@ -0,0 +1,137 @@
+// material-ui
+import * as React from 'react';
+import {
+ DataGrid,
+ GridActionsCellItem,
+} from "@mui/x-data-grid";
+import EditIcon from '@mui/icons-material/Edit';
+import {useEffect} from "react";
+import {useNavigate} from "react-router-dom";
+import { useTheme } from '@mui/material/styles';
+import Checkbox from '@mui/material/Checkbox';
+// ==============================|| EVENT TABLE ||============================== //
+
+export default function UserTable({recordList}) {
+ const [rows, setRows] = React.useState(recordList);
+ const [rowModesModel] = React.useState({});
+ const theme = useTheme();
+
+ const navigate = useNavigate()
+
+ useEffect(() => {
+ setRows(recordList);
+ }, [recordList]);
+
+ const handleEditClick = (id) => () => {
+ navigate('/user/'+ id);
+ };
+
+ const columns = [
+ {
+ field: 'actions',
+ type: 'actions',
+ headerName: 'Actions',
+ width: 100,
+ cellClassName: 'actions',
+ getActions: ({id}) => {
+ return [
+ }
+ label="Edit"
+ className="textPrimary"
+ onClick={handleEditClick(id)}
+ color="primary"
+ />]
+ },
+ },
+ {
+ id: 'username',
+ field: 'username',
+ headerName: 'User Name',
+ flex: 1,
+ },
+ {
+ id: 'name',
+ field: 'name',
+ headerName: 'Full Name',
+ flex: 1,
+ },
+ {
+ id: 'post',
+ field: 'post',
+ headerName: 'Post',
+ flex: 1,
+ },
+ {
+ id: 'email',
+ field: 'email',
+ headerName: 'Email',
+ flex: 1,
+ },
+ {
+ id: 'subDivisionId',
+ field: 'subDivisionId',
+ //type: 'date',
+ //sortable: false,
+ headerName: 'Sub-Division',
+ flex: 1,
+ },
+ {
+ id: 'lotusNotesUser',
+ field: 'lotusNotesUser',
+ type: 'bool',
+ headerName: 'Lotus Notes User',
+ flex: 1,
+ renderCell: (params) => {
+ return (
+
+ );
+ },
+ },
+ {
+ id: 'locked',
+ field: 'locked',
+ type: 'bool',
+ headerName: 'Locked',
+ flex: 1,
+ renderCell: (params) => {
+ return (
+
+ );
+ },
+ },
+ ];
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pnspsUserSearchPage/index.js b/src/pages/pnspsUserSearchPage/index.js
new file mode 100644
index 0000000..164c0ad
--- /dev/null
+++ b/src/pages/pnspsUserSearchPage/index.js
@@ -0,0 +1,84 @@
+// material-ui
+import {
+ Grid, Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import SearchForm from "./UserSearchForm";
+import EventTable from "./UserTable";
+import {useEffect, useState} from "react";
+import axios from "axios";
+import {apiPath} from "../../auth/utils";
+import {GET_USER_PATH} from "../../utils/ApiPathConst";
+import * as React from "react";
+import LoadingComponent from "../extra-pages/LoadingComponent";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const UserSettingPage = () => {
+
+ const [record,setRecord] = useState([]);
+ const [searchCriteria, setSearchCriteria] = useState({});
+ const [onReady, setOnReady] = useState(false);
+
+ useEffect(() => {
+ getUserList();
+ }, []);
+
+ useEffect(() => {
+ setOnReady(true);
+ }, [record]);
+
+ useEffect(() => {
+ getUserList();
+ }, [searchCriteria]);
+
+ function getUserList(){
+ axios.get(`${apiPath}${GET_USER_PATH}`,
+ {params: searchCriteria}
+ )
+ .then((response) => {
+ if (response.status === 200) {
+ setRecord(response.data);
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
+ }
+
+ function applySearch(input) {
+ setSearchCriteria(input);
+ }
+
+ return (
+ !onReady ?
+
+ :
+
+
+ View User
+
+
+ {/*row 1*/}
+
+
+
+ {/*row 2*/}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UserSettingPage;
diff --git a/src/pages/pnspsUserSettingPage/DummyComboRecord.js b/src/pages/pnspsUserSettingPage/DummyComboRecord.js
new file mode 100644
index 0000000..356f116
--- /dev/null
+++ b/src/pages/pnspsUserSettingPage/DummyComboRecord.js
@@ -0,0 +1,77 @@
+export const eventType = [
+ {label: '同心', type: 1},
+ {label: '創新', type: 2},
+ {label: '惠民', type: 3},
+ {label: '傳承', type: 3},
+];
+
+export const divisionType = [
+ {key: 1, label: 'Railways Branch', type: 1},
+ {key: 2, label: 'Electricity and Energy Efficiency Branch ', type: 2},
+ {key: 3, label: 'Gas and General Legislation Branch', type: 3},
+ {key: 4, label: 'Engineering Services Branch 1', type: 4},
+ {key: 5, label: 'Engineering Services Branch 2', type: 5},
+ {key: 6, label: 'Engineering Services Branch 3', type: 6},
+];
+
+export const subDivision1 = [
+ {key: 1, label: 'Sub Division 1 of Railways Branch', type: 1},
+ {key: 2, label: 'Sub Division 2 of Railways Branch', type: 2},
+ {key: 3, label: 'Sub Division 3 of Railways Branch', type: 3},
+ {key: 4, label: 'Sub Division 4 of Railways Branch', type: 4},
+];
+
+export const subDivision2 = [
+ {key: 1, label: 'Sub Division 1 of Electricity and Energy Efficiency Branch', type: 1},
+ {key: 2, label: 'Sub Division 2 of Electricity and Energy Efficiency Branch', type: 2},
+ {key: 3, label: 'Sub Division 3 of Electricity and Energy Efficiency Branch', type: 3},
+];
+
+export const subDivision3 = [
+ {key: 1, label: 'Sub Division 1 of Gas and General Legislation Branch', type: 1},
+ {key: 2, label: 'Sub Division 2 of Gas and General Legislation Branch', type: 2},
+ {key: 3, label: 'Sub Division 3 of Gas and General Legislation Branch', type: 3},
+];
+
+export const subDivision4 = [
+ {key: 1, label: 'Sub Division 1 of Engineering Services Branch 1', type: 1},
+ {key: 2, label: 'Sub Division 2 of Engineering Services Branch 1', type: 2},
+ {key: 3, label: 'Sub Division 3 of Engineering Services Branch 1', type: 3},
+ {key: 4, label: 'Sub Division 4 of Engineering Services Branch 1', type: 4},
+];
+
+export const subDivision5 = [
+ {key: 1, label: 'Sub Division 1 of Engineering Services Branch 2', type: 1},
+ {key: 2, label: 'Sub Division 2 of Engineering Services Branch 2', type: 2},
+ {key: 3, label: 'Sub Division 3 of Engineering Services Branch 2', type: 3},
+];
+
+export const subDivision6 = [
+ {key: 1, label: 'Sub Division 1 of Engineering Services Branch 3', type: 1},
+ {key: 2, label: 'Sub Division 2 of Engineering Services Branch 3', type: 2},
+ {key: 3, label: 'Sub Division 3 of Engineering Services Branch 3', type: 3},
+];
+
+export const tableRecord = [
+ {trackingNo: 84564564, name: 'Camera', fat: 40, carbs: 2, protein: 4057},
+ {trackingNo: 98764564, name: 'Laptop', fat: 300, carbs: 0, protein: 180139},
+ {trackingNo: 98756325, name: 'Mobile', fat: 355, carbs: 1, protein: 90989},
+ {trackingNo: 98652366, name: 'Handset', fat: 50, carbs: 1, protein: 10239},
+ {trackingNo: 13286564, name: 'Computer', fat: 100, carbs: 1, protein: 8334},
+ {trackingNo: 86739658, name: 'TV', fat: 99, carbs: 0, protein: 410780},
+ {trackingNo: 13256498, name: 'Keyboard', fat: 125, carbs: 2, protein: 70999},
+ {trackingNo: 98753263, name: 'Mouse', fat: 89, carbs: 2, protein: 10570},
+ {trackingNo: 98753275, name: 'Desktop', fat: 185, carbs: 1, protein: 98063},
+ {trackingNo: 98753291, name: 'Chair', fat: 100, carbs: 0, protein: 14001},
+];
+
+export const tableRecordTemp = [
+ {id:1 ,eventNo: 84564564, eventDate:"2022-03-20" , category: '同心', hrmPlan: 'Visionary Leadership', name: 'HKMA Best Annual Reports Awards - The Electrical and Mechanical Services Department Annual Report 2020/21 - Certificate of Excellence'},
+ {id:2 ,eventNo: 98764564, eventDate:"2022-05-12" , category: '同心', hrmPlan: 'Visionary Leadership', name: 'HKMA Best Annual Reports Awards - The Electrical and Mechanical Services Department Annual Report 2020/21- Best New Entry'},
+ {id:3 ,eventNo: 98756325, eventDate:"2022-06-04" , category: '創新', hrmPlan: 'Visionary Leadership', name: '19th Hong Kong Occupational Safety and Health Award - Gold Award - The Virtual Reality-based Lift Maintenance training programme'},
+ {id:4 ,eventNo: 98652366, eventDate:"2022-08-16" , category: '創新', hrmPlan: 'Visionary Leadership', name: 'BIM Achievement 2022 - BIM Organisations 2022'},
+ {id:5 ,eventNo: 13286564, eventDate:"2022-09-30" , category: '惠民', hrmPlan: 'Visionary Leadership', name: 'Civil Service Outstanding Service Award Scheme 2022 - Excellence in Team Collaboration (Internal Service) - Innovation Facilitator'},
+ {id:6 ,eventNo: 86739658, eventDate:"2022-10-25" , category: '惠民', hrmPlan: 'Visionary Leadership', name: 'Civil Service Outstanding Service Award Scheme 2022 - Excellence in Team Collaboration (Management of Crisis) - E&M 100 - CHT Rescue Team'},
+ {id:7 ,eventNo: 13256498, eventDate:"2022-11-21" , category: '傳承', hrmPlan: 'Visionary Leadership', name: '11th Guangzhou/Hong Kong/Macao/Chengdu Youth Skills Competition - Three TTs from the EMSD got the top three prizes in the Electrical Installations trade of the Hong Kong Region qualifying competition'},
+ {id:8 ,eventNo: 98753263, eventDate:"2022-12-31" , category: '傳承', hrmPlan: 'Visionary Leadership', name: 'VTC 2021 Outstanding Apprentices Scheme - Outstanding Apprentice - Mr. LEE King (TTII)'},
+];
\ No newline at end of file
diff --git a/src/pages/pnspsUserSettingPage/UserSearchForm.js b/src/pages/pnspsUserSettingPage/UserSearchForm.js
new file mode 100644
index 0000000..2297846
--- /dev/null
+++ b/src/pages/pnspsUserSettingPage/UserSearchForm.js
@@ -0,0 +1,232 @@
+// material-ui
+import {
+ Button,
+ CardContent, FormControlLabel,
+ Grid, TextField,
+ Typography
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import {useForm} from "react-hook-form";
+
+import dayjs from "dayjs";
+import {useEffect, useState} from "react";
+import Autocomplete from '@mui/material/Autocomplete';
+import {
+ subDivision1,
+ subDivision2,
+ subDivision3,
+ subDivision4,
+ subDivision5,
+ subDivision6
+} from "pages/pnspsUserSettingPage/DummyComboRecord";
+import Checkbox from "@mui/material/Checkbox";
+import * as React from "react";
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+const subDivisionArray =[
+ ...subDivision1,
+ ...subDivision2,
+ ...subDivision3,
+ ...subDivision4,
+ ...subDivision5,
+ ...subDivision6
+];
+
+const UserSearchForm = ({applySearch}) => {
+
+ const [value, setValue] = useState();
+ const [type, setType] = useState([]);
+ const [division, setDivision] = useState(null);
+ const [subDivision, setSubDivision] = useState(null);
+ const [isLotusNoteUser, setIsLotusNoteUser] = useState(false);
+ const [locked, setLocked] = useState(false);
+
+
+ const { reset, register, handleSubmit } = useForm()
+ const onSubmit = (data) => {
+
+ let typeArray = [];
+
+ for(let i =0; i < type.length; i++){
+ typeArray.push(type[i].label);
+ }
+
+ const temp = {
+ eventName: data.eventName,
+ eventOrganization: data.eventOrganization,
+ eventRegion: data.eventRegion,
+ eventDescription: data.eventDescription,
+ type: typeArray,
+ division: division,
+ subDivision: subDivision,
+ selectedDate: dayjs(value).format("MM/DD/YYYY")
+ };
+ applySearch(temp);
+ };
+
+ useEffect(() => {
+ if(division != null){
+ setSubDivision(subDivisionArray[division.type-1][0]);
+ }
+
+ }, [division]);
+
+ function resetForm(){
+ setValue(new Date().toDateString());
+ setType([]);
+ setDivision(null);
+ setSubDivision(null);
+ setIsLotusNoteUser(false);
+ setLocked(false);
+ reset();
+ }
+
+ return (
+
+
+
+
+ );
+};
+
+export default UserSearchForm;
diff --git a/src/pages/pnspsUserSettingPage/UserTable.js b/src/pages/pnspsUserSettingPage/UserTable.js
new file mode 100644
index 0000000..ed2ab25
--- /dev/null
+++ b/src/pages/pnspsUserSettingPage/UserTable.js
@@ -0,0 +1,137 @@
+// material-ui
+import * as React from 'react';
+import {
+ DataGrid,
+ GridActionsCellItem,
+} from "@mui/x-data-grid";
+import EditIcon from '@mui/icons-material/Edit';
+import {useEffect} from "react";
+import {useNavigate} from "react-router-dom";
+import { useTheme } from '@mui/material/styles';
+import Checkbox from '@mui/material/Checkbox';
+// ==============================|| EVENT TABLE ||============================== //
+
+export default function UserTable({recordList}) {
+ const [rows, setRows] = React.useState(recordList);
+ const [rowModesModel] = React.useState({});
+ const theme = useTheme();
+
+ const navigate = useNavigate()
+
+ useEffect(() => {
+ setRows(recordList);
+ }, [recordList]);
+
+ const handleEditClick = (id) => () => {
+ navigate('/user/'+ id);
+ };
+
+ const columns = [
+ {
+ field: 'actions',
+ type: 'actions',
+ headerName: 'Actions',
+ width: 100,
+ cellClassName: 'actions',
+ getActions: ({id}) => {
+ return [
+ }
+ label="Edit"
+ className="textPrimary"
+ onClick={handleEditClick(id)}
+ color="primary"
+ />]
+ },
+ },
+ {
+ id: 'username',
+ field: 'username',
+ headerName: 'User Name',
+ flex: 1,
+ },
+ {
+ id: 'name',
+ field: 'name',
+ headerName: 'Full Name',
+ flex: 1,
+ },
+ {
+ id: 'post',
+ field: 'post',
+ headerName: 'Post',
+ flex: 1,
+ },
+ {
+ id: 'email',
+ field: 'email',
+ headerName: 'Email',
+ flex: 1,
+ },
+ {
+ id: 'subDivisionId',
+ field: 'subDivisionId',
+ //type: 'date',
+ //sortable: false,
+ headerName: 'Sub-Division',
+ flex: 1,
+ },
+ {
+ id: 'lotusNotesUser',
+ field: 'lotusNotesUser',
+ type: 'bool',
+ headerName: 'Lotus Notes User',
+ flex: 1,
+ renderCell: (params) => {
+ return (
+
+ );
+ },
+ },
+ {
+ id: 'locked',
+ field: 'locked',
+ type: 'bool',
+ headerName: 'Locked',
+ flex: 1,
+ renderCell: (params) => {
+ return (
+
+ );
+ },
+ },
+ ];
+
+ return (
+
+
+
+ );
+}
diff --git a/src/pages/pnspsUserSettingPage/index.js b/src/pages/pnspsUserSettingPage/index.js
new file mode 100644
index 0000000..0f333cf
--- /dev/null
+++ b/src/pages/pnspsUserSettingPage/index.js
@@ -0,0 +1,89 @@
+// material-ui
+import {
+ Grid
+} from '@mui/material';
+import MainCard from "../../components/MainCard";
+import SearchForm from "./UserSearchForm";
+import EventTable from "./UserTable";
+import {useEffect, useState} from "react";
+import axios from "axios";
+import {apiPath} from "../../auth/utils";
+import {GET_USER_PATH} from "../../utils/ApiPathConst";
+
+// ==============================|| DASHBOARD - DEFAULT ||============================== //
+
+
+const UserSettingPage = () => {
+
+ const [record,setRecord] = useState([]);
+ const [searchCriteria, setSearchCriteria] = useState({});
+ const [sortedRecord, setSortedRecord] = useState([]);
+
+ useEffect(() => {
+ axios.get(`${apiPath}${GET_USER_PATH}`)
+ .then((response) => {
+ if (response.status === 200) {
+ setRecord(response.data);
+ setSortedRecord(response.data);
+ }
+ })
+ .catch(error => {
+ console.log(error);
+ return false;
+ });
+ }, [])
+
+ const filterSearchName = (array) => {
+ return array.filter((item) => item.name.toLowerCase().includes(searchCriteria.eventName));
+ };
+
+ const filterSearchType = (array) => {
+ return array.filter((item) => item.category.includes(searchCriteria.type));
+ };
+
+ function sortData(record) {
+ let sortedRecord = record;
+ sortedRecord = filterSearchName(sortedRecord);
+ sortedRecord = filterSearchType(sortedRecord);
+ return sortedRecord;
+ }
+
+ function applySearch(input) {
+ setSearchCriteria(input);
+ }
+
+ useEffect(() => {
+ //console.log(searchCriteria);
+ if (Object.keys(searchCriteria).length !== 0) {
+ const tempSortedRecord = sortData(record);
+ console.log(tempSortedRecord);
+ setSortedRecord(tempSortedRecord);
+ } else {
+ setSortedRecord(record);
+ }
+ }, [searchCriteria]);
+
+ return (
+
+ {/*row 1*/}
+
+
+
+ {/*row 2*/}
+
+
+
+
+
+
+
+
+ );
+};
+
+export default UserSettingPage;
diff --git a/src/routes/MainRoutes.js b/src/routes/MainRoutes.js
index 1b85f35..d4d0494 100644
--- a/src/routes/MainRoutes.js
+++ b/src/routes/MainRoutes.js
@@ -6,7 +6,6 @@ import MainLayout from 'layout/MainLayout';
// render - dashboard
const DashboardDefault = Loadable(lazy(() => import('pages/dashboard')));
-const ARSDashboard = Loadable(lazy(() => import('pages/arsdashboard')));
// render - sample page
const SamplePage = Loadable(lazy(() => import('pages/extra-pages/SamplePage')));
@@ -27,10 +26,6 @@ const MainRoutes = {
path: '/',
element:
},
- {
- path: '/arsDashboard',
- element:
- },
{
path: 'color',
element:
diff --git a/src/routes/SettingRoutes.js b/src/routes/SettingRoutes.js
new file mode 100644
index 0000000..4a7b8fa
--- /dev/null
+++ b/src/routes/SettingRoutes.js
@@ -0,0 +1,48 @@
+import { lazy } from 'react';
+
+// project import
+import Loadable from 'components/Loadable';
+import MainLayout from "../layout/MainLayout";
+
+// render - login
+const SettingPage = Loadable(lazy(() => import('pages/pnspsSettingPage')));
+const PasswordPolicyPage = Loadable(lazy(()=> import('pages/pnspsPasswordPolicyPage')))
+const UserSettingPage = Loadable(lazy(()=>import ('pages/pnspsUserSettingPage/')));
+const UserGroupSearchPage = Loadable(lazy(() => import('pages/pnspsUserGroupSearchPage')));
+const UserSearchPage = Loadable(lazy(()=>import ('pages/pnspsUserSearchPage')));
+const UserMaintainPage = Loadable(lazy(() => import('pages/pnspsUserDetailPage')));
+
+// ==============================|| AUTH ROUTING ||============================== //
+
+const SettingRoutes = {
+ path: '/',
+ element: ,
+ children: [
+ {
+ path: 'usergroupSearchview',
+ element:
+ },
+ {
+ path: '/user/:id',
+ element:
+ },
+ {
+ path: 'userSearchview',
+ element:
+ },
+ {
+ path: 'usersetting',
+ element:
+ },
+ {
+ path: 'setting',
+ element:
+ },
+ {
+ path: 'passwordpolicy',
+ element:
+ }
+ ]
+};
+
+export default SettingRoutes;
diff --git a/src/routes/index.js b/src/routes/index.js
index 8a5acd2..8f99933 100644
--- a/src/routes/index.js
+++ b/src/routes/index.js
@@ -9,6 +9,7 @@ import {handleLogoutFunction,
setupAxiosInterceptors,
isTokenValid} from "../auth";
import {useNavigate} from "react-router-dom";
+import SettingRoutes from './SettingRoutes';
// ==============================|| ROUTING RENDER ||============================== //
export default function ThemeRoutes() {
@@ -41,7 +42,8 @@ export default function ThemeRoutes() {
]
},
LoginRoutes,
- MainRoutes
+ MainRoutes,
+ SettingRoutes
]);
//return useRoutes([MainRoutes, LoginRoutes]);
}
diff --git a/src/utils/ApiPathConst.js b/src/utils/ApiPathConst.js
new file mode 100644
index 0000000..aba9fa8
--- /dev/null
+++ b/src/utils/ApiPathConst.js
@@ -0,0 +1,3 @@
+export const GET_GROUP_COMBO_PATH = "/group/combo"
+export const GET_USER_PATH = "/user"
+export const GET_AUTH_LIST = "/user/auth/combo"
\ No newline at end of file