| @@ -42,7 +42,7 @@ const LocaleSelector = () => { | |||
| }; | |||
| const iconBackColorOpen = 'grey.300'; | |||
| const iconBackColor = 'grey.100'; | |||
| const iconBackColor = '#ffffff'; | |||
| return ( | |||
| <Box sx={{ flexShrink: 0, ml: 0.75 }}> | |||
| @@ -67,6 +67,18 @@ export default function SearchDemandNote({ recordList, reloadFun }) { | |||
| } | |||
| const doUploadFile = (event) => { | |||
| let file = event.target.files[0]; | |||
| HttpUtils.postWithFiles({ | |||
| url:UrlUtils.DEMAND_NOTE_ATTACH, | |||
| files:[file], | |||
| onSuccess() { | |||
| if (reloadFun) reloadFun(); | |||
| }, | |||
| }); | |||
| document.getElementById("uploadFileBtn").value = ""; | |||
| } | |||
| const markPaid = () => { | |||
| setConfirmPopUp(false); | |||
| let idList = []; | |||
| @@ -171,11 +183,32 @@ export default function SearchDemandNote({ recordList, reloadFun }) { | |||
| return ( | |||
| <div style={{ height: '100%', width: '100%' }}> | |||
| <Grid container maxWidth justifyContent="flex-start"> | |||
| <Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||
| <input | |||
| id="uploadFileBtn" | |||
| name="file" | |||
| type="file" | |||
| accept=".pdf" | |||
| style={{ display: 'none' }} | |||
| onChange={(event) => { | |||
| doUploadFile(event) | |||
| }} | |||
| /> | |||
| <label htmlFor="uploadFileBtn"> | |||
| <Button | |||
| component="span" | |||
| variant="contained" | |||
| size="large" | |||
| > | |||
| <Typography variant="h5">Attach DN</Typography> | |||
| </Button> | |||
| </label> | |||
| </Grid> | |||
| <Grid item sx={{ ml: 3, mr: 3, mb: 3, mt: 3 }}> | |||
| <Button | |||
| size="large" | |||
| variant="contained" | |||
| onClick={()=>setSendPopUp(true)} | |||
| onClick={() => setSendPopUp(true)} | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end' | |||
| @@ -201,7 +234,7 @@ export default function SearchDemandNote({ recordList, reloadFun }) { | |||
| <Button | |||
| size="large" | |||
| variant="contained" | |||
| onClick={()=>setConfirmPopUp(true)} | |||
| onClick={() => setConfirmPopUp(true)} | |||
| sx={{ | |||
| textTransform: 'capitalize', | |||
| alignItems: 'end' | |||
| @@ -9,7 +9,7 @@ import { | |||
| // Grid, | |||
| Stack, | |||
| Typography, | |||
| Button, | |||
| Button, StepLabel, | |||
| } from '@mui/material'; | |||
| import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
| @@ -22,34 +22,11 @@ const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/BusCustomFormW | |||
| const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom'))); | |||
| import axios from "axios"; | |||
| import { GET_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst"; | |||
| import {useTheme} from "@emotion/react"; | |||
| // import CustomFormWizard from './auth-forms/BusCustomFormWizard'; | |||
| // import AuthWrapper from './AuthWrapperCustom'; | |||
| // ================================|| REGISTER ||================================ // | |||
| const stepStyle = { | |||
| width: "40%", | |||
| boxShadow: 2, | |||
| backgroundColor: "#FFFFFF", | |||
| padding: 2, | |||
| "& .Mui-active": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "warning.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "warning.main" | |||
| } | |||
| }, | |||
| "& .Mui-completed": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "secondary.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "secondary.main" | |||
| } | |||
| } | |||
| } | |||
| const steps = ['個人資料', '預覽', '完成提交']; | |||
| const BusRegister = () => { | |||
| @@ -59,6 +36,39 @@ const BusRegister = () => { | |||
| const [username, setUsername] = useState("") | |||
| const [base64Url, setBase64Url] = useState("") | |||
| const [checkCode, setCheckCode] = useState("") | |||
| const theme = useTheme(); | |||
| const stepStyle = { | |||
| [theme.breakpoints.up('lg')]: { | |||
| width: '40%', | |||
| }, | |||
| [theme.breakpoints.up('md')]: { | |||
| width: '70%', | |||
| }, | |||
| [theme.breakpoints.up('xs')]: { | |||
| width: '95%', | |||
| }, | |||
| boxShadow: 1, | |||
| backgroundColor: "#FFFFFF", | |||
| padding: 2, | |||
| "& .Mui-active": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "warning.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "warning.main" | |||
| } | |||
| }, | |||
| "& .Mui-completed": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "secondary.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "secondary.main" | |||
| } | |||
| } | |||
| } | |||
| const totalSteps = () => { | |||
| return steps.length; | |||
| @@ -131,7 +141,7 @@ const BusRegister = () => { | |||
| return ( | |||
| // <AuthWrapper> | |||
| <Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', bgcolor: 'backgroundColor.default' }} alignItems="center"> | |||
| <Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '35px', bgcolor: 'backgroundColor.default' }} alignItems="center"> | |||
| <Stepper activeStep={activeStep} sx={stepStyle}> | |||
| {steps.map((label, index) => ( | |||
| <Step key={label} completed={completed[index]} readOnly={true}> | |||
| @@ -140,14 +150,26 @@ const BusRegister = () => { | |||
| (<StepButton | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <Typography variant="step1">{label}</Typography> | |||
| <StepLabel sx={{ | |||
| flexDirection: 'column', | |||
| "& .MuiStepLabel-iconContainer": { | |||
| paddingRight: 0 | |||
| }}}> | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepLabel> | |||
| </StepButton>) : | |||
| (<StepButton | |||
| sx={activeStep === 2 ? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } } : allStepsCompleted() ? { "& .MuiSvgIcon-root": { color: "secondary.main", fontSize: "2rem" } } : { color: "rgba(0, 0, 0, 0.38)" }} | |||
| icon={<VisibilityIcon />} | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <Typography variant="step1">{label}</Typography> | |||
| <StepLabel sx={{ | |||
| flexDirection: 'column', | |||
| "& .MuiStepLabel-iconContainer": { | |||
| paddingRight: 0 | |||
| }}}> | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepLabel> | |||
| </StepButton>) | |||
| } | |||
| @@ -12,7 +12,7 @@ import { | |||
| // Grid, | |||
| Stack, | |||
| Typography, | |||
| Button, | |||
| Button, StepLabel, | |||
| } from '@mui/material'; | |||
| import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
| import { GET_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst"; | |||
| @@ -22,33 +22,11 @@ import Loadable from 'components/Loadable'; | |||
| import { lazy } from 'react'; | |||
| import { notifyActionError } from 'utils/CommonFunction'; | |||
| import axios from "axios"; | |||
| import {useTheme} from "@emotion/react"; | |||
| const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/CustomFormWizard'))); | |||
| const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom'))); | |||
| // ================================|| REGISTER ||================================ // | |||
| const stepStyle = { | |||
| width: "40%", | |||
| boxShadow: 1, | |||
| backgroundColor: "#FFFFFF", | |||
| padding: 2, | |||
| "& .Mui-active": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "warning.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "warning.main" | |||
| } | |||
| }, | |||
| "& .Mui-completed": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "secondary.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "secondary.main" | |||
| } | |||
| } | |||
| } | |||
| const steps = ['個人資料', '預覽', '完成提交']; | |||
| const Register = () => { | |||
| @@ -58,6 +36,39 @@ const Register = () => { | |||
| const [username, setUsername] = useState(""); | |||
| const [base64Url, setBase64Url] = useState("") | |||
| const [checkCode, setCheckCode] = useState("") | |||
| const theme = useTheme(); | |||
| const stepStyle = { | |||
| [theme.breakpoints.up('lg')]: { | |||
| width: '40%', | |||
| }, | |||
| [theme.breakpoints.up('md')]: { | |||
| width: '70%', | |||
| }, | |||
| [theme.breakpoints.up('xs')]: { | |||
| width: '95%', | |||
| }, | |||
| boxShadow: 1, | |||
| backgroundColor: "#FFFFFF", | |||
| padding: 2, | |||
| "& .Mui-active": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "warning.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "warning.main" | |||
| } | |||
| }, | |||
| "& .Mui-completed": { | |||
| "&.MuiStepIcon-root": { | |||
| color: "secondary.main", | |||
| fontSize: "2rem", | |||
| }, | |||
| "& .MuiStepConnector-line": { | |||
| borderColor: "secondary.main" | |||
| } | |||
| } | |||
| } | |||
| const totalSteps = () => { | |||
| return steps.length; | |||
| @@ -132,27 +143,39 @@ const Register = () => { | |||
| return ( | |||
| // <AuthWrapper> | |||
| <Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', bgcolor: 'backgroundColor.default' }} alignItems="center"> | |||
| <Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '35px', bgcolor: 'backgroundColor.default' }} alignItems="center"> | |||
| <Stepper activeStep={activeStep} sx={stepStyle}> | |||
| {steps.map((label, index) => ( | |||
| <Step key={label} completed={completed[index]} readOnly={true}> | |||
| { | |||
| index < 2 ? | |||
| (<StepButton | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepButton>) : | |||
| (<StepButton | |||
| sx={activeStep === 2 ? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } } : allStepsCompleted() ? { "& .MuiSvgIcon-root": { color: "secondary.main", fontSize: "2rem" } } : { color: "rgba(0, 0, 0, 0.38)" }} | |||
| icon={<VisibilityIcon />} | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepButton>) | |||
| } | |||
| <Step key={label} completed={completed[index]} readOnly={true}> | |||
| { | |||
| index < 2 ? | |||
| (<StepButton | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <StepLabel sx={{ | |||
| flexDirection: 'column', | |||
| "& .MuiStepLabel-iconContainer": { | |||
| paddingRight: 0 | |||
| }}}> | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepLabel> | |||
| </StepButton>) : | |||
| (<StepButton | |||
| sx={activeStep === 2 ? { "& .MuiSvgIcon-root": { color: "warning.main", fontSize: "2rem" } } : allStepsCompleted() ? { "& .MuiSvgIcon-root": { color: "secondary.main", fontSize: "2rem" } } : { color: "rgba(0, 0, 0, 0.38)" }} | |||
| icon={<VisibilityIcon />} | |||
| // onClick={handleStep(index)} | |||
| > | |||
| <StepLabel sx={{ | |||
| flexDirection: 'column', | |||
| "& .MuiStepLabel-iconContainer": { | |||
| paddingRight: 0 | |||
| }}}> | |||
| <Typography variant="step1">{label}</Typography> | |||
| </StepLabel> | |||
| </StepButton>) | |||
| } | |||
| </Step> | |||
| </Step> | |||
| ))} | |||
| </Stepper> | |||
| {allStepsCompleted() ? ( | |||
| @@ -184,6 +207,7 @@ const Register = () => { | |||
| disabled={true} | |||
| onClick={handleBack} | |||
| sx={{ mr: 1 }} | |||
| variant="h5" | |||
| > | |||
| <Typography variant="h5">返回</Typography> | |||
| </Button> | |||
| @@ -193,6 +217,7 @@ const Register = () => { | |||
| disabled={activeStep === 0} | |||
| onClick={handleBack} | |||
| sx={{ mr: 1 }} | |||
| variant="h5" | |||
| > | |||
| <Typography variant="h5">返回</Typography> | |||
| </Button> | |||
| @@ -739,9 +739,8 @@ const BusCustomFormWizard = (props) => { | |||
| )} | |||
| </Stack> | |||
| <Grid container spacing={2} alignItems="center"> | |||
| <Grid item> | |||
| <Grid item sx={{mt:1}}> | |||
| <Typography variant="subtitle1"> | |||
| <br /> | |||
| •至少8個字元,字元越多越好 <br /> | |||
| •字母和數字的混合<br /> | |||
| •英文字母大寫與小寫的混合<br /> | |||
| @@ -763,7 +762,6 @@ const BusCustomFormWizard = (props) => { | |||
| <Grid item xs={12} md={12}> | |||
| <Typography variant="subtitle1"> | |||
| <br /> | |||
| •請輸入機構/公司英文名稱或中文名稱<br /> | |||
| •Please enter the English/Chinese name of the organisation/company | |||
| </Typography> | |||
| @@ -834,7 +832,7 @@ const BusCustomFormWizard = (props) => { | |||
| </Grid> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1}> | |||
| <InputLabel htmlFor="brNo-signup"> | |||
| <InputLabel htmlFor="brNo-signup" sx={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}> | |||
| <Typography variant="pnspsFormHeader"> | |||
| 商業登記證號碼 (e.g. 12341234-123-12-12-1) | |||
| <span style={{ color: '#f10000' }}>*</span> | |||
| @@ -966,8 +964,7 @@ const BusCustomFormWizard = (props) => { | |||
| onChange={(event, newValue) => { | |||
| setSelectedAddress4(newValue); | |||
| }} | |||
| size="small" | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, /*"#address4-combo": { padding: "0px 0px 0px 0px" },*/ "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address4-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| renderInput={(params) => <TextField {...params} placeholder="區域 (只適用於香港)" />} | |||
| /> | |||
| <Autocomplete | |||
| @@ -975,11 +972,10 @@ const BusCustomFormWizard = (props) => { | |||
| id="address5-combo" | |||
| value={selectedAddress5} | |||
| options={address5ComboList} | |||
| size="small" | |||
| onChange={(event, newValue) => { | |||
| if (newValue !== null) { | |||
| setSelectedAddress5(newValue); | |||
| if (newValue == '香港') { | |||
| if (newValue === '香港') { | |||
| setCheckCountry(false) | |||
| } else { | |||
| setSelectedAddress4(""); | |||
| @@ -991,7 +987,7 @@ const BusCustomFormWizard = (props) => { | |||
| } | |||
| }} | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, /*"#address5-combo": { padding: "0px 0px 0px 0px" },*/ "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address5-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| renderInput={(params) => <TextField {...params} placeholder="國家/地區" />} | |||
| /> | |||
| {formik.touched.address1 && formik.errors.address1 && ( | |||
| @@ -771,7 +771,7 @@ const CustomFormWizard = (props) => { | |||
| </FormHelperText> | |||
| )} | |||
| </Stack> | |||
| <FormControl fullWidth sx={{ mt: 1 }}> | |||
| <FormControl fullWidth sx={{ mt: 2 }}> | |||
| <Grid container spacing={2} alignItems="center"> | |||
| <Grid item> | |||
| <Box sx={{ bgcolor: level?.color, width: 85, height: 8, borderRadius: '7px' }} /> | |||
| @@ -970,6 +970,11 @@ const CustomFormWizard = (props) => { | |||
| // sx={{height:"53px"}} | |||
| startAdornment={<InputAdornment position="start">(</InputAdornment>} | |||
| endAdornment={<InputAdornment position="end">)</InputAdornment>} | |||
| sx={{ | |||
| '& .MuiOutlinedInput-input': { | |||
| padding: '5px 5px 5px 5px', // Set the desired padding inline | |||
| }, | |||
| }} | |||
| inputProps={{ | |||
| maxLength: 1, | |||
| onKeyDown: (e) => { | |||
| @@ -1163,7 +1168,7 @@ const CustomFormWizard = (props) => { | |||
| onChange={(event, newValue) => { | |||
| setSelectedAddress4(newValue); | |||
| }} | |||
| sx={{ "& .MuiInputBase-root": { height: "48px" }, "#address4-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address4-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| renderInput={(params) => <TextField {...params} placeholder="區域 (只適用於香港)" />} | |||
| /> | |||
| <Autocomplete | |||
| @@ -1186,7 +1191,7 @@ const CustomFormWizard = (props) => { | |||
| } | |||
| }} | |||
| sx={{ "& .MuiInputBase-root": { height: "48px" }, "#address5-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address5-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }} | |||
| renderInput={(params) => <TextField {...params} placeholder="國家/地區" />} | |||
| /> | |||
| {formik.touched.address1 && formik.errors.address1 && ( | |||
| @@ -77,7 +77,7 @@ export default function UploadFileTable({ recordList, setUpdateRows, }) { | |||
| id: 'name', | |||
| field: 'name', | |||
| headerName: <Typography variant="h6">檔案名稱</Typography>, | |||
| flex: 5, | |||
| flex: 4, | |||
| }, | |||
| { | |||
| id: 'size', | |||
| @@ -87,7 +87,7 @@ export default function UploadFileTable({ recordList, setUpdateRows, }) { | |||
| // console.log(params) | |||
| return Math.ceil(params.value / 1024) + " KB"; | |||
| }, | |||
| flex: 1, | |||
| flex: 2, | |||
| }, | |||
| ]; | |||
| @@ -128,7 +128,7 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({ | |||
| root: { | |||
| fontSize: '1.0rem', | |||
| height: '40px', | |||
| width: '40vw', // Default width for xs screen sizes | |||
| width: '70vw', // Default width for xs screen sizes | |||
| '@media (min-width: 600px)': { // sm breakpoint | |||
| width: '30vw', | |||
| }, | |||
| @@ -136,7 +136,7 @@ export const PNSPS_LONG_BUTTON_THEME = createTheme({ | |||
| width: '25vw', | |||
| }, | |||
| '@media (min-width: 1280px)': { // lg breakpoint | |||
| width: '14vw', | |||
| width: '19vw', | |||
| }, | |||
| textTransform: "none", | |||
| alignItems: 'center' | |||
| @@ -104,6 +104,7 @@ export const DEMAND_NOTE_LIST = apiPath+'/demandNote/list';//GET | |||
| export const DEMAND_NOTE_LOAD = apiPath+'/demandNote/load';//GET | |||
| export const DEMAND_NOTE_SEND = apiPath+'/demandNote/send-dn';//POST | |||
| export const DEMAND_NOTE_MARK_PAID = apiPath+'/demandNote/mark-as-paid';//POST | |||
| export const DEMAND_NOTE_ATTACH = apiPath+'/demandNote/attach';//POST | |||
| @@ -86,54 +86,9 @@ export const fileDownload = ({url, fileId, skey, filename, onResponse, onError}) | |||
| }); | |||
| }; | |||
| // export const reportDownload = ({url, onError}) =>{ | |||
| // axios.get( url, | |||
| // { | |||
| // responseType: 'blob', | |||
| // } | |||
| // ).then( | |||
| // (response)=>{ | |||
| // const filename = response.headers | |||
| // .get("content-disposition") | |||
| // .split("filename=")[1] | |||
| // .split('"')[1].trim(); | |||
| // const url = URL.createObjectURL(response.data); | |||
| // const a = document.createElement('a'); | |||
| // a.href = url; | |||
| // a.setAttribute("download", filename); | |||
| // document.body.appendChild(a); | |||
| // a.click(); | |||
| // document.body.removeChild(a); | |||
| // URL.revokeObjectURL(url); | |||
| // } | |||
| // ).catch(error => { | |||
| // return handleError(error,onError); | |||
| // }); | |||
| // }; | |||
| export const fileUpload = ({ refType, refId, files, refCode, onSuccess, onFail, onError}) =>{ | |||
| // console.log(files); | |||
| // var formData = new FormData(); | |||
| // for (let i = 0; i < files.length; i++){ | |||
| // const file = files[i] | |||
| // formData.append("multipartFileList", file); | |||
| // } | |||
| // // formData.append("multipartFile", file); | |||
| // formData.append("refType", refType); | |||
| // formData.append("refId", refId); | |||
| // if(refCode){ | |||
| // formData.append("refCode", refCode); | |||
| // } | |||
| // console.log(formData) | |||
| // axios.post(FILE_UP_POST,formData,{ | |||
| // headers: { | |||
| // "Content-Type":"multipart/form-data" | |||
| // } | |||
| // }).then( | |||
| // (response)=>{ | |||
| // onResponse(response,onSuccess,onFail); | |||
| // } | |||
| // ).catch(error => { return handleError(error, onError); }); | |||
| export const fileUpload = ({refType, refId, files, refCode, onSuccess, onFail, onError}) =>{ | |||
| postWithFiles({ | |||
| url: FILE_UP_POST, | |||
| params:{ | |||