| @@ -47,8 +47,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| const location = useLocation(); | |||
| const queryParams = new URLSearchParams(location.search); | |||
| const refId = queryParams.get("refId"); | |||
| const [isFirstInit, setIsFirstInit] = useState(true); | |||
| const params = useParams(); | |||
| const navigate = useNavigate(); | |||
| const ability = useContext(AbilityContext); | |||
| @@ -61,6 +60,8 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| const { setIsUploading } = useContext(UploadContext); | |||
| const [refClient, setRefClient] = useState({}); | |||
| const [consultantComboList, setConsultantComboList] = useState([]); | |||
| const [selectedConsultant, setSelectedConsultant] = useState(null); | |||
| const [isFirstInit, setIsFirstInit] = useState(true); | |||
| // Form data | |||
| const { register, getValues, setValue } = useForm(); | |||
| @@ -70,7 +71,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| // Handler to navigate back | |||
| const returnSearchPage = () => { | |||
| navigate('/search'); | |||
| navigate('/client'); | |||
| } | |||
| const FIXED_HEADER_HEIGHT = 120; // <-- **IMPORTANT: Set this to the height of your actual fixed header in pixels** | |||
| @@ -100,6 +101,15 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| const handleEditClick = () => { | |||
| setIsEditing(true); | |||
| }; | |||
| useEffect(() => { | |||
| if (!isObjEmpty(refClient) && consultantComboList.length > 0 && isFirstInit) { | |||
| const matched = consultantComboList.find(c => c.id === refClient.consultantId); | |||
| setSelectedConsultant(matched || null); | |||
| setValue("consultantId", matched || null); | |||
| setIsFirstInit(false); | |||
| } | |||
| }, [refClient, consultantComboList, isFirstInit]); | |||
| // 1. Earned Income | |||
| const [earnedIncome, setEarnedIncome] = useState({ | |||
| @@ -253,6 +263,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| const handleLiabilitiesChange = (field, value) => { | |||
| setLiabilities(prev => ({ ...prev, [field]: value })); | |||
| }; | |||
| const totalLiabilitiesCurrent = (parseFloat(liabilities.personalLoansCurrent) || 0) + | |||
| (parseFloat(liabilities.mortgagesCurrent) || 0) + | |||
| (parseFloat(liabilities.marginAccountCurrent) || 0) + | |||
| @@ -292,6 +303,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| }; | |||
| const formatNumberForDisplay = (num) => { | |||
| console.log(num); | |||
| // 1. Handle null, undefined, or empty string input gracefully (return as is) | |||
| if (num === null || num === undefined || num === '') return ''; | |||
| @@ -322,6 +334,8 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| return formatted + '.'; | |||
| } | |||
| } | |||
| console.log(formatted); | |||
| return formatted; | |||
| }; | |||
| @@ -392,9 +406,31 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| setValue("firstname", refClient.firstname); | |||
| setValue("email", refClient.email); | |||
| setValue("phone1", refClient.phone1); | |||
| setValue("phone1Code", refClient.phone1Code); | |||
| setValue("phone2", refClient.phone2); | |||
| setValue("remarks", refClient.remarks); | |||
| setValue("caseManagerId", 1); | |||
| setValue("crAddressRoom", refClient.crAddressRoom); | |||
| setValue("crAddressFloor", refClient.crAddressFloor); | |||
| setValue("crAddressBuilding", refClient.crAddressBuilding); | |||
| setValue("crAddressStreet", refClient.crAddressStreet); | |||
| setValue("crAddressStreet", refClient.crAddressStreet); | |||
| setValue("crAddressArea", refClient.crAddressArea); | |||
| setValue("crAddressCity", refClient.crAddressCity); | |||
| setValue("crAddressCountry", refClient.crAddressCountry); | |||
| setValue("crAddressPostalCode", refClient.crAddressPostalCode); | |||
| setValue("corAddressRoom", refClient.corAddressRoom); | |||
| setValue("corAddressFloor", refClient.corAddressFloor); | |||
| setValue("corAddressBlock", refClient.corAddressBlock); | |||
| setValue("corAddressBuilding", refClient.corAddressBuilding); | |||
| setValue("corAddressStreet", refClient.corAddressStreet); | |||
| setValue("corAddressArea", refClient.corAddressArea); | |||
| setValue("corAddressCity", refClient.corAddressCity); | |||
| setValue("corAddressCountry", refClient.corAddressCountry); | |||
| setValue("corAddressPostalCode", refClient.corAddressPostalCode); | |||
| earnedIncome.salaryCurrent = refClient.salaryCurrent; | |||
| earnedIncome.salaryLast = refClient.salaryLast; | |||
| earnedIncome.bonusCurrent = refClient.bonusCurrent; | |||
| @@ -412,9 +448,9 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| unearnedIncome.investmentIncomeLast = refClient.investmentIncomeLast; | |||
| unearnedIncome.otherUnearnedCurrent = refClient.otherUnearnedCurrent; | |||
| unearnedIncome.otherUnearnedLast = refClient.otherUnearnedLast; | |||
| unearnedIncome.mortgageCurrent = refClient.mortgageCurrent; | |||
| unearnedIncome.mortgageLast = refClient.mortgageLast; | |||
| expenditure.mortgageCurrent = refClient.mortgageCurrent; | |||
| expenditure.mortgageLast = refClient.mortgageLast; | |||
| expenditure.rentCurrent = refClient.rentCurrent; | |||
| expenditure.rentLast = refClient.rentLast; | |||
| expenditure.schoolingCurrent = refClient.schoolingCurrent; | |||
| @@ -500,6 +536,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| data["firstname"] = values.firstname; | |||
| data["email"] = values.email; | |||
| data["phone1"] = values.phone1; | |||
| data["phone1Code"] = values.phone1Code; | |||
| data["phone2"] = values.phone2; | |||
| data["remarks"] = values.remarks; | |||
| data["caseManagerId"] = 1; | |||
| @@ -514,6 +551,15 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| data["crAddressCity"] = values.crAddressCity; | |||
| data["crAddressCountry"] = values.crAddressCountry; | |||
| data["crAddressPostalCode"] = values.crAddressPostalCode; | |||
| data["corAddressRoom"] = values.corAddressRoom; | |||
| data["corAddressFloor"] = values.corAddressFloor; | |||
| data["corAddressBlock"] = values.corAddressBlock; | |||
| data["corAddressBuilding"] = values.corAddressBuilding; | |||
| data["corAddressStreet"] = values.corAddressStreet; | |||
| data["corAddressArea"] = values.corAddressArea; | |||
| data["corAddressCity"] = values.corAddressCity; | |||
| data["corAddressCountry"] = values.corAddressCountry; | |||
| data["corAddressPostalCode"] = values.corAddressPostalCode; | |||
| data = { | |||
| ...data, // Keep all existing header fields | |||
| @@ -736,10 +782,23 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| Phone Number: | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <Grid item xs={1} sm={1} md={1} lg={1.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| inputProps={{ maxLength: 5 }} | |||
| size="small" | |||
| {...register("phone1Code", { value: refClient.phote1Code })} | |||
| id='phone1Code' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| <Grid item xs={0.1} sm={0.1} md={0.1} lg={0.15}> | |||
| </Grid> | |||
| <Grid item xs={6} sm={6} md={6} lg={5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 20 }} | |||
| size="small" | |||
| {...register("phone1", { value: refClient.phone1 })} | |||
| id='phone1' | |||
| @@ -783,11 +842,12 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| options={consultantComboList} | |||
| getOptionLabel={(option) => option.name || ""} | |||
| isOptionEqualToValue={(option, value) => option.id === value.id} | |||
| value={getValues("consultantId") || null} | |||
| onChange={(event, newValue) => { | |||
| setValue('consultantId', newValue || null); | |||
| }} | |||
| renderInput={(params) => ( | |||
| value={selectedConsultant} | |||
| onChange={(e, v) => { | |||
| setSelectedConsultant(v); | |||
| setValue('consultantId', v); } | |||
| } | |||
| renderInput={(params) => ( | |||
| <TextField | |||
| {...params} | |||
| label="Consultant" | |||
| @@ -803,7 +863,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Room): | |||
| Rs. Address(Room): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -823,7 +883,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Floor): | |||
| Rs. Address(Floor): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -843,7 +903,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Block): | |||
| Rs. Address(Block): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -863,7 +923,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Buliding): | |||
| Rs. Address(Buliding): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -883,7 +943,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Street): | |||
| Rs. Address(Street): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -903,7 +963,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Area): | |||
| Rs. Address(Area): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -923,7 +983,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(City): | |||
| Rs. Address(City): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -943,7 +1003,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Country): | |||
| Rs. Address(Country): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -963,7 +1023,7 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Address(Postal Code): | |||
| Rs. Address(Postal Code): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| @@ -979,6 +1039,190 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Room): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressRoom", { value: refClient.corAddressRoom })} | |||
| id='corAddressRoom' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Floor): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressFloor", { value: refClient.corAddressFloor })} | |||
| id='corAddressFloor' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Block): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressBlock", { value: refClient.corAddressBlock })} | |||
| id='corAddressBlock' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Buliding): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressBuilding", { value: refClient.corAddressBuilding })} | |||
| id='corAddressBuilding' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Street): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressStreet", { value: refClient.corAddressStreet })} | |||
| id='corAddressStreet' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Area): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressArea", { value: refClient.corAddressArea })} | |||
| id='corAddressArea' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(City): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressCity", { value: refClient.corAddressCity })} | |||
| id='corAddressCity' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Country): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressCountry", { value: refClient.corAddressCountry })} | |||
| id='corAddressCountry' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| <Grid container alignItems={"center"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, display: 'flex', alignItems: 'center' }}> | |||
| <Typography variant="lionerSize" component="span"> | |||
| Corr. Address(Postal Code): | |||
| </Typography> | |||
| </Grid> | |||
| <Grid item xs={7} sm={7} md={7} lg={6.5}> | |||
| <TextField | |||
| fullWidth | |||
| inputProps={{ maxLength: 50 }} | |||
| size="small" | |||
| {...register("corAddressPostalCode", { value: refClient.corAddressPostalCode })} | |||
| id='corAddressPostalCode' | |||
| disabled={!isEditing} | |||
| autoComplete="off" | |||
| /> | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3, mt: 1 }}> | |||
| <Grid container alignItems={"flex-start"}> | |||
| <Grid item xs={4} sm={4} md={4} lg={4} sx={{ ml: 3, mr: 3, mt: 1, display: 'flex', alignItems: 'flex-start' }}> | |||
| @@ -1002,6 +1246,8 @@ const ClientForm = ({ refClientDetail, isNewRecord, getClientDetail }) => { | |||
| </Grid> | |||
| </Grid> | |||
| </Grid> | |||
| <Grid item xs={12} sm={12} md={12} lg={5.5} sx={{ ml: 3, mr: 3, mb: 3 }}> | |||
| </Grid> | |||
| <Grid> | |||
| {/* ======================================================================= */} | |||
| {/* --- START: EARNED INCOME 薪酬收入 (Image 1) --- */} | |||