Browse Source

public user search and view

master
Anna Ho 2 years ago
parent
commit
66d5e59cbb
9 changed files with 309 additions and 156 deletions
  1. +4
    -5
      src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js
  2. +99
    -42
      src/pages/pnspsUserDetailPage_Organization/UserInformationCard_Organization.js
  3. +1
    -1
      src/pages/pnspsUserDetailPage_Organization/index.js
  4. +20
    -19
      src/pages/pnspsUserSearchPage_Individual/UserSearchForm_Individual.js
  5. +70
    -22
      src/pages/pnspsUserSearchPage_Individual/UserTable_Individual.js
  6. +41
    -18
      src/pages/pnspsUserSearchPage_Organization/UserSearchForm_Organization.js
  7. +68
    -22
      src/pages/pnspsUserSearchPage_Organization/UserTable_Organization.js
  8. +1
    -26
      src/utils/ComboData.js
  9. +5
    -1
      src/utils/IconUtils.js

+ 4
- 5
src/pages/pnspsUserDetailPage_Individual/UserInformationCard_Individual.js View File

@@ -79,6 +79,8 @@ const UserInformationCard_Individual = ({userData,userFile, loadDataFun}) => {
userData["faxNumber"] = userData.faxNo?.faxNumber; userData["faxNumber"] = userData.faxNo?.faxNumber;
userData["fax_countryCode"] = userData.faxNo?.countryCode; userData["fax_countryCode"] = userData.faxNo?.countryCode;


userData["lastLoginDate"] = userData.lastLogin?DateUtils.datetimeStr(userData.lastLogin):"";

setIdDocType(userData.idDocType); setIdDocType(userData.idDocType);
setDistrict(userData.district); setDistrict(userData.district);
setCountry(userData.country); setCountry(userData.country);
@@ -645,11 +647,8 @@ const UserInformationCard_Individual = ({userData,userFile, loadDataFun}) => {


<TextField <TextField
fullWidth fullWidth
{...register("lastLogin",
{
value: currentUserData?.lastLogin,
})}
id='lastLogin'
{...register("lastLoginDate")}
id='lastLoginDate'
disabled disabled
> >
</TextField> </TextField>


+ 99
- 42
src/pages/pnspsUserDetailPage_Organization/UserInformationCard_Organization.js View File

@@ -1,6 +1,7 @@
// material-ui // material-ui
import { import {
Grid, TextField, Typography, Button
Grid, TextField, Typography, Button,
OutlinedInput, FormHelperText
} from '@mui/material'; } from '@mui/material';
import MainCard from "../../components/MainCard"; import MainCard from "../../components/MainCard";
import * as React from "react"; import * as React from "react";
@@ -10,6 +11,9 @@ import * as DateUtils from '../../utils/DateUtils';
import * as HttpUtils from '../../utils/HttpUtils'; import * as HttpUtils from '../../utils/HttpUtils';
import * as UrlUtils from "../../utils/ApiPathConst"; import * as UrlUtils from "../../utils/ApiPathConst";


import { useFormik,FormikProvider } from 'formik';
import * as yup from 'yup';

// ==============================|| DASHBOARD - DEFAULT ||============================== // // ==============================|| DASHBOARD - DEFAULT ||============================== //




@@ -19,10 +23,33 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
const [editMode, setEditMode] = useState(false); const [editMode, setEditMode] = useState(false);
const [locked, setLocked] = useState(false); const [locked, setLocked] = useState(false);



const from = useForm({defaultValues: userData}); const from = useForm({defaultValues: userData});
const {register,reset, handleSubmit} = from; const {register,reset, handleSubmit} = from;


const formik = useFormik({
initialValues:(currentUserData),
validationSchema:yup.object().shape({
enName: yup.string().max(255).required('請輸入英文姓名'),
enCompanyName: yup.string().max(255).required('請輸入英文名稱'),
chName: yup.string().max(255).required('請輸入中文姓名'),
address1: yup.string().max(255).required('請輸入第一行地址'),
address2: yup.string().max(255).required('請輸入第二行地址'),
address3: yup.string().max(255).required('請輸入第三行地址'),
email: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵'),
emailConfirm: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵').oneOf([yup.ref('email'), null], '請輸入相同電郵'),
phoneCountryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'),
faxCountryCode: yup.string().min(3,'請輸入3位數字'),
phone: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'),
fax: yup.string().min(8,'請輸入8位數字'),
brExpiryDate: yup.string().min(8,'請輸入商業登記證有效日期'),
brNo: yup.string().min(8,'請輸入商業登記證號碼'),
})
});


useEffect(() => { useEffect(() => {
let createDate = DateUtils.datetimeStr(userData.created); let createDate = DateUtils.datetimeStr(userData.created);
let modifiedBy = DateUtils.datetimeStr(userData.modified)+", "+userData.modifiedBy; let modifiedBy = DateUtils.datetimeStr(userData.modified)+", "+userData.modifiedBy;
@@ -51,29 +78,36 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
}, [currentUserData]); }, [currentUserData]);




function onSubmitForm(_formData) {

function onSubmitForm() {
HttpUtils.post({ HttpUtils.post({
url: UrlUtils.POST_IND_USER+"/"+userData.id, url: UrlUtils.POST_IND_USER+"/"+userData.id,
params: { params: {
chName: _formData.chName,
enName: _formData.enName,
chName: formik.values.chName,
enName: formik.values.enName,
contactTel: { contactTel: {
countryCode: _formData.tel_countryCode,
phoneNumber: _formData.phoneNumber
countryCode: formik.values.tel_countryCode,
phoneNumber: formik.values.phoneNumber
}, },
faxNo: { faxNo: {
countryCode: _formData.fax_countryCode,
faxNumber: _formData.faxNumber
countryCode: formik.values.fax_countryCode,
faxNumber: formik.values.faxNumber
}, },
addressBus: { addressBus: {
country: _formData.country,
district: _formData.district,
addressLine1: _formData.addressLine1,
addressLine2: _formData.addressLine2,
addressLine3: _formData.addressLine3,
country: formik.values.country,
district: formik.values.district,
addressLine1: formik.values.addressLine1,
addressLine2: formik.values.addressLine2,
addressLine3: formik.values.addressLine3,
}, },
identification: _formData.identification,
emailBus:_formData.emailBus,
identification: formik.values.identification,
emailBus:formik.values.emailBus,
contactPerson: formik.values.contactPerson,
enCompanyName: formik.values.enCompanyName,
chCompanyName: formik.values.chCompanyName,
brNo: formik.values.brNo,
brExpiryDate: formik.values.brExpiryDate,

}, },
onSuccess: function(){ onSuccess: function(){
loadDataFun(); loadDataFun();
@@ -89,6 +123,15 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
window.open("/org/fromUser/"+userData.id, "_blank", "noreferrer"); window.open("/org/fromUser/"+userData.id, "_blank", "noreferrer");
}; };


const onVerifiedClick = () => {
HttpUtils.get({
url: UrlUtils.GET_IND_USER_VERIFY+"/"+userData.id,
onSuccess: function(){
loadDataFun();
}
});
};

const doLock = () => { const doLock = () => {
HttpUtils.get({ HttpUtils.get({
url: UrlUtils.GET_USER_LOCK+"/"+userData.id, url: UrlUtils.GET_USER_LOCK+"/"+userData.id,
@@ -107,6 +150,7 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
}); });
}; };


return ( return (
<MainCard elevation={0} <MainCard elevation={0}
border={false} border={false}
@@ -116,6 +160,7 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
Information Information
</Typography> </Typography>


<FormikProvider value={formik}>
<form onSubmit={handleSubmit(onSubmitForm)}> <form onSubmit={handleSubmit(onSubmitForm)}>


{/*top button*/} {/*top button*/}
@@ -302,10 +347,7 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {


<Grid item xs={7} s={7} md={7} lg={6} > <Grid item xs={7} s={7} md={7} lg={6} >
<TextField <TextField
{...register("identification",
{
value: currentUserData?.identification,
})}
{...register("identification")}
id='identification' id='identification'
disabled={!editMode} disabled={!editMode}
/> />
@@ -325,8 +367,8 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
<Grid item xs={7} s={7} md={7} lg={6}> <Grid item xs={7} s={7} md={7} lg={6}>
<TextField <TextField
fullWidth fullWidth
{...register("emailAddress")}
id='emailAddress'
{...register("emailBus")}
id='emailBus'
disabled={!editMode} disabled={!editMode}
/> />
</Grid> </Grid>
@@ -341,8 +383,9 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
Verified: Verified:
</Grid> </Grid>


{ {
currentUserData.verified || editMode?
currentUserData.verifiedBy || editMode?
<Grid item xs={6}> <Grid item xs={6}>
<TextField <TextField
fullWidth fullWidth
@@ -369,17 +412,20 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
textTransform: 'capitalize', textTransform: 'capitalize',
alignItems: 'end' alignItems: 'end'
}} }}
onClick={onVerifiedClick}
> >
Verify Verify
</Button> </Button>
</Grid> </Grid>
</> </>
} }
</Grid> </Grid>
</Grid> </Grid>







<Grid item lg={4}> <Grid item lg={4}>
<Grid container alignItems={"center"}> <Grid container alignItems={"center"}>
<Grid item xs={4} s={4} md={4} lg={4} <Grid item xs={4} s={4} md={4} lg={4}
@@ -522,7 +568,7 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
fullWidth fullWidth
{...register("chCompanyName")} {...register("chCompanyName")}
id='chCompanyName' id='chCompanyName'
disabled
disabled={!editMode}
/> />
</Grid> </Grid>
</Grid> </Grid>
@@ -597,12 +643,30 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
</Grid> </Grid>


<Grid item xs={7} s={7} md={7} lg={6}> <Grid item xs={7} s={7} md={7} lg={6}>
<TextField
fullWidth
{...register("brExpiryDateTemp")}
id='brExpiryDateTemp'
disabled={!editMode}
/>
<OutlinedInput
fullWidth
disabled={!editMode}
{...register("brExpiryDate")}
error={Boolean(formik.touched.brExpiryDate && formik.errors.brExpiryDate)}
id="brExpiryDate"
type="date"
value={formik.values.brExpiryDate}
name="brExpiryDate"
onChange={formik.handleChange}
placeholder="與與商業登記證相同如有"
inputProps={{
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.preventDefault();
}
},
}}
/>
{formik.touched.brExpiryDate && formik.errors.brExpiryDate && (
<FormHelperText error id="brExpiryDate">
{formik.errors.brExpiryDate}
</FormHelperText>
)}
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>
@@ -617,28 +681,19 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
<Grid item xs={7} s={7} md={12} lg={6}> <Grid item xs={7} s={7} md={12} lg={6}>
<TextField <TextField
fullWidth fullWidth
{...register("addressLine1",
{
value: currentUserData?.address?.addressLine1,
})}
{...register("addressLine1")}
id='addressLine1' id='addressLine1'
disabled={!editMode} disabled={!editMode}
/> />
<TextField <TextField
fullWidth fullWidth
{...register("addressLine2",
{
value: currentUserData?.address?.addressLine2,
})}
{...register("addressLine2")}
id='addressLine2' id='addressLine2'
disabled={!editMode} disabled={!editMode}
/> />
<TextField <TextField
fullWidth fullWidth
{...register("addressLine3",
{
value: currentUserData?.address?.addressLine3,
})}
{...register("addressLine3")}
id='addressLine3' id='addressLine3'
disabled={!editMode} disabled={!editMode}
/> />
@@ -685,6 +740,8 @@ const UserInformationCard_Organization = ({userData, loadDataFun}) => {
</Grid> </Grid>


</form> </form>

</FormikProvider>
</MainCard> </MainCard>
); );
}; };


+ 1
- 1
src/pages/pnspsUserDetailPage_Organization/index.js View File

@@ -30,7 +30,7 @@ const UserMaintainPage_Organization = () => {
HttpUtils.get({ HttpUtils.get({
url: `${UrlUtils.GET_ORG_USER_PATH}/${params.id}`, url: `${UrlUtils.GET_ORG_USER_PATH}/${params.id}`,
onSuccess: function(response){ onSuccess: function(response){
response.data["addressBus"] = JSON.parse(response.data["address"]);
response.data["addressBus"] = JSON.parse(response.data["addressBus"]);
response.data["contactTel"] = JSON.parse(response.data["contactTel"]); response.data["contactTel"] = JSON.parse(response.data["contactTel"]);
response.data["faxNo"] = JSON.parse(response.data["faxNo"]); response.data["faxNo"] = JSON.parse(response.data["faxNo"]);
setUserData(response.data) setUserData(response.data)


+ 20
- 19
src/pages/pnspsUserSearchPage_Individual/UserSearchForm_Individual.js View File

@@ -1,15 +1,13 @@
// material-ui // material-ui
import { import {
Button, Button,
CardContent, FormControlLabel,
CardContent,
Grid, TextField, Grid, TextField,
Typography
Autocomplete
} from '@mui/material'; } from '@mui/material';
import MainCard from "../../components/MainCard"; import MainCard from "../../components/MainCard";
import {useForm} from "react-hook-form"; import {useForm} from "react-hook-form";

import { useState} from "react"; import { useState} from "react";
import Checkbox from "@mui/material/Checkbox";
import * as React from "react"; import * as React from "react";
// ==============================|| DASHBOARD - DEFAULT ||============================== // // ==============================|| DASHBOARD - DEFAULT ||============================== //


@@ -17,8 +15,7 @@ import * as React from "react";
const UserSearchForm_Individual = ({applySearch}) => { const UserSearchForm_Individual = ({applySearch}) => {


const [type, setType] = useState([]); const [type, setType] = useState([]);
const [locked, setLocked] = useState(false);

const [accountFilter, setAccountFilter] = useState("Active");


const { reset, register, handleSubmit } = useForm() const { reset, register, handleSubmit } = useForm()
const onSubmit = (data) => { const onSubmit = (data) => {
@@ -34,14 +31,13 @@ const UserSearchForm_Individual = ({applySearch}) => {
fullName: data.fullName, fullName: data.fullName,
email: data.email, email: data.email,
phone: data.phone, phone: data.phone,
locked: locked,
accountFilter: accountFilter,
}; };
applySearch(temp); applySearch(temp);
}; };


function resetForm(){ function resetForm(){
setType([]); setType([]);
setLocked(false);
reset(); reset();
} }


@@ -97,18 +93,23 @@ const UserSearchForm_Individual = ({applySearch}) => {
</Grid> </Grid>


<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
<FormControlLabel
control={
<Checkbox
checked={locked}
onChange={(event) => setLocked(event.target.checked)}
name="checked"
color="primary"
size="small"
<Autocomplete
{...register("accountFilter")}
disablePortal
id="accountFilter"
options={["Active","Locked","Not verified"]}
value={accountFilter}
onChange={(event, newValue) => {
if (newValue !== null){
setAccountFilter(newValue);
}
}}
renderInput={(params) => (
<TextField {...params}
label="Status"
/>
)}
/> />
}
label={<Typography variant="h6">Locked</Typography>}
/>
</Grid> </Grid>
{/*<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>*/} {/*<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>*/}
{/* <TextField*/} {/* <TextField*/}


+ 70
- 22
src/pages/pnspsUserSearchPage_Individual/UserTable_Individual.js View File

@@ -2,19 +2,19 @@
import * as React from 'react'; import * as React from 'react';
import { import {
DataGrid, DataGrid,
GridActionsCellItem,
GridActionsCellItem
} from "@mui/x-data-grid"; } from "@mui/x-data-grid";
import VisibilityIcon from '@mui/icons-material/Visibility'; import VisibilityIcon from '@mui/icons-material/Visibility';
import HighlightOff from '@mui/icons-material/HighlightOff';
import CheckCircleOutline from '@mui/icons-material/CheckCircleOutline';
import {useEffect} from "react"; import {useEffect} from "react";
import {useNavigate} from "react-router-dom"; import {useNavigate} from "react-router-dom";
import { useTheme } from '@mui/material/styles';
import Checkbox from '@mui/material/Checkbox';
import * as DateUtils from "../../utils/DateUtils";
// ==============================|| EVENT TABLE ||============================== // // ==============================|| EVENT TABLE ||============================== //


export default function UserTable_Individual({recordList}) { export default function UserTable_Individual({recordList}) {
const [rows, setRows] = React.useState(recordList); const [rows, setRows] = React.useState(recordList);
const [rowModesModel] = React.useState({}); const [rowModesModel] = React.useState({});
const theme = useTheme();


const navigate = useNavigate() const navigate = useNavigate()


@@ -52,34 +52,82 @@ export default function UserTable_Individual({recordList}) {
flex: 1, flex: 1,
}, },
{ {
id: 'name',
field: 'name',
headerName: 'Full Name',
id: 'enName',
field: 'enName',
headerName: 'Name (Eng)',
flex: 1, flex: 1,
}, },
{ {
id: 'email',
field: 'email',
id: 'chName',
field: 'chName',
headerName: 'Name (Ch)',
flex: 1,
},
{
id: 'contactTel',
field: 'contactTel',
headerName: 'Tel.',
flex: 1,
valueGetter:(params)=>{
if(params.value){
let tel = JSON.parse(params.value);
return "+"+tel.countryCode+ " "+tel.phoneNumber;
}
}
},
{
id: 'emailAddress',
field: 'emailAddress',
headerName: 'Email', headerName: 'Email',
flex: 1, flex: 1,
}, },
{
id: 'lastLogin',
field: 'lastLogin',
headerName: 'Last Login',
flex: 1,
valueGetter:(params)=>{
if(params.value){
return DateUtils.datetimeStr(params.value);
}
}
},
{ {
id: 'locked', id: 'locked',
field: 'locked', field: 'locked',
type: 'bool',
headerName: 'Locked',
headerName: 'Status',
flex: 1, flex: 1,
renderCell: (params) => {
return (
<Checkbox
theme={theme}
key="locked"
checked={params.row.locked}
color="primary"
size="small"
//onChange={handleChange}
/>
);
valueGetter:(params)=>{
if(params.value){
return "Locked";
}else{
return "Active";
}
}
},
{
field: 'verifiedDate',
type: 'actions',
headerName: 'Verified',
width: 100,
cellClassName: 'actions',
getActions: (params) => {
if(params.row.verifiedDate)
return [
<GridActionsCellItem
key=""
icon={<CheckCircleOutline/>}
color="success"
/>];
return [
<GridActionsCellItem
key=""
icon={<HighlightOff/>}
color="error"
/>];
}, },
}, },
]; ];


+ 41
- 18
src/pages/pnspsUserSearchPage_Organization/UserSearchForm_Organization.js View File

@@ -1,15 +1,13 @@
// material-ui // material-ui
import { import {
Button, Button,
CardContent, FormControlLabel,
Grid, TextField,
Typography
CardContent, Autocomplete,
Grid, TextField
} from '@mui/material'; } from '@mui/material';
import MainCard from "../../components/MainCard"; import MainCard from "../../components/MainCard";
import {useForm} from "react-hook-form"; import {useForm} from "react-hook-form";


import { useState} from "react"; import { useState} from "react";
import Checkbox from "@mui/material/Checkbox";
import * as React from "react"; import * as React from "react";
// ==============================|| DASHBOARD - DEFAULT ||============================== // // ==============================|| DASHBOARD - DEFAULT ||============================== //


@@ -17,7 +15,7 @@ import * as React from "react";
const UserSearchForm_Organization = ({applySearch}) => { const UserSearchForm_Organization = ({applySearch}) => {


const [type, setType] = useState([]); const [type, setType] = useState([]);
const [locked, setLocked] = useState(false);
const [accountFilter, setAccountFilter] = useState("Active");




const { reset, register, handleSubmit } = useForm() const { reset, register, handleSubmit } = useForm()
@@ -34,14 +32,15 @@ const UserSearchForm_Organization = ({applySearch}) => {
fullName: data.fullName, fullName: data.fullName,
email: data.email, email: data.email,
phone: data.phone, phone: data.phone,
locked: locked,
brNoStr: data.brNoStr,
orgName: data.orgName,
accountFilter: accountFilter,
}; };
applySearch(temp); applySearch(temp);
}; };


function resetForm(){ function resetForm(){
setType([]); setType([]);
setLocked(false);
reset(); reset();
} }


@@ -60,6 +59,25 @@ const UserSearchForm_Organization = ({applySearch}) => {


{/*row 2*/} {/*row 2*/}
<Grid container alignItems={"center"}> <Grid container alignItems={"center"}>

<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
<TextField
fullWidth
{...register("orgName")}
id="orgName"
label="Org Name"
/>
</Grid>

<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
<TextField
fullWidth
{...register("brNoStr")}
id="brNoStr"
label="BR No."
/>
</Grid>

<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
<TextField <TextField
fullWidth fullWidth
@@ -97,18 +115,23 @@ const UserSearchForm_Organization = ({applySearch}) => {
</Grid> </Grid>


<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}> <Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>
<FormControlLabel
control={
<Checkbox
checked={locked}
onChange={(event) => setLocked(event.target.checked)}
name="checked"
color="primary"
size="small"
<Autocomplete
{...register("accountFilter")}
disablePortal
id="accountFilter"
options={["Active","Locked","Not verified"]}
value={accountFilter}
onChange={(event, newValue) => {
if (newValue !== null){
setAccountFilter(newValue);
}
}}
renderInput={(params) => (
<TextField {...params}
label="Status"
/>
)}
/> />
}
label={<Typography variant="h6">Locked</Typography>}
/>
</Grid> </Grid>
{/*<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>*/} {/*<Grid item xs={9} s={6} md={5} lg={3} sx={{ml:3, mr:3, mb:3}}>*/}
{/* <TextField*/} {/* <TextField*/}


+ 68
- 22
src/pages/pnspsUserSearchPage_Organization/UserTable_Organization.js View File

@@ -7,14 +7,13 @@ import {
import VisibilityIcon from '@mui/icons-material/Visibility'; import VisibilityIcon from '@mui/icons-material/Visibility';
import {useEffect} from "react"; import {useEffect} from "react";
import {useNavigate} from "react-router-dom"; import {useNavigate} from "react-router-dom";
import { useTheme } from '@mui/material/styles';
import Checkbox from '@mui/material/Checkbox';
import HighlightOff from '@mui/icons-material/HighlightOff';
import CheckCircleOutline from '@mui/icons-material/CheckCircleOutline';
// ==============================|| EVENT TABLE ||============================== // // ==============================|| EVENT TABLE ||============================== //


export default function UserTable_Organization({recordList}) { export default function UserTable_Organization({recordList}) {
const [rows, setRows] = React.useState(recordList); const [rows, setRows] = React.useState(recordList);
const [rowModesModel] = React.useState({}); const [rowModesModel] = React.useState({});
const theme = useTheme();


const navigate = useNavigate() const navigate = useNavigate()


@@ -52,34 +51,81 @@ export default function UserTable_Organization({recordList}) {
flex: 1, flex: 1,
}, },
{ {
id: 'name',
field: 'name',
headerName: 'Full Name',
id: 'enName',
field: 'enName',
headerName: 'Name (Eng)',
flex: 1, flex: 1,
}, },
{ {
id: 'email',
field: 'email',
headerName: 'Email',
id: 'chName',
field: 'chName',
headerName: 'Name (Ch)',
flex: 1, flex: 1,
}, },
{
id: 'enCompanyName',
field: 'enCompanyName',
headerName: 'Company(Eng)',
flex: 1,
},
{
id: 'chCompanyName',
field: 'chCompanyName',
headerName: 'Company(Ch)',
flex: 1,
},
{
id: 'brNo',
field: 'brNo',
headerName: 'Br No',
flex: 1,
},
{
id: 'lastLogin',
field: 'lastLogin',
headerName: 'Last Login',
flex: 1,
valueGetter:(params)=>{
if(params.value){
return DateUtils.datetimeStr(params.value);
}
}
},
{ {
id: 'locked', id: 'locked',
field: 'locked', field: 'locked',
type: 'bool',
headerName: 'Locked',
headerName: 'Status',
flex: 1, flex: 1,
renderCell: (params) => {
return (
<Checkbox
theme={theme}
key="locked"
checked={params.row.locked}
color="primary"
size="small"
//onChange={handleChange}
/>
);
valueGetter:(params)=>{
if(params.value){
return "Locked";
}else{
return "Active";
}
}
},
{
field: 'verifiedDate',
type: 'actions',
headerName: 'Verified',
width: 100,
cellClassName: 'actions',
getActions: (params) => {
if(params.row.verifiedDate)
return [
<GridActionsCellItem
key=""
icon={<CheckCircleOutline/>}
color="success"
/>];
return [
<GridActionsCellItem
key=""
icon={<HighlightOff/>}
color="error"
/>];
}, },
}, },
]; ];


+ 1
- 26
src/utils/ComboData.js View File

@@ -1,32 +1,7 @@
import * as yup from 'yup';


export const idDocType = ["passport","HKID","CNID","BR","otherCert"]; export const idDocType = ["passport","HKID","CNID","BR","otherCert"];
export const district = ["北區","長洲區","大埔區","大嶼山區","東區","觀塘區","黃大仙區","九龍城區","葵青區","南區","南丫島區", export const district = ["北區","長洲區","大埔區","大嶼山區","東區","觀塘區","黃大仙區","九龍城區","葵青區","南區","南丫島區",
"坪洲區","荃灣區","沙田區","深水埗區","屯門區","灣仔區","西貢區","油尖旺區","元朗區","中西區"]; "坪洲區","荃灣區","沙田區","深水埗區","屯門區","灣仔區","西貢區","油尖旺區","元朗區","中西區"];
export const country = ["香港","內地","澳門"]; export const country = ["香港","內地","澳門"];


export const validationSchema = ()=>{
return yup.object().shape({
username: yup.string().min(8,"用戶名稱最少8位").required('請輸入用戶名稱'),
password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼')
.matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母')
.matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母')
.matches(/^(?=.*[0-9])/, '請包括最少1個數字')
.matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'),
confirmPassword: yup.string().min(8,'請最少輸入8位密碼').required('請確認密碼').oneOf([yup.ref('password'), null], '請輸入相同密碼'),
enName: yup.string().max(255).required('請輸入英文姓名'),
chName: yup.string().max(255).required('請輸入中文姓名'),
address1: yup.string().max(255).required('請輸入第一行地址'),
address2: yup.string().max(255).required('請輸入第二行地址'),
address3: yup.string().max(255).required('請輸入第三行地址'),
email: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵'),
emailConfirm: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵').oneOf([yup.ref('email'), null], '請輸入相同電郵'),
idNo: yup.string().min(7,"請輸入證件號碼").required('請輸入證件號碼'),
checkDigit:yup.string().max(1).required('請輸入括號內的數字或字母'),
idDocType: yup.string().max(255).required('請輸入證件類別'),
phoneCountryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'),
faxCountryCode: yup.string().min(3,'請輸入3位數字'),
phone: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'),
fax: yup.string().min(8,'請輸入8位數字'),
});
}
export const accountFilter = [{display:"Active", value:"active"},{display:"Locked", value:"locked"},{display:"Not verified", value:"notVerified"}];

+ 5
- 1
src/utils/IconUtils.js View File

@@ -3,8 +3,12 @@ import DeleteIcon from '@mui/icons-material/DeleteForever';
import EditIcon from '@mui/icons-material/Edit'; import EditIcon from '@mui/icons-material/Edit';
import ViewIcon from '@mui/icons-material/Visibility'; import ViewIcon from '@mui/icons-material/Visibility';
import DownloadICon from '@mui/icons-material/Download'; import DownloadICon from '@mui/icons-material/Download';
import VaildIcon from '@mui/icons-material/CheckCircleOutline';
import InVaildIcon from '@mui/icons-material/HighlightOff';


export const Delete = DeleteIcon; export const Delete = DeleteIcon;
export const Edit = EditIcon; export const Edit = EditIcon;
export const View = ViewIcon; export const View = ViewIcon;
export const Download = DownloadICon;
export const Download = DownloadICon;
export const Vaild = VaildIcon;
export const Invaild = InVaildIcon;

Loading…
Cancel
Save