@@ -74,62 +74,62 @@ function Header(props) { | |||
isGLDLoggedIn() ? | |||
<div id="adminContent"> | |||
<li> | |||
<Link className="dashboard" to='/dashboard'>Dashboard</Link> | |||
<Link className="dashboard" to='/dashboard'><Typography variant={"headerTitle1"} sx={{ml:2}}>Dashboard</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="application" to='/application/search'>Application</Link> | |||
<Link className="application" to='/application/search'><Typography variant={"headerTitle1"} sx={{ml:2}}>Application</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="proof" to='/proof/search'>Proof</Link> | |||
<Link className="proof" to='/proof/search'><Typography variant={"headerTitle1"} sx={{ml:2}}>Proof</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="payment" to='/dashboard'>Payment</Link> | |||
<Link className="payment" to='/dashboard'><Typography variant={"headerTitle1"} sx={{ml:2}}>Payment</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="client" >Client<KeyboardArrowDownIcon /></Link> | |||
<Link className="client" ><Typography variant={"headerTitle1"} sx={{ml:2}}>Client</Typography><KeyboardArrowDownIcon /></Link> | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="userSearchview" to='/userSearchview'>Users (GLD)</Link> | |||
<Link className="userSearchview" to='/userSearchview'><Typography variant={"headerTitle1"} sx={{ml:2}}>Users (GLD)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="indUser" to='/indUser'>Users (Individual)</Link> | |||
<Link className="indUser" to='/indUser'><Typography variant={"headerTitle1"} sx={{ml:2}}>Users (Individual)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="orgUser" to='/orgUser'>Users (Organization)</Link> | |||
<Link className="orgUser" to='/orgUser'><Typography variant={"headerTitle1"} sx={{ml:2}}>Users (Organization)</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="org" to='/org'>Organization</Link> | |||
<Link className="org" to='/org'><Typography variant={"headerTitle1"} sx={{ml:2}}>Organization</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="usergroupSearchview" to='/usergroupSearchview'>User Group</Link> | |||
<Link className="usergroupSearchview" to='/usergroupSearchview'><Typography variant={"headerTitle1"} sx={{ml:2}}>User Group</Typography></Link> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<Link className="logout" onClick={handleLogout}>Logout</Link> | |||
<Link className="logout" onClick={handleLogout}><Typography variant={"headerTitle1"} sx={{ml:2}}>Logout</Typography></Link> | |||
</li> | |||
</div> | |||
: | |||
<div id="individualUserContent"> | |||
<li> | |||
<Link className="dashboard" to='/dashboard'>主頁</Link> | |||
<Link className="dashboard" to='/dashboard'><Typography variant={"headerTitle1"} sx={{ml:2}}>主頁</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="myDocumet" to='/publicNotice'>我的公共啟事</Link> | |||
<Link className="myDocumet" to='/publicNotice'><Typography variant={"headerTitle1"} sx={{ml:2}}>我的公共啟事</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="documentRecord" to='/proof/search'>校對記錄</Link> | |||
<Link className="documentRecord" to='/proof/search'><Typography variant={"headerTitle1"} sx={{ml:2}}>校對記錄</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="paymentRecord" to='/dashboard'>付款記錄</Link> | |||
<Link className="paymentRecord" to='/dashboard'><Typography variant={"headerTitle1"} sx={{ml:2}}>付款記錄</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="userSetting" to='/dashboard'>設定<KeyboardArrowDownIcon /></Link> | |||
<Link className="userSetting" to='/dashboard'><Typography variant={"headerTitle1"} sx={{ml:2}}>設定</Typography><KeyboardArrowDownIcon /></Link> | |||
{isPrimaryLoggedIn() ? | |||
<ul className='dropdown'> | |||
<li> | |||
<Link className="manageOrgUser" to='setting/manageUser'>公司/機構用戶記錄</Link> | |||
<Link className="manageOrgUser" to='setting/manageUser'><Typography variant={"headerTitle1"} sx={{ml:2}}>公司/機構用戶記錄</Typography></Link> | |||
</li> | |||
</ul> | |||
: | |||
@@ -137,7 +137,7 @@ function Header(props) { | |||
} | |||
</li> | |||
<li> | |||
<Link className="logout" onClick={handleLogout}>登出</Link> | |||
<Link className="logout" onClick={handleLogout}><Typography variant={"headerTitle1"} sx={{ml:2}}>登出</Typography></Link> | |||
</li> | |||
</div> | |||
); | |||
@@ -145,10 +145,10 @@ function Header(props) { | |||
const logoutContent = ( | |||
<div> | |||
<li> | |||
<Link className="login" to='/login'>登入</Link> | |||
<Link className="login" to='/login'><Typography variant={"headerTitle1"} sx={{ml:2}}>登入</Typography></Link> | |||
</li> | |||
<li> | |||
<Link className="register" to='/register'>申請</Link> | |||
<Link className="register" to='/register'><Typography variant={"headerTitle1"} sx={{ml:2}}>申請</Typography></Link> | |||
</li> | |||
</div> | |||
); | |||
@@ -64,9 +64,9 @@ const Index = () => { | |||
}, [paymentData]); | |||
const loadForm = () => { | |||
const timeoutdatetime = "2023-10-26T09:04:30Z[UTC]" | |||
const convertedDateString = timeoutdatetime.replace("[UTC]", ""); | |||
setFpsmerchanttimeoutdatetime(convertedDateString) | |||
// const timeoutdatetime = "2023-10-26T09:04:30Z[UTC]" | |||
// const convertedDateString = timeoutdatetime.replace("[UTC]", ""); | |||
// setFpsmerchanttimeoutdatetime(convertedDateString) | |||
HttpUtils.post({ | |||
url: paymentPath+loadPaymentUrl+(paymentData.type=="PPS"?"pps":"creditcard"), | |||
@@ -40,6 +40,7 @@ const Index = () => { | |||
const [responeData, setResponeDataData] = React.useState({}); | |||
const [fpsTransctionData, setFpsTransctionData] = React.useState({}); | |||
const [fpsmerchanttimeoutdatetime, setFpsmerchanttimeoutdatetime] = React.useState(""); | |||
const [timeDownCount, setTimeDownCount] = React.useState(0); | |||
// const [fpsqrcodeurl, setFpsqrcodeurl] = React.useState(""); | |||
// const pasgPath = 'https://fps.payapps.hkicl.com.hk'; //PRD | |||
@@ -185,6 +186,8 @@ const Index = () => { | |||
console.log(time) | |||
console.log(timeOutDate) | |||
console.log(currentTime) | |||
console.log(timeOutDate.getTime()-currentTime.getTime()) | |||
setTimeDownCount(timeOutDate.getTime()-currentTime.getTime()) | |||
getPaymentStatus(); | |||
if (timeOutDate.getTime()<currentTime.getTime()){ | |||
console.log("stop"); | |||
@@ -239,9 +242,11 @@ const Index = () => { | |||
<br /> | |||
<img src={fpsTransctionData.fpsqrcodeimgbase64} alt="QR Code"/> | |||
<br /> | |||
二維碼有效期限10分鐘 | |||
二維碼有效期限3分鐘 | |||
<br /> | |||
請在規定時間內完成付款流程 | |||
<br /> | |||
{"剩餘時間:"+timeDownCount} | |||
</Typography> | |||
<Typography variant="h3" sx={{ ml: 8, mt: 4, mr: 8, textAlign: "center" }}> | |||
@@ -33,27 +33,44 @@ const MultiPaymentWindow = (props) => { | |||
const windowTitle = "請選擇付款方式"; | |||
const [content, setContent] = useState(); | |||
const [loadtTransactionData, setLoadtTransactionData] = useState({}); | |||
const [loadAvailableMethodData, setLoadAvailableMethodData] = useState([]); | |||
const [paymentMethod, setPaymentMethod] = useState(""); | |||
const [transactionData, setTransactionData] = useState([]); | |||
const [transactionData, setTransactionData] = useState({}); | |||
const [availableMethodData, setAvailableMethodData] = useState([]); | |||
const [onReady, setOnReady] = useState(false); | |||
useEffect(() => { | |||
console.log(props.availableMethods) | |||
console.log(props.transactionData) | |||
if(props.availableMethods.length > 0){ | |||
setAvailableMethodData(props.availableMethods) | |||
setTransactionData(props.transactionData) | |||
if(Object.keys(props.transactionData).length > 0){ | |||
setLoadtTransactionData(props.transactionData) | |||
} | |||
}, [props.transactionData]); | |||
useEffect(() => { | |||
console.log(availableMethodData) | |||
console.log(transactionData) | |||
if(availableMethodData.length > 0){ | |||
console.log(props.availableMethods) | |||
if(props.availableMethods.length > 0){ | |||
setLoadAvailableMethodData(props.availableMethods) | |||
} | |||
}, [props.availableMethods]); | |||
useEffect(() => { | |||
if(loadAvailableMethodData.length > 0){ | |||
setAvailableMethodData(loadAvailableMethodData) | |||
} | |||
}, [loadAvailableMethodData]); | |||
useEffect(() => { | |||
if(Object.keys(loadtTransactionData).length > 0){ | |||
setTransactionData(loadtTransactionData) | |||
} | |||
}, [loadtTransactionData]); | |||
useEffect(() => { | |||
if(availableMethodData.length > 0 && Object.keys(transactionData).length > 0){ | |||
setOnReady(true) | |||
} | |||
}, [availableMethodData]); | |||
}, [availableMethodData,transactionData]); | |||
useEffect(() => { | |||
console.log(paymentMethod) | |||
@@ -44,8 +44,8 @@ const AuthWrapper = ({ children }) => ( | |||
alignItems="center" | |||
spacing={2}> | |||
<Grid item xs={12} md={8} lg={8} xl={9} sx={{ ml: 4, mt: 3 ,display: { xs: 'none', sm: 'block' }}}> | |||
<Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem"}}>香港特別行政區政府</Typography> | |||
<Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.6rem",fontWeight:"bold"}}>憲報</Typography> | |||
<Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.8rem"}}>香港特別行政區政府</Typography> | |||
<Typography style={{textAlign: "center",fontFamily: "微軟正黑體",fontSize: "1.8rem",fontWeight:"bold"}}>憲報</Typography> | |||
</Grid> | |||
<Grid | |||
item | |||
@@ -1,183 +1,185 @@ | |||
// import { Link } from 'react-router-dom'; | |||
import React,{useState} from 'react'; | |||
// material-ui | |||
import { | |||
Stepper, | |||
Step, | |||
StepButton, | |||
// Grid, | |||
Stack, | |||
Typography, | |||
Button, | |||
} from '@mui/material'; | |||
import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
// project import | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from 'react'; | |||
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/BusCustomFormWizard'))); | |||
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom'))); | |||
// 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" | |||
} | |||
// import { Link } from 'react-router-dom'; | |||
import React, { useState } from 'react'; | |||
// material-ui | |||
import { | |||
Stepper, | |||
Step, | |||
StepButton, | |||
// Grid, | |||
Stack, | |||
Typography, | |||
Button, | |||
} from '@mui/material'; | |||
import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
// project import | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from 'react'; | |||
const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/BusCustomFormWizard'))); | |||
const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom'))); | |||
// 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", | |||
}, | |||
"& .Mui-completed": { | |||
"&.MuiStepIcon-root": { | |||
color: "secondary.main", | |||
fontSize: "2rem", | |||
}, | |||
"& .MuiStepConnector-line": { | |||
borderColor: "secondary.main" | |||
} | |||
"& .MuiStepConnector-line": { | |||
borderColor: "warning.main" | |||
} | |||
}, | |||
"& .Mui-completed": { | |||
"&.MuiStepIcon-root": { | |||
color: "secondary.main", | |||
fontSize: "2rem", | |||
}, | |||
"& .MuiStepConnector-line": { | |||
borderColor: "secondary.main" | |||
} | |||
} | |||
const steps = ['個人資料', '預覽', '完成提交']; | |||
} | |||
const steps = ['個人資料', '預覽', '完成提交']; | |||
const BusRegister = () => { | |||
const [activeStep, setActiveStep] = useState(0); | |||
const [completed, setCompleted] = useState([false]); | |||
const [updateValid, setUpdateValid] = useState(false); | |||
const BusRegister = () => { | |||
const [activeStep, setActiveStep] = useState(0); | |||
const [completed, setCompleted] = useState([false]); | |||
const [updateValid, setUpdateValid] = useState(false); | |||
const totalSteps = () => { | |||
return steps.length; | |||
}; | |||
const totalSteps = () => { | |||
return steps.length; | |||
}; | |||
const completedSteps = () => { | |||
return Object.keys(completed).length; | |||
}; | |||
const completedSteps = () => { | |||
return Object.keys(completed).length; | |||
}; | |||
const isLastStep = () => { | |||
return activeStep === totalSteps() - 1; | |||
}; | |||
const isLastStep = () => { | |||
return activeStep === totalSteps() - 1; | |||
}; | |||
const allStepsCompleted = () => { | |||
return completedSteps() === totalSteps(); | |||
}; | |||
const allStepsCompleted = () => { | |||
return completedSteps() === totalSteps(); | |||
}; | |||
const handleNext = () => { | |||
const newActiveStep = | |||
const handleNext = () => { | |||
const newActiveStep = | |||
isLastStep() && !allStepsCompleted() | |||
? // It's the last step, but not all steps have been completed, | |||
// find the first step that has been completed | |||
steps.findIndex((step, i) => !(i in completed)) | |||
: activeStep + 1; | |||
setActiveStep(newActiveStep); | |||
scrollToTop(); | |||
}; | |||
const handleBack = () => { | |||
scrollToTop(); | |||
setActiveStep((prevActiveStep) => prevActiveStep - 1); | |||
}; | |||
const scrollToTop = () => { | |||
window.scrollTo(0,0); | |||
}; | |||
const handleReset = () => { | |||
setActiveStep(0); | |||
setCompleted({}); | |||
}; | |||
return( | |||
// <AuthWrapper> | |||
<Stack sx={{ width: '100%',fontSize: '2rem',paddingTop: '65px'}} 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)} | |||
> | |||
{label} | |||
</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)} | |||
> | |||
{label} | |||
</StepButton>) | |||
} | |||
</Step> | |||
))} | |||
</Stepper> | |||
{allStepsCompleted() ? ( | |||
<React.Fragment> | |||
<Typography sx={{ mt: 2, mb: 1 }}> | |||
All steps completed - you're finished | |||
</Typography> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
<Button onClick={handleReset}>Reset</Button> | |||
</Stack> | |||
</React.Fragment> | |||
) : ( | |||
<React.Fragment> | |||
<AuthWrapper> | |||
<CustomFormWizard setUpdateValid={setUpdateValid} step={activeStep} /> | |||
{/* <CustomFormWizard step={activeStep} /> */} | |||
</AuthWrapper> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
{ activeStep === totalSteps() - 1 ? ( | |||
<Button | |||
color="inherit" | |||
disabled={true} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
? // It's the last step, but not all steps have been completed, | |||
// find the first step that has been completed | |||
steps.findIndex((step, i) => !(i in completed)) | |||
: activeStep + 1; | |||
setActiveStep(newActiveStep); | |||
scrollToTop(); | |||
}; | |||
const handleBack = () => { | |||
scrollToTop(); | |||
setActiveStep((prevActiveStep) => prevActiveStep - 1); | |||
}; | |||
const scrollToTop = () => { | |||
window.scrollTo(0, 0); | |||
}; | |||
const handleReset = () => { | |||
setActiveStep(0); | |||
setCompleted({}); | |||
}; | |||
return ( | |||
// <AuthWrapper> | |||
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', 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)} | |||
> | |||
返回 | |||
</Button> | |||
):( | |||
<Button | |||
color="inherit" | |||
disabled={activeStep === 0} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
<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> | |||
))} | |||
</Stepper> | |||
{allStepsCompleted() ? ( | |||
<React.Fragment> | |||
<Typography variant="h4" sx={{ mt: 2, mb: 1 }}> | |||
All steps completed - you're finished | |||
</Typography> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
<Button variant="h5" onClick={handleReset}>Reset</Button> | |||
</Stack> | |||
</React.Fragment> | |||
) : ( | |||
<React.Fragment> | |||
<AuthWrapper> | |||
<CustomFormWizard setUpdateValid={setUpdateValid} step={activeStep} /> | |||
{/* <CustomFormWizard step={activeStep} /> */} | |||
</AuthWrapper> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
{activeStep === totalSteps() - 1 ? ( | |||
<Button | |||
color="inherit" | |||
disabled={true} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
variant="h5" | |||
> | |||
<Typography variant="h5">返回</Typography> | |||
</Button> | |||
) : ( | |||
<Button | |||
color="inherit" | |||
disabled={activeStep === 0} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
variant="h5" | |||
> | |||
<Typography variant="h5">返回</Typography> | |||
</Button> | |||
) | |||
} | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
{activeStep === totalSteps() - 2 ? | |||
( | |||
<Button variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Typography variant="h5">提交</Typography> | |||
</Button> | |||
) | |||
} | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
{activeStep === totalSteps() - 2 ? | |||
) : (activeStep === totalSteps() - 1 ? | |||
( | |||
<Button variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
提交 | |||
<Button variant="outlined" color="inherit" | |||
disabled={true} sx={{ mr: 1 }}> | |||
<Typography variant="h5">提交</Typography> | |||
</Button> | |||
) : ( activeStep === totalSteps() - 1 ? | |||
( | |||
<Button variant="outlined" color="inherit" | |||
disabled={true} sx={{ mr: 1 }}> | |||
提交 | |||
</Button> | |||
): | |||
( | |||
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Button disabled={!updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
繼續 | |||
</Button> | |||
) | |||
) : | |||
( | |||
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Button disabled={!updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Typography variant="h5">繼續</Typography> | |||
</Button> | |||
) | |||
)} | |||
{/* {activeStep !== steps.length && | |||
{/* {activeStep !== steps.length && | |||
(completed[activeStep] ? ( | |||
<Typography variant="caption" sx={{ display: 'inline-block' }}> | |||
Step {activeStep + 1} already completed | |||
@@ -189,12 +191,12 @@ | |||
: 'Complete Step'} | |||
</Button> | |||
))} */} | |||
</Stack> | |||
</React.Fragment> | |||
)} | |||
</Stack > | |||
// </AuthWrapper> | |||
); | |||
}; | |||
export default BusRegister; | |||
</Stack> | |||
</React.Fragment> | |||
)} | |||
</Stack > | |||
// </AuthWrapper> | |||
); | |||
}; | |||
export default BusRegister; |
@@ -1,182 +1,182 @@ | |||
// import { Link } from 'react-router-dom'; | |||
import React,{useState | |||
// ,useEffect | |||
} from 'react'; | |||
// import { Link } from 'react-router-dom'; | |||
import React, { | |||
useState | |||
// ,useEffect | |||
} from 'react'; | |||
// material-ui | |||
import { | |||
Stepper, | |||
Step, | |||
StepButton, | |||
// Grid, | |||
Stack, | |||
Typography, | |||
Button, | |||
// material-ui | |||
import { | |||
Stepper, | |||
Step, | |||
StepButton, | |||
// Grid, | |||
Stack, | |||
Typography, | |||
Button, | |||
} from '@mui/material'; | |||
import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
} from '@mui/material'; | |||
import VisibilityIcon from '@mui/icons-material/Visibility'; | |||
// project import | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from '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" | |||
} | |||
// project import | |||
import Loadable from 'components/Loadable'; | |||
import { lazy } from '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", | |||
}, | |||
"& .Mui-completed": { | |||
"&.MuiStepIcon-root": { | |||
color: "secondary.main", | |||
fontSize: "2rem", | |||
}, | |||
"& .MuiStepConnector-line": { | |||
borderColor: "secondary.main" | |||
} | |||
"& .MuiStepConnector-line": { | |||
borderColor: "secondary.main" | |||
} | |||
} | |||
const steps = ['個人資料', '預覽', '完成提交']; | |||
} | |||
const steps = ['個人資料', '預覽', '完成提交']; | |||
const Register = () => { | |||
const [activeStep, setActiveStep] = useState(0); | |||
const [completed, setCompleted] = useState([false]); | |||
const [updateValid, setUpdateValid] = useState(false); | |||
const Register = () => { | |||
const [activeStep, setActiveStep] = useState(0); | |||
const [completed, setCompleted] = useState([false]); | |||
const [updateValid, setUpdateValid] = useState(false); | |||
const totalSteps = () => { | |||
return steps.length; | |||
}; | |||
const totalSteps = () => { | |||
return steps.length; | |||
}; | |||
const completedSteps = () => { | |||
return Object.keys(completed).length; | |||
}; | |||
const completedSteps = () => { | |||
return Object.keys(completed).length; | |||
}; | |||
const isLastStep = () => { | |||
return activeStep === totalSteps() - 1; | |||
}; | |||
const isLastStep = () => { | |||
return activeStep === totalSteps() - 1; | |||
}; | |||
const allStepsCompleted = () => { | |||
return completedSteps() === totalSteps(); | |||
}; | |||
const allStepsCompleted = () => { | |||
return completedSteps() === totalSteps(); | |||
}; | |||
const handleNext = () => { | |||
const newActiveStep = | |||
const handleNext = () => { | |||
const newActiveStep = | |||
isLastStep() && !allStepsCompleted() | |||
? // It's the last step, but not all steps have been completed, | |||
// find the first step that has been completed | |||
steps.findIndex((step, i) => !(i in completed)) | |||
: activeStep + 1; | |||
setActiveStep(newActiveStep); | |||
scrollToTop(); | |||
}; | |||
const handleBack = () => { | |||
scrollToTop(); | |||
setActiveStep((prevActiveStep) => prevActiveStep - 1); | |||
}; | |||
? // It's the last step, but not all steps have been completed, | |||
// find the first step that has been completed | |||
steps.findIndex((step, i) => !(i in completed)) | |||
: activeStep + 1; | |||
setActiveStep(newActiveStep); | |||
scrollToTop(); | |||
}; | |||
const scrollToTop = () => { | |||
window.scrollTo(0,0); | |||
}; | |||
const handleBack = () => { | |||
scrollToTop(); | |||
setActiveStep((prevActiveStep) => prevActiveStep - 1); | |||
}; | |||
const handleReset = () => { | |||
setActiveStep(0); | |||
setCompleted({}); | |||
}; | |||
const scrollToTop = () => { | |||
window.scrollTo(0, 0); | |||
}; | |||
return( | |||
// <AuthWrapper> | |||
<Stack sx={{ width: '100%',fontSize: '2rem',paddingTop: '65px'}} 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)} | |||
> | |||
{label} | |||
</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)} | |||
> | |||
{label} | |||
</StepButton>) | |||
} | |||
const handleReset = () => { | |||
setActiveStep(0); | |||
setCompleted({}); | |||
}; | |||
</Step> | |||
))} | |||
</Stepper> | |||
{allStepsCompleted() ? ( | |||
<React.Fragment> | |||
<Typography sx={{ mt: 2, mb: 1 }}> | |||
All steps completed - you're finished | |||
</Typography> | |||
<Stack direction="row" sx={{ pt: 2 }}> | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
<Button onClick={handleReset}>Reset</Button> | |||
</Stack> | |||
</React.Fragment> | |||
) : ( | |||
<React.Fragment> | |||
<AuthWrapper> | |||
<CustomFormWizard setUpdateValid={setUpdateValid} step={activeStep} /> | |||
{/* <CustomFormWizard step={activeStep} /> */} | |||
</AuthWrapper> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
{ activeStep === 2|| activeStep === 0? ( | |||
<Button | |||
color="inherit" | |||
disabled={true} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
return ( | |||
// <AuthWrapper> | |||
<Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '65px', 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)} | |||
> | |||
返回 | |||
</Button> | |||
):( | |||
<Button | |||
color="inherit" | |||
disabled={activeStep === 0} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
<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> | |||
))} | |||
</Stepper> | |||
{allStepsCompleted() ? ( | |||
<React.Fragment> | |||
<Typography variant="h4" sx={{ mt: 2, mb: 1 }}> | |||
All steps completed - you're finished | |||
</Typography> | |||
<Stack direction="row" sx={{ pt: 2 }}> | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
<Button onClick={handleReset}><Typography variant="h5">Reset</Typography></Button> | |||
</Stack> | |||
</React.Fragment> | |||
) : ( | |||
<React.Fragment> | |||
<AuthWrapper> | |||
<CustomFormWizard setUpdateValid={setUpdateValid} step={activeStep} /> | |||
{/* <CustomFormWizard step={activeStep} /> */} | |||
</AuthWrapper> | |||
<Stack direction="row" sx={{ pb: 2 }}> | |||
{activeStep === 2 || activeStep === 0 ? ( | |||
<Button | |||
color="inherit" | |||
disabled={true} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
> | |||
<Typography variant="h5">返回</Typography> | |||
</Button> | |||
) : ( | |||
<Button | |||
color="inherit" | |||
disabled={activeStep === 0} | |||
onClick={handleBack} | |||
sx={{ mr: 1 }} | |||
> | |||
<Typography variant="h5">返回</Typography> | |||
</Button> | |||
) | |||
} | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
{activeStep === totalSteps() - 2 ? | |||
( | |||
<Button variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Typography variant="h5">提交</Typography> | |||
</Button> | |||
) | |||
} | |||
<Stack sx={{ flex: '1 1 auto' }} /> | |||
{activeStep === totalSteps() - 2 ? | |||
) : (activeStep === totalSteps() - 1 ? | |||
( | |||
<Button variant="outlined" color="inherit" | |||
disabled={true} sx={{ mr: 1 }}> | |||
<Typography variant="h5">提交</Typography> | |||
</Button> | |||
) : | |||
( | |||
<Button variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
提交 | |||
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Button disabled={!updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Typography variant="h5">繼續</Typography> | |||
</Button> | |||
) : ( activeStep === totalSteps() - 1 ? | |||
( | |||
<Button variant="outlined" color="inherit" | |||
disabled={true} sx={{ mr: 1 }}> | |||
提交 | |||
</Button> | |||
): | |||
( | |||
// <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
<Button disabled={!updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}> | |||
繼續 | |||
</Button> | |||
) | |||
) | |||
)} | |||
{/* {activeStep !== steps.length && | |||
{/* {activeStep !== steps.length && | |||
(completed[activeStep] ? ( | |||
<Typography variant="caption" sx={{ display: 'inline-block' }}> | |||
Step {activeStep + 1} already completed | |||
@@ -188,12 +188,12 @@ | |||
: 'Complete Step'} | |||
</Button> | |||
))} */} | |||
</Stack> | |||
</React.Fragment> | |||
)} | |||
</Stack > | |||
// </AuthWrapper> | |||
); | |||
}; | |||
</Stack> | |||
</React.Fragment> | |||
)} | |||
</Stack > | |||
// </AuthWrapper> | |||
); | |||
}; | |||
export default Register; | |||
export default Register; |
@@ -7,14 +7,11 @@ import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png'; | |||
import banner from 'assets/images/bg_ml.jpg'; | |||
import { Stack } from '../../../node_modules/@mui/material/index'; | |||
// ================================|| LOGIN ||================================ // | |||
const RegisterCustom = () => ( | |||
<Stack justifyContent="center" sx={{ minHeight: '100vh' }}> | |||
<Stack justifyContent="center" sx={{ minHeight: '100vh', bgcolor: 'backgroundColor.default' }}> | |||
<img src={banner} alt="banner" width="100%" height="200px"/> | |||
<center> | |||
<Card | |||
@@ -24,8 +21,10 @@ const RegisterCustom = () => ( | |||
'& > *': { | |||
flexGrow: 1, | |||
flexBasis: '50%' | |||
} | |||
}, | |||
backgroundColor: "secondary" | |||
}} | |||
> | |||
<Box alignItems="center"> | |||
<Grid container> | |||
@@ -38,7 +37,7 @@ const RegisterCustom = () => ( | |||
<Grid container > | |||
<Grid item xs={12} md={6} sx={{ borderRight: 1 , borderColor: 'grey.500' }}> | |||
<Typography mb={4} variant="h3">個人用戶</Typography> | |||
<Button variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>以「智方便」繼續</Button> | |||
<Button variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}><Typography variant="h5">以「智方便」繼續</Typography></Button> | |||
<Box mt={4} ml={2} mr={2} bgcolor="grey.100" p={1.5} > | |||
<Typography textAlign='justify' variant="body1" display="block" gutterBottom> | |||
@@ -50,7 +49,7 @@ const RegisterCustom = () => ( | |||
<Typography m={5}>或</Typography> | |||
<Button href="/registerFrom" variant="contained">申請個人用戶</Button> | |||
<Button href="/registerFrom" variant="contained"><Typography variant="h5">申請個人用戶</Typography></Button> | |||
<Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||
需上載身份證明文件數碼檔案以進行網上申請。 | |||
@@ -59,7 +58,7 @@ const RegisterCustom = () => ( | |||
</Grid> | |||
<Grid item xs={12} md={6} sx={{ borderLeft: 1 ,borderColor: 'grey.500' }}> | |||
<Typography mb={4} variant="h3">機構/公司用戶</Typography> | |||
<Button href="/registerFromOrganization" variant="contained">申請機構/公司用戶</Button> | |||
<Button href="/registerFromOrganization" variant="contained" sx={{mt:0.5}}><Typography variant="h5">申請機構/公司用戶</Typography></Button> | |||
<Typography ml={4} mr={4} mt={4} variant="body1" display="block" sx={{fontWeight: 'bold'}} gutterBottom> | |||
需上載以下任何一份證明文件以進行網上申請。 | |||
<br/>如:商業登記證;專業執業證書 | |||
@@ -4,8 +4,8 @@ import React, { | |||
lazy | |||
} from 'react'; | |||
import { Link as RouterLink } from 'react-router-dom'; | |||
import {useNavigate} from 'react-router-dom'; | |||
import {useForm,} from 'react-hook-form' | |||
import { useNavigate } from 'react-router-dom'; | |||
import { useForm, } from 'react-hook-form' | |||
// material-ui | |||
import { | |||
@@ -26,7 +26,7 @@ import { | |||
// third party | |||
import * as yup from 'yup'; | |||
import { useFormik,FormikProvider } from 'formik'; | |||
import { useFormik, FormikProvider } from 'formik'; | |||
// project import | |||
//import FirebaseSocial from './FirebaseSocial'; | |||
@@ -38,8 +38,8 @@ const PasswordAlertDialog = Loadable(lazy(() => import('./PasswordAlertDialog')) | |||
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons'; | |||
// import axios from "axios"; | |||
import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png'; | |||
import {useDispatch} from "react-redux"; | |||
import {handleLogin} from "auth/index"; | |||
import { useDispatch } from "react-redux"; | |||
import { handleLogin } from "auth/index"; | |||
import useJwt from "../../../auth/jwt/useJwt"; | |||
import { handleLogoutFunction } from 'auth/index'; | |||
// ============================|| FIREBASE - LOGIN ||============================ // | |||
@@ -64,11 +64,11 @@ const AuthLoginCustom = () => { | |||
}; | |||
const tryLogin = () => { | |||
if(isValid){ | |||
dispatch(handleLogoutFunction()); | |||
if (isValid) { | |||
dispatch(handleLogoutFunction()); | |||
// setSumitting(true) | |||
useJwt | |||
.login({username: values.username, password: values.password}) | |||
.login({ username: values.username, password: values.password }) | |||
.then((response) => { | |||
console.log(response) | |||
const userData = { | |||
@@ -82,7 +82,7 @@ const AuthLoginCustom = () => { | |||
creditor: response.data.creditor, | |||
//avatar: require('src/assets/images/users/avatar-3.png').default, | |||
} | |||
const data = {...userData, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken} | |||
const data = { ...userData, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken } | |||
// setSuccess(true) | |||
dispatch(handleLogin(data)) | |||
navigate('/dashboard'); | |||
@@ -96,42 +96,41 @@ const AuthLoginCustom = () => { | |||
setErrorMassage(error.response.data.error) | |||
setOpen(true) | |||
}); | |||
}else{ | |||
} else { | |||
setOpen(true) | |||
} | |||
} | |||
const formik = useFormik({ | |||
initialValues:({ | |||
username: '', | |||
password: '', | |||
submit: null | |||
initialValues: ({ | |||
username: '', | |||
password: '', | |||
submit: null | |||
}), | |||
validationSchema:yup.object().shape({ | |||
// username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'), | |||
username: yup.string().required('請輸入用戶名稱'), | |||
password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼') | |||
.matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') | |||
.matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') | |||
.matches(/^(?=.*[0-9])/, '請包括最少1個數字') | |||
.matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'), | |||
validationSchema: yup.object().shape({ | |||
// username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'), | |||
username: yup.string().required('請輸入用戶名稱'), | |||
password: yup.string().min(8, '請輸入最少8位密碼').required('請輸入密碼') | |||
.matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') | |||
.matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') | |||
.matches(/^(?=.*[0-9])/, '請包括最少1個數字') | |||
.matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'), | |||
}), | |||
}); | |||
const checkDataField = (data)=> { | |||
if (data.username !==""&& | |||
data.password !==""&& | |||
handlePassword(data.password) | |||
// &&handle6Digi(data.username) | |||
) | |||
{ | |||
setisValid(true) | |||
setIsButtonDisabled(false); | |||
return isValid | |||
}else{ | |||
setisValid(false) | |||
setIsButtonDisabled(true); | |||
return isValid | |||
const checkDataField = (data) => { | |||
if (data.username !== "" && | |||
data.password !== "" && | |||
handlePassword(data.password) | |||
// &&handle6Digi(data.username) | |||
) { | |||
setisValid(true) | |||
setIsButtonDisabled(false); | |||
return isValid | |||
} else { | |||
setisValid(false) | |||
setIsButtonDisabled(true); | |||
return isValid | |||
} | |||
}; | |||
@@ -143,17 +142,17 @@ const AuthLoginCustom = () => { | |||
var numbers = /[0-9]/g; | |||
var symbol = /^(?=.*[!@#%&])/; | |||
if (!new_pass.match(lowerCase)) { | |||
return false; | |||
return false; | |||
} else if (!new_pass.match(upperCase)) { | |||
return false; | |||
return false; | |||
} else if (!new_pass.match(numbers)) { | |||
return false; | |||
return false; | |||
} else if (!new_pass.match(symbol)) { | |||
return false; | |||
return false; | |||
} else if (new_pass.length < 8) { | |||
return false; | |||
} else { | |||
return true; | |||
return true; | |||
} | |||
} | |||
@@ -162,123 +161,123 @@ const AuthLoginCustom = () => { | |||
}; | |||
const { values } = formik | |||
useEffect(() => { | |||
checkDataField(values) | |||
}, [values]) | |||
useEffect(() => { | |||
checkDataField(values) | |||
}, [values]) | |||
const {handleSubmit} = useForm({}) | |||
const { handleSubmit } = useForm({}) | |||
return ( | |||
<FormikProvider value={formik}> | |||
<form onSubmit={handleSubmit(tryLogin)}> | |||
<Grid container spacing={3}> | |||
<Grid item xs={12}> | |||
<Stack spacing={1}> | |||
<InputLabel htmlFor="email-login">用戶登入名稱</InputLabel> | |||
<OutlinedInput | |||
id="username" | |||
name="username" | |||
onChange={formik.handleChange} | |||
placeholder="" | |||
fullWidth | |||
value={formik.values.username} | |||
error={Boolean(formik.touched.username && formik.errors.username)} | |||
onBlur={formik.handleBlur} | |||
inputProps={{ | |||
maxLength: 50, | |||
onKeyDown: (e) => { | |||
if (e.key === 'Enter') { | |||
e.preventDefault(); | |||
} | |||
}, | |||
<FormikProvider value={formik}> | |||
<form onSubmit={handleSubmit(tryLogin)}> | |||
<Grid container spacing={3}> | |||
<Grid item xs={12}> | |||
<Stack spacing={1}> | |||
<InputLabel htmlFor="email-login"><Typography variant="h5">用戶登入名稱</Typography></InputLabel> | |||
<OutlinedInput | |||
id="username" | |||
name="username" | |||
onChange={formik.handleChange} | |||
placeholder="" | |||
fullWidth | |||
value={formik.values.username} | |||
error={Boolean(formik.touched.username && formik.errors.username)} | |||
onBlur={formik.handleBlur} | |||
inputProps={{ | |||
maxLength: 50, | |||
onKeyDown: (e) => { | |||
if (e.key === 'Enter') { | |||
e.preventDefault(); | |||
} | |||
}, | |||
}} | |||
/> | |||
{formik.touched.username && formik.errors.username && ( | |||
<FormHelperText error id="standard-weight-helper-text-username-login"> | |||
{formik.errors.username} | |||
</FormHelperText> | |||
)} | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack spacing={1}> | |||
<InputLabel htmlFor="password-login">密碼</InputLabel> | |||
<OutlinedInput | |||
fullWidth | |||
id="password-login" | |||
type={showPassword ? 'text' : 'password'} | |||
name="password" | |||
value={formik.values.password} | |||
onChange={formik.handleChange} | |||
onBlur={formik.handleBlur} | |||
error={Boolean(formik.touched.password && formik.errors.password)} | |||
endAdornment={ | |||
<InputAdornment position="end"> | |||
<IconButton | |||
aria-label="toggle password visibility" | |||
onClick={handleClickShowPassword} | |||
onMouseDown={handleMouseDownPassword} | |||
edge="end" | |||
size="large" | |||
> | |||
{showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||
</IconButton> | |||
</InputAdornment> | |||
} | |||
placeholder="" | |||
/> | |||
{formik.touched.password && formik.errors.password && ( | |||
<FormHelperText error id="standard-weight-helper-text-password-login"> | |||
{formik.errors.password} | |||
</FormHelperText> | |||
)} | |||
</Stack> | |||
</Grid> | |||
/> | |||
{formik.touched.username && formik.errors.username && ( | |||
<FormHelperText error id="standard-weight-helper-text-username-login"> | |||
{formik.errors.username} | |||
</FormHelperText> | |||
)} | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack spacing={1}> | |||
<InputLabel htmlFor="password-login"><Typography variant="h5">密碼</Typography></InputLabel> | |||
<OutlinedInput | |||
fullWidth | |||
id="password-login" | |||
type={showPassword ? 'text' : 'password'} | |||
name="password" | |||
value={formik.values.password} | |||
onChange={formik.handleChange} | |||
onBlur={formik.handleBlur} | |||
error={Boolean(formik.touched.password && formik.errors.password)} | |||
endAdornment={ | |||
<InputAdornment position="end"> | |||
<IconButton | |||
aria-label="toggle password visibility" | |||
onClick={handleClickShowPassword} | |||
onMouseDown={handleMouseDownPassword} | |||
edge="end" | |||
size="large" | |||
> | |||
{showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />} | |||
</IconButton> | |||
</InputAdornment> | |||
} | |||
placeholder="" | |||
/> | |||
{formik.touched.password && formik.errors.password && ( | |||
<FormHelperText error id="standard-weight-helper-text-password-login"> | |||
{formik.errors.password} | |||
</FormHelperText> | |||
)} | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<AnimateButton> | |||
<Button disableElevation disabled={isButtonDisabled} | |||
fullWidth size="large" type="submit" variant="contained" color="primary" | |||
sx={{ | |||
"&.Mui-disabled": { | |||
background: "#bbdefb", | |||
color: "#fff", | |||
border: "2px solid", | |||
borderColor: "#e7e7e7" | |||
} | |||
}}> | |||
登錄 | |||
</Button> | |||
</AnimateButton> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Link variant="h6" component={RouterLink} to="" color="primary"> | |||
<Typography align="center"> | |||
<Grid item xs={12}> | |||
<AnimateButton> | |||
<Button disableElevation disabled={isButtonDisabled} | |||
fullWidth size="large" type="submit" variant="contained" color="primary" | |||
sx={{ | |||
"&.Mui-disabled": { | |||
background: "#bbdefb", | |||
color: "#fff", | |||
border: "2px solid", | |||
borderColor: "#e7e7e7" | |||
} | |||
}}> | |||
<Typography variant="h5">登錄</Typography> | |||
</Button> | |||
</AnimateButton> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Link component={RouterLink} to="" color="primary"> | |||
<Typography align="center" variant="h6"> | |||
忘記密碼? | |||
</Typography> | |||
</Link> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Button fullWidth size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>智方便登入</Button> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Link href="#">了解更多智方便</Link> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Button fullWidth size="large" variant="outlined" href="/register" >建立/重新啟動帳戶</Button> | |||
</Stack> | |||
</Grid> | |||
</Typography> | |||
</Link> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Button fullWidth size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}><Typography variant="h5">智方便登入</Typography></Button> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Link href="#"><Typography align="center" variant="h6">了解更多智方便</Typography></Link> | |||
</Stack> | |||
</Grid> | |||
<Grid item xs={12}> | |||
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}> | |||
<Button fullWidth size="large" variant="outlined" href="/register" ><Typography variant="h5">建立/重新啟動帳戶</Typography></Button> | |||
</Stack> | |||
</Grid> | |||
<PasswordAlertDialog open={open} handleClose={handleClose} errorMassage={errorMassage}/> | |||
</form> | |||
</FormikProvider> | |||
</Grid> | |||
<PasswordAlertDialog open={open} handleClose={handleClose} errorMassage={errorMassage} /> | |||
</form> | |||
</FormikProvider> | |||
); | |||
}; | |||
@@ -6,17 +6,18 @@ import { | |||
// GridRowModes | |||
} from "@mui/x-data-grid"; | |||
// import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; | |||
import {useEffect} from "react"; | |||
import { useEffect } from "react"; | |||
// import {useNavigate} from "react-router-dom"; | |||
// import { useTheme } from '@mui/material/styles'; | |||
import { | |||
Box, | |||
Stack | |||
Stack, | |||
Typography | |||
} from '@mui/material'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function PreviewUploadFileTable({recordList,}) { | |||
export default function PreviewUploadFileTable({ recordList, }) { | |||
const [rows, setRows] = React.useState(recordList); | |||
const [rowModesModel] = React.useState({}); | |||
// const theme = useTheme(); | |||
@@ -30,8 +31,10 @@ export default function PreviewUploadFileTable({recordList,}) { | |||
function NoRowsOverlay() { | |||
return ( | |||
<Stack height="100%" alignItems="center" justifyContent="center"> | |||
沒有上傳檔案 | |||
{/* <pre>(rows={[]})</pre> */} | |||
<Typography variant="h6"> | |||
沒有上傳檔案 | |||
</Typography> | |||
{/* <pre>(rows={[]})</pre> */} | |||
</Stack> | |||
); | |||
} | |||
@@ -71,17 +74,17 @@ export default function PreviewUploadFileTable({recordList,}) { | |||
{ | |||
id: 'name', | |||
field: 'name', | |||
headerName: '檔案名稱', | |||
headerName: <Typography variant="h6">檔案名稱</Typography>, | |||
flex: 1, | |||
}, | |||
{ | |||
id: 'size', | |||
field: 'size', | |||
headerName: '檔案大小', | |||
headerName: <Typography variant="h6">檔案大小</Typography>, | |||
valueGetter: (params) => { | |||
// console.log(params) | |||
return Math.ceil(params.value/1024)+" KB"; | |||
}, | |||
return Math.ceil(params.value / 1024) + " KB"; | |||
}, | |||
flex: 1, | |||
}, | |||
]; | |||
@@ -92,7 +95,7 @@ export default function PreviewUploadFileTable({recordList,}) { | |||
rows={rows} | |||
columns={columns} | |||
editMode="row" | |||
sx={{border:1}} | |||
sx={{ border: 1 }} | |||
rowModesModel={rowModesModel} | |||
disablePagination | |||
components={{ NoRowsOverlay, }} | |||
@@ -6,19 +6,20 @@ import { | |||
GridRowModes | |||
} from "@mui/x-data-grid"; | |||
import RemoveCircleOutlineIcon from '@mui/icons-material/RemoveCircleOutline'; | |||
import {useEffect} from "react"; | |||
import { useEffect } from "react"; | |||
// import {useNavigate} from "react-router-dom"; | |||
// import { useTheme } from '@mui/material/styles'; | |||
import { | |||
Box, | |||
Stack | |||
Stack, | |||
Typography | |||
} from '@mui/material'; | |||
// ==============================|| EVENT TABLE ||============================== // | |||
export default function UploadFileTable({recordList, setUpdateRows,}) { | |||
export default function UploadFileTable({ recordList, setUpdateRows, }) { | |||
const [rows, setRows] = React.useState(recordList); | |||
const [rowModesModel,setRowModesModel] = React.useState({}); | |||
const [rowModesModel, setRowModesModel] = React.useState({}); | |||
// const theme = useTheme(); | |||
// const navigate = useNavigate() | |||
@@ -31,8 +32,10 @@ export default function UploadFileTable({recordList, setUpdateRows,}) { | |||
function NoRowsOverlay() { | |||
return ( | |||
<Stack height="100%" alignItems="center" justifyContent="center"> | |||
沒有上傳檔案 | |||
{/* <pre>(rows={[]})</pre> */} | |||
<Typography variant="h6"> | |||
沒有上傳檔案 | |||
</Typography> | |||
{/* <pre>(rows={[]})</pre> */} | |||
</Stack> | |||
); | |||
} | |||
@@ -58,11 +61,11 @@ export default function UploadFileTable({recordList, setUpdateRows,}) { | |||
width: 30, | |||
cellClassName: 'actions', | |||
// hide:true, | |||
getActions: ({id}) => { | |||
getActions: ({ id }) => { | |||
return [ | |||
<GridActionsCellItem | |||
key="OutSave" | |||
icon={<RemoveCircleOutlineIcon/>} | |||
icon={<RemoveCircleOutlineIcon />} | |||
label="delete" | |||
className="textPrimary" | |||
onClick={handleCancelClick(id)} | |||
@@ -73,17 +76,17 @@ export default function UploadFileTable({recordList, setUpdateRows,}) { | |||
{ | |||
id: 'name', | |||
field: 'name', | |||
headerName: '檔案名稱', | |||
headerName: <Typography variant="h6">檔案名稱</Typography>, | |||
flex: 1, | |||
}, | |||
{ | |||
id: 'size', | |||
field: 'size', | |||
headerName: '檔案大小', | |||
headerName: <Typography variant="h6">檔案大小</Typography>, | |||
valueGetter: (params) => { | |||
// console.log(params) | |||
return Math.ceil(params.value/1024)+" KB"; | |||
}, | |||
return Math.ceil(params.value / 1024) + " KB"; | |||
}, | |||
flex: 1, | |||
}, | |||
]; | |||
@@ -94,7 +97,7 @@ export default function UploadFileTable({recordList, setUpdateRows,}) { | |||
rows={rows} | |||
columns={columns} | |||
editMode="row" | |||
sx={{border:1}} | |||
sx={{ border: 1 }} | |||
rowModesModel={rowModesModel} | |||
disablePagination | |||
components={{ NoRowsOverlay, }} | |||
@@ -83,6 +83,9 @@ const Palette = (mode) => { | |||
dark: '#b0671e', | |||
contrastText: '#fff', | |||
}, | |||
backgroundColor: { | |||
default: '#F2F2F2' | |||
} | |||
} | |||
}); | |||
}; | |||
@@ -9,30 +9,35 @@ const Typography = (fontFamily) => ({ | |||
fontWeightBold: 600, | |||
h1: { | |||
fontWeight: 600, | |||
fontSize: '2.375rem', | |||
fontSize: '2.5rem', | |||
lineHeight: 1.21 | |||
}, | |||
h2: { | |||
fontWeight: 600, | |||
fontSize: '1.875rem', | |||
fontSize: '2.375rem', | |||
lineHeight: 1.27 | |||
}, | |||
h3: { | |||
fontWeight: 600, | |||
fontSize: '1.5rem', | |||
fontSize: '1.875rem', | |||
lineHeight: 1.33 | |||
}, | |||
h4: { | |||
fontWeight: 600, | |||
fontSize: '1.25rem', | |||
fontSize: '1.5rem', | |||
lineHeight: 1.4 | |||
}, | |||
h5: { | |||
fontWeight: 600, | |||
fontSize: '1rem', | |||
lineHeight: 1.5 | |||
fontSize: '1.275rem', | |||
lineHeight: 1.66 | |||
}, | |||
h6: { | |||
fontWeight: 600, | |||
fontSize: '1.1rem', | |||
lineHeight: 1.57 | |||
}, | |||
h7: { | |||
fontWeight: 400, | |||
fontSize: '0.875rem', | |||
lineHeight: 1.57 | |||
@@ -43,23 +48,39 @@ const Typography = (fontFamily) => ({ | |||
lineHeight: 1.66 | |||
}, | |||
body1: { | |||
fontSize: '0.875rem', | |||
fontSize: '1.1rem', | |||
fontWeight: 600, | |||
lineHeight: 1.57 | |||
}, | |||
body2: { | |||
fontSize: '0.75rem', | |||
fontSize: '1.2rem', | |||
lineHeight: 1.66 | |||
}, | |||
subtitle1: { | |||
fontSize: '0.875rem', | |||
fontSize: '1rem', | |||
fontWeight: 600, | |||
lineHeight: 1.57 | |||
}, | |||
subtitle2: { | |||
fontSize: '0.75rem', | |||
fontSize: '0.8rem', | |||
fontWeight: 500, | |||
lineHeight: 1.66 | |||
}, | |||
headerTitle1: { | |||
fontSize: '1.5rem', | |||
fontWeight: 600, | |||
lineHeight: 1.66 | |||
}, | |||
errorMessage1: { | |||
fontSize: '1rem', | |||
fontWeight: 600, | |||
lineHeight: 1 | |||
}, | |||
step1: { | |||
fontSize: '1.4rem', | |||
fontWeight: 600, | |||
lineHeight: 1 | |||
}, | |||
overline: { | |||
lineHeight: 1.66 | |||
}, | |||
@@ -68,4 +89,4 @@ const Typography = (fontFamily) => ({ | |||
} | |||
}); | |||
export default Typography; | |||
export default Typography; |