| @@ -11,6 +11,10 @@ body, | |||||
| font-family: "Noto Sans HK", "Noto Sans SC"; | font-family: "Noto Sans HK", "Noto Sans SC"; | ||||
| } | } | ||||
| .page-grey { | |||||
| filter: grayscale(100%); | |||||
| } | |||||
| /* Chrome, Safari, Edge, Opera */ | /* Chrome, Safari, Edge, Opera */ | ||||
| input::-webkit-outer-spin-button, | input::-webkit-outer-spin-button, | ||||
| input::-webkit-inner-spin-button { | input::-webkit-inner-spin-button { | ||||
| @@ -1,4 +1,4 @@ | |||||
| import { StrictMode } from 'react'; | |||||
| import { StrictMode, useEffect, useContext } from 'react'; | |||||
| import { createRoot } from 'react-dom/client'; | import { createRoot } from 'react-dom/client'; | ||||
| import { BrowserRouter } from 'react-router-dom'; | import { BrowserRouter } from 'react-router-dom'; | ||||
| import "./assets/style/styles.css" | import "./assets/style/styles.css" | ||||
| @@ -19,7 +19,31 @@ import reportWebVitals from './reportWebVitals'; | |||||
| import { I18nProvider } from "components/I18nProvider"; | import { I18nProvider } from "components/I18nProvider"; | ||||
| import { AutoLogoutProvider } from "components/AutoLogoutProvider"; | import { AutoLogoutProvider } from "components/AutoLogoutProvider"; | ||||
| import { RefreshTokenProvider } from "components/RefreshTokenProvider"; | import { RefreshTokenProvider } from "components/RefreshTokenProvider"; | ||||
| import { SysSettingProvider } from "components/SysSettingProvider"; | |||||
| import { SysSettingProvider, SysContext } from 'components/SysSettingProvider'; | |||||
| import { useLocation } from 'react-router-dom'; | |||||
| function GreyWrapper({ children }) { | |||||
| const location = useLocation(); | |||||
| const { sysSetting } = useContext(SysContext); | |||||
| useEffect(() => { | |||||
| const isLoginPage = location.pathname === '/login'; | |||||
| const enableGrey = sysSetting?.greyLogin === true; | |||||
| if (isLoginPage && enableGrey) { | |||||
| document.body.classList.add('page-grey'); | |||||
| } else { | |||||
| document.body.classList.remove('page-grey'); | |||||
| } | |||||
| return () => { | |||||
| document.body.classList.remove('page-grey'); | |||||
| }; | |||||
| }, [location.pathname, sysSetting?.greyLogin]); | |||||
| return children; | |||||
| } | |||||
| // ==============================|| MAIN - REACT DOM RENDER ||============================== // | // ==============================|| MAIN - REACT DOM RENDER ||============================== // | ||||
| @@ -36,7 +60,9 @@ root.render( | |||||
| <BrowserRouter basename="/"> | <BrowserRouter basename="/"> | ||||
| <RefreshTokenProvider> | <RefreshTokenProvider> | ||||
| <AutoLogoutProvider> | <AutoLogoutProvider> | ||||
| <App /> | |||||
| <GreyWrapper> | |||||
| <App /> | |||||
| </GreyWrapper> | |||||
| </AutoLogoutProvider> | </AutoLogoutProvider> | ||||
| </RefreshTokenProvider> | </RefreshTokenProvider> | ||||
| </BrowserRouter> | </BrowserRouter> | ||||
| @@ -436,6 +436,11 @@ const SearchDemandNoteForm = ({ applySearch, orgComboData, searchCriteria, issue | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | '& .MuiOutlinedInput-root': { height: 40 } | ||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| {...params} | {...params} | ||||
| @@ -191,11 +191,14 @@ const Index = () => { | |||||
| > | > | ||||
| <Typography variant="h5">Upload Files</Typography> | <Typography variant="h5">Upload Files</Typography> | ||||
| <input | <input | ||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| id="uploadFileBtn" | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| aria-label="Upload Excel file (.xlsx)" | |||||
| /> | /> | ||||
| </Button> | </Button> | ||||
| </ThemeProvider> | </ThemeProvider> | ||||
| @@ -172,11 +172,11 @@ const Index = () => { | |||||
| size="large" | size="large" | ||||
| disabled={waitDownload} | disabled={waitDownload} | ||||
| onClick={doExport} | onClick={doExport} | ||||
| aria-label="Export holiday template" | |||||
| > | > | ||||
| <Typography variant="h5">Export</Typography> | <Typography variant="h5">Export</Typography> | ||||
| </Button> | </Button> | ||||
| </ThemeProvider> | </ThemeProvider> | ||||
| {isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ? | {isGrantedAny(["MAINTAIN_GAZETTE_ISSUE"]) ? | ||||
| <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}> | ||||
| <Button | <Button | ||||
| @@ -187,12 +187,14 @@ const Index = () => { | |||||
| > | > | ||||
| <Typography variant="h5">Upload Files</Typography> | <Typography variant="h5">Upload Files</Typography> | ||||
| <input | <input | ||||
| name="file" | |||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| id="uploadFileBtn" | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".xlsx" | |||||
| hidden | |||||
| disabled={waitImport} | |||||
| onChange={readFile} | |||||
| aria-label="Upload Excel file (.xlsx)" | |||||
| /> | /> | ||||
| </Button> | </Button> | ||||
| </ThemeProvider> | </ThemeProvider> | ||||
| @@ -155,6 +155,11 @@ const OrganizationSearchForm = ({ applySearch, onGridReady, searchCriteria }) => | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | '& .MuiOutlinedInput-root': { height: 40 } | ||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| {...params} | {...params} | ||||
| @@ -275,27 +275,26 @@ const FormPanel = ({ formData }) => { | |||||
| /> | /> | ||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <Button | <Button | ||||
| component="label" | component="label" | ||||
| variant="contained" | variant="contained" | ||||
| size="large" | size="large" | ||||
| disabled={attachments.length >= maxUploadsForType(formik.values.groupType)} | |||||
| disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | |||||
| > | > | ||||
| <Typography variant="h5">Upload Files</Typography> | |||||
| <input | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".pdf" | |||||
| hidden | |||||
| disabled={attachments.length >= maxUploadsForType(formik.values.groupType)} | |||||
| onChange={readFile} | |||||
| /> | |||||
| <Typography variant="h5">Upload Files</Typography> | |||||
| <input | |||||
| id="uploadFileBtn" | |||||
| name="file" | |||||
| type="file" | |||||
| accept=".pdf" | |||||
| hidden | |||||
| disabled={attachments.length >= (formik.values.groupType == "Private Bill" ? 2 : 1)} | |||||
| onChange={readFile} | |||||
| aria-label="Upload PDF file" | |||||
| /> | |||||
| </Button> | </Button> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={12}> | <Grid item xs={12} md={12}> | ||||
| <UploadFileTable | <UploadFileTable | ||||
| key="uploadTable" | key="uploadTable" | ||||
| @@ -415,6 +414,7 @@ const FormPanel = ({ formData }) => { | |||||
| setColumnPrice(newValue) | setColumnPrice(newValue) | ||||
| formik.values["fee"] = newValue.value * formik.values.length; | formik.values["fee"] = newValue.value * formik.values.length; | ||||
| }} | }} | ||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField {...params} | <TextField {...params} | ||||
| InputLabelProps={{ | InputLabelProps={{ | ||||
| @@ -165,7 +165,6 @@ const StatusChangeDialog = (props) => { | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | ||||
| '& .MuiOutlinedInput-root': { height: 40 } | '& .MuiOutlinedInput-root': { height: 40 } | ||||
| }} | }} | ||||
| // sx={{"& .MuiInputBase-root": { height: "41px" },"#idDocType":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} | |||||
| renderInput={(params) => <TextField {...params} placeholder="" />} | renderInput={(params) => <TextField {...params} placeholder="" />} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -279,11 +279,44 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| setSelectedStatus(newValue); | setSelectedStatus(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | |||||
| sx={{ | sx={{ | ||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | '& .MuiInputBase-root': { alignItems: 'center' }, | ||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | ||||
| '& .MuiOutlinedInput-root': { height: 40 } | '& .MuiOutlinedInput-root': { height: 40 } | ||||
| }} | }} | ||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| label="Status" | |||||
| InputLabelProps={{ | |||||
| shrink: true | |||||
| }} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| {/* <Autocomplete | |||||
| multiple | |||||
| {...register("status")} | |||||
| id="status" | |||||
| size="small" | |||||
| options={ComboData.publicNoticeStatic_GLD} | |||||
| value={selectedStatus} | |||||
| onChange={(event, newValue) => { | |||||
| const findAllIndex = newValue.findIndex((ele) => { | |||||
| return ele.type === "all" | |||||
| }) | |||||
| if (findAllIndex > -1) { | |||||
| setSelectedStatus([newValue[findAllIndex]]); | |||||
| setSelectedLabelsString('all') | |||||
| } else { | |||||
| const selectedLabels = newValue.map(option => option.type); | |||||
| const selectedLabelsString = `${selectedLabels.join(',')}`; | |||||
| setSelectedStatus(newValue); | |||||
| setSelectedLabelsString(selectedLabelsString); | |||||
| } | |||||
| }} | |||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| @@ -266,11 +266,44 @@ const SearchPublicNoticeForm = ({ applySearch, orgComboData, searchCriteria, iss | |||||
| setSelectedStatus(newValue); | setSelectedStatus(newValue); | ||||
| } | } | ||||
| }} | }} | ||||
| getOptionLabel={(option) => option.label} | |||||
| sx={{ | sx={{ | ||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | '& .MuiInputBase-root': { alignItems: 'center' }, | ||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | ||||
| '& .MuiOutlinedInput-root': { height: 40 } | '& .MuiOutlinedInput-root': { height: 40 } | ||||
| }} | }} | ||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| label="Status" | |||||
| InputLabelProps={{ | |||||
| shrink: true | |||||
| }} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| {/* <Autocomplete | |||||
| multiple | |||||
| {...register("status")} | |||||
| id="status" | |||||
| size="small" | |||||
| options={ComboData.publicNoticeStatic_GLD} | |||||
| value={selectedStatus} | |||||
| onChange={(event, newValue) => { | |||||
| const findAllIndex = newValue.findIndex((ele) => { | |||||
| return ele.type === "all" | |||||
| }) | |||||
| if (findAllIndex > -1) { | |||||
| setSelectedStatus([newValue[findAllIndex]]); | |||||
| setSelectedLabelsString('all') | |||||
| } else { | |||||
| const selectedLabels = newValue.map(option => option.type); | |||||
| const selectedLabelsString = `${selectedLabels.join(',')}`; | |||||
| setSelectedStatus(newValue); | |||||
| setSelectedLabelsString(selectedLabelsString); | |||||
| } | |||||
| }} | |||||
| getOptionLabel={(option) => option.label} | getOptionLabel={(option) => option.label} | ||||
| renderInput={(params) => ( | renderInput={(params) => ( | ||||
| <TextField | <TextField | ||||
| @@ -1,11 +1,12 @@ | |||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
| import { Box, Grid, Typography } from '@mui/material'; | |||||
| // import { Stack } from '@mui/material'; | |||||
| import { Box, Grid, Typography, Dialog, DialogContent, IconButton } from '@mui/material'; | |||||
| import CloseIcon from '@mui/icons-material/Close'; | |||||
| import Loadable from 'components/Loadable'; | import Loadable from 'components/Loadable'; | ||||
| import { lazy, } from 'react'; | |||||
| import { lazy, useState } from 'react'; | |||||
| import { FormattedMessage, useIntl } from "react-intl"; | import { FormattedMessage, useIntl } from "react-intl"; | ||||
| import { checkSysEnv, checkPaymentSuspention } from "utils/Utils"; | import { checkSysEnv, checkPaymentSuspention } from "utils/Utils"; | ||||
| import backbroundImg from 'assets/images/bg_ml.jpg'; | import backbroundImg from 'assets/images/bg_ml.jpg'; | ||||
| import lgceImg from 'assets/images/2025_lgce.jpg'; // <-- your popup image | |||||
| import 'assets/style/loginStyles.css'; | import 'assets/style/loginStyles.css'; | ||||
| const AuthCard = Loadable(lazy(() => import('./AuthCardCustom'))); | const AuthCard = Loadable(lazy(() => import('./AuthCardCustom'))); | ||||
| @@ -18,26 +19,79 @@ const BackgroundHead = { | |||||
| }; | }; | ||||
| const AuthWrapper = ({ children }) => { | const AuthWrapper = ({ children }) => { | ||||
| // Move useIntl inside component | |||||
| const intl = useIntl(); | const intl = useIntl(); | ||||
| // --- Date control --- | |||||
| const today = new Date(); | |||||
| const showUntil = new Date("2025-11-27T00:00:00"); // 8 Dec 2025 and onwards = hide popup | |||||
| const [openPopup, setOpenPopup] = useState(today < showUntil); | |||||
| const handleClosePopup = () => { | |||||
| setOpenPopup(false); | |||||
| }; | |||||
| return ( | return ( | ||||
| <Box sx={{ minHeight: '87vh' }}> | <Box sx={{ minHeight: '87vh' }}> | ||||
| <Dialog | |||||
| open={openPopup} | |||||
| onClose={handleClosePopup} | |||||
| aria-labelledby="election-promo-title" | |||||
| maxWidth="md" | |||||
| PaperProps={{ | |||||
| sx: { | |||||
| borderRadius: 2, | |||||
| overflow: 'hidden', | |||||
| boxShadow: 6 | |||||
| } | |||||
| }} | |||||
| > | |||||
| <Box sx={{ position: 'relative' }}> | |||||
| <IconButton | |||||
| aria-label="Close" | |||||
| onClick={handleClosePopup} | |||||
| sx={{ | |||||
| position: 'absolute', | |||||
| top: 6, | |||||
| right: 6, | |||||
| zIndex: 1, | |||||
| bgcolor: 'rgba(255,255,255,0.8)', | |||||
| '&:hover': { bgcolor: 'rgba(255,255,255,1)' } | |||||
| }} | |||||
| > | |||||
| <CloseIcon /> | |||||
| </IconButton> | |||||
| <DialogContent sx={{ p: 0 }}> | |||||
| <Box | |||||
| component="img" | |||||
| src={lgceImg} | |||||
| alt={intl.formatMessage({ id: 'lgce_alt', defaultMessage: '2025 Legislative Council General Election' })} | |||||
| title={intl.formatMessage({ id: 'lgce_title', defaultMessage: '2025 Legislative Council General Election' })} | |||||
| sx={{ | |||||
| display: 'block', | |||||
| width: '100%', | |||||
| maxWidth: '720px', | |||||
| height: 'auto' | |||||
| }} | |||||
| /> | |||||
| </DialogContent> | |||||
| </Box> | |||||
| </Dialog> | |||||
| {/* Page content */} | |||||
| <div style={BackgroundHead}> | <div style={BackgroundHead}> | ||||
| <Grid | <Grid | ||||
| container | container | ||||
| direction="row" | direction="row" | ||||
| justifyContent="space-between" | justifyContent="space-between" | ||||
| alignItems="center" | alignItems="center" | ||||
| sx={{ | |||||
| minHeight: '87vh' | |||||
| }} | |||||
| sx={{ minHeight: '87vh' }} | |||||
| > | > | ||||
| <Grid item xs={12} md={8} lg={8} xl={8} > | |||||
| <Grid container direction="column" | |||||
| <Grid item xs={12} md={8} lg={8} xl={8}> | |||||
| <Grid | |||||
| container | |||||
| direction="column" | |||||
| justifyContent="flex-start" | justifyContent="flex-start" | ||||
| alignItems="flex-start" | alignItems="flex-start" | ||||
| // spacing={2} | |||||
| sx={{ minHeight: { md: 'calc(87vh)' } }} | sx={{ minHeight: { md: 'calc(87vh)' } }} | ||||
| > | > | ||||
| <Grid item xs={12} sx={{ ml: 4,}}> | <Grid item xs={12} sx={{ ml: 4,}}> | ||||
| @@ -47,15 +101,20 @@ const AuthWrapper = ({ children }) => { | |||||
| </Typography> | </Typography> | ||||
| : | : | ||||
| <Typography style={{ textAlign: "flex-start" }}> | <Typography style={{ textAlign: "flex-start" }}> | ||||
| <div style={{ padding: 12 }} dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "homePageHeaderMessage" }) }} /> | |||||
| <div | |||||
| style={{ padding: 12 }} | |||||
| dangerouslySetInnerHTML={{ __html: intl.formatMessage({ id: "homePageHeaderMessage" }) }} | |||||
| /> | |||||
| </Typography> | </Typography> | ||||
| } | } | ||||
| </Grid> | </Grid> | ||||
| <Grid container direction="column" | |||||
| justifyContent="flex-start" | |||||
| alignItems="center" | |||||
| spacing={2} | |||||
| sx={{ minHeight: { md: 'calc(50vh)' } }} | |||||
| <Grid | |||||
| container | |||||
| direction="column" | |||||
| justifyContent="flex-start" | |||||
| alignItems="center" | |||||
| spacing={2} | |||||
| sx={{ minHeight: { md: 'calc(50vh)' } }} | |||||
| > | > | ||||
| <Grid item xs={12} sx={{ ml: 4, mt: 12, display: { xs: 'none', sm: 'block' } }}> | <Grid item xs={12} sx={{ ml: 4, mt: 12, display: { xs: 'none', sm: 'block' } }}> | ||||
| <Typography style={{ textAlign: "center", fontSize: "1.8rem" }}> | <Typography style={{ textAlign: "center", fontSize: "1.8rem" }}> | ||||
| @@ -67,28 +126,27 @@ const AuthWrapper = ({ children }) => { | |||||
| <Typography style={{ textAlign: "center", fontSize: "1.8rem" }}> | <Typography style={{ textAlign: "center", fontSize: "1.8rem" }}> | ||||
| <FormattedMessage id="PNSPS_fullname" /> | <FormattedMessage id="PNSPS_fullname" /> | ||||
| </Typography> | </Typography> | ||||
| { | |||||
| checkSysEnv() !== '' ? | |||||
| <Typography style={{ color: 'red', textAlign: "center", fontSize: "1.8rem" }}> | |||||
| User Acceptance Test Environment | |||||
| </Typography> | |||||
| : "" | |||||
| } | |||||
| {checkSysEnv() !== '' ? ( | |||||
| <Typography style={{ color: 'red', textAlign: "center", fontSize: "1.8rem" }}> | |||||
| User Acceptance Test Environment | |||||
| </Typography> | |||||
| ) : ( | |||||
| "" | |||||
| )} | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={12} md={4} lg={4} xl={4}> | |||||
| <Grid | |||||
| container | |||||
| justifyContent="center" | |||||
| alignItems="center" | |||||
| sx={{ minHeight: { xs: 'calc(90vh - 134px)', md: 'calc(90vh - 112px)' }, }} | |||||
| > | |||||
| <Grid item xs={12} md={11} lg={11} xl={11}> | |||||
| <AuthCard>{children}</AuthCard> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={4} lg={4} xl={4}> | |||||
| <Grid | |||||
| container | |||||
| justifyContent="center" | |||||
| alignItems="center" | |||||
| sx={{ minHeight: { xs: 'calc(90vh - 134px)', md: 'calc(90vh - 112px)' } }} | |||||
| > | |||||
| <Grid item xs={12} md={11} lg={11} xl={11}> | |||||
| <AuthCard>{children}</AuthCard> | |||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -644,12 +644,12 @@ const CustomFormWizard = (props) => { | |||||
| setCheckCountry(true) | setCheckCountry(true) | ||||
| } | } | ||||
| }} | }} | ||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => <TextField {...params} placeholder={intl.formatMessage({ id: 'regionOrCountry' })} />} | |||||
| sx={{ | |||||
| '& .MuiInputBase-root': { alignItems: 'center' }, | |||||
| '& .MuiAutocomplete-endAdornment': { top: '50%', transform: 'translateY(-50%)' }, | |||||
| '& .MuiOutlinedInput-root': { height: 40 } | |||||
| }} | |||||
| renderInput={(params) => <TextField {...params} placeholder={intl.formatMessage({ id: 'regionOrCountry' })} />} | |||||
| /> | /> | ||||
| {formik.touched.address1 && formik.errors.address1 && ( | {formik.touched.address1 && formik.errors.address1 && ( | ||||
| <FormHelperText error id="helper-text-address1-signup"> | <FormHelperText error id="helper-text-address1-signup"> | ||||
| @@ -2,52 +2,112 @@ | |||||
| const AboutUs = () => { | const AboutUs = () => { | ||||
| const content =` | const content =` | ||||
| <style> | |||||
| td.tnc { min-width: 24px; vertical-align: text-top; } div.tnc { text-align: justify; text-justify: inter-word; font-style: normal; } strong.tnc { font- size: large; } li.tnc { margin: 10px 0; } | |||||
| </style> | |||||
| <div class="tnc"> | |||||
| <strong class="tnc" | |||||
| ><h2><center>私隐政策</center></h2></strong | |||||
| > | |||||
| <ol> | |||||
| <li class="tnc"> | |||||
| 申请人在本网站内所提供的个人资料会供申请刊登公共启事及为承担法律责任用途。 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 保障个人资料私隐是政府物流服务署每位成员所关注的事宜。我们尊重个人资料私隐,并承诺全面执行及遵从保障资料原则及《个人资料(私隐)条例》的所有相关条文。政府物流服务署建立及实施系统监控,以确保遵从以下六项保障资料原则 | |||||
| – | |||||
| <ol type="a"> | |||||
| <li class="tnc"> | |||||
| 以合法和公平的方法收集足够但不超乎适度的个人资料,只供用于与政府物流服务署的职能或活动有关的合法目的 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 采取所有切实可行的步骤,以确保在顾及有关的个人资料会被使用于的目的下,所收集或保留的个人资料是准确的。删除就使用目的而言不再属有需要的个人资料; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 所收集的个人资料只可用作收集资料时资料会被使用于的目的或直接有关的目的,除非有关个人已就更改使用明示同意或法律准许有关使用; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 采取所有切实可行的步骤,以确保个人资料受保障而不受未获准许的或意外的查阅、处理、删除或使用所影响; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 采取所有切实可行的步骤,以确保任何人能获政府物流服务署告知所持有的个人资料的种类及资料将会为什么目的而使用的;以及 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 准许资料当事人查阅/改正其个人资料及以法律准许或规定的方式处理任何查阅/改正个人资料的要求。 | |||||
| </li> | |||||
| </ol> | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 如要查阅或改正本署所持有的个人资料,请向以下人士提出: <br /><br /> | |||||
| 香港北角渣华道333号<br /> | |||||
| 北角政府合署10楼<br /> | |||||
| 政府物流服务署<br /> | |||||
| 保障资料主任<br /> | |||||
| <br /> | |||||
| ( 注:请以个人资料私隐专员指定的<a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_c.pdf">表格</a>提出查阅资料的要求。) | |||||
| </li> | |||||
| </ol> | |||||
| </div> | |||||
| <style> | |||||
| .privacy-policy { | |||||
| max-width: 900px; | |||||
| margin: 0 auto 2rem; | |||||
| font-size: 1.05rem; | |||||
| line-height: 1.75; | |||||
| text-align: justify; | |||||
| text-justify: inter-word; | |||||
| } | |||||
| .privacy-policy h2, | |||||
| .privacy-policy h3, | |||||
| .privacy-policy h4 { | |||||
| margin: 1.8rem 0 0.9rem; | |||||
| font-weight: 600; | |||||
| text-align: left; | |||||
| } | |||||
| .privacy-policy h2 { | |||||
| font-size: 1.9rem; | |||||
| } | |||||
| .privacy-policy h3 { | |||||
| font-size: 1.35rem; | |||||
| } | |||||
| .privacy-policy h4 { | |||||
| font-size: 1.15rem; | |||||
| } | |||||
| .privacy-policy p { | |||||
| margin: 0 0 1rem; | |||||
| } | |||||
| .privacy-policy ol { | |||||
| margin: 0.5rem 0 1.6rem; | |||||
| padding-left: 1.4rem; | |||||
| } | |||||
| .privacy-policy ol li { | |||||
| margin: 0.6rem 0; | |||||
| } | |||||
| .privacy-policy a { | |||||
| text-decoration: underline; | |||||
| } | |||||
| .privacy-policy address { | |||||
| font-style: normal; | |||||
| line-height: 1.6; | |||||
| margin-bottom: 1rem; | |||||
| } | |||||
| .privacy-policy .note { | |||||
| font-size: 0.95rem; | |||||
| font-style: italic; | |||||
| } | |||||
| </style> | |||||
| <div class="privacy-policy"> | |||||
| <h2>私隐政策</h2> | |||||
| <p> | |||||
| 保障个人资料私隐是政府物流服务署每位成员所关注的事宜。我们尊重个人资料私隐,并承诺全面执行及遵从保障资料原则及《个人资料(私隐)条例》的所有相关条文。政府物流服务署建立及实施系统监控,以确保遵从以下六项保障资料原则: | |||||
| </p> | |||||
| <ol type="a"> | |||||
| <li>以合法和公平的方法收集足够但不过度的个人资料,只供用于与政府物流服务署职能或活动有关的合法目的;</li> | |||||
| <li>采取所有切实可行的步骤,以确保在顾及个人资料用途下所收集或保留的资料是准确的。删除不再需要的个人资料;</li> | |||||
| <li>所收集的个人资料只可用于收集时所说明或直接相关的目的,除非资料当事人明示同意或法律允许;</li> | |||||
| <li>采取所有切实可行的步骤,确保个人资料受到保障,不受未授权或意外查阅、处理、删除或使用的影响;</li> | |||||
| <li>采取所有切实可行的步骤,确保任何人可获知政府物流服务署所持有的个人资料种类及其用途;以及</li> | |||||
| <li>允许资料当事人查阅/更正其个人资料,并按法律许可或规定处理有关申请。</li> | |||||
| </ol> | |||||
| <h3>收集个人资料声明</h3> | |||||
| <h4>收集资料的目的</h4> | |||||
| <p> | |||||
| 申请人在本网站提供的个人资料将用于申请刊登公共启事及履行相关法律责任。提供资料属自愿性质;如资料不足,我们可能无法处理相关刊登申请。 | |||||
| </p> | |||||
| <h4>披露个人资料</h4> | |||||
| <p> | |||||
| 政府物流服务署可能会向其他政策局/部门披露你在本网站提供的个人资料。 | |||||
| </p> | |||||
| <h4>查阅个人资料</h4> | |||||
| <p> | |||||
| 如需查阅或更正本署持有的个人资料,请联络: | |||||
| </p> | |||||
| <address> | |||||
| 香港北角渣华道333号<br> | |||||
| 北角政府合署10楼<br> | |||||
| 政府物流服务署<br> | |||||
| 保障资料主任 | |||||
| </address> | |||||
| <p class="note"> | |||||
| 注:请以个人资料私隐专员指定的 | |||||
| <a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_c.pdf">表格</a> | |||||
| 提出查阅资料申请。 | |||||
| </p> | |||||
| </div> | |||||
| ` | ` | ||||
| ; | ; | ||||
| @@ -2,75 +2,142 @@ | |||||
| const Page = () => { | const Page = () => { | ||||
| const content = ` | const content = ` | ||||
| <style> | |||||
| td.tnc { min-width: 24px; vertical-align: text-top; } div.tnc { text-align: justify; text-justify: inter-word; font-style: normal; } strong.tnc { font-size: large; } li.tnc { margin: 10px 0; } | |||||
| </style> | |||||
| <div class="tnc"> | |||||
| <strong class="tnc" | |||||
| ><h2><center>Privacy Policy</center></h2></strong | |||||
| > | |||||
| <ol> | |||||
| <li class="tnc"> | |||||
| The personal data provided by the applicant in this website would be | |||||
| used for application of public notice publication and for assumption | |||||
| of liability. | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| The protection of personal data privacy is the concern of every member | |||||
| of Government Logistics Department. We respect personal data privacy | |||||
| and are committed to fully implementing and complying with the data | |||||
| protection principles and all relevant provisions of the Personal Data | |||||
| (Privacy) Ordinance. We develop and implement programme controls that | |||||
| give effect to the six data protection principles below – | |||||
| <ol type="a"> | |||||
| <li class="tnc"> | |||||
| collect adequate, but not excessive, personal data by lawful and | |||||
| fair means only for lawful purposes related to our functions or | |||||
| activities; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| take all reasonably practicable steps to ensure that the personal | |||||
| data collected or retained are accurate, having regard to the | |||||
| purposes for which they are to be used. Erase personal data no | |||||
| longer than necessary for the purposes for which they are to be | |||||
| used; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| use the personal data collected only for purposes or directly | |||||
| related purposes for which the data were to be used at the time of | |||||
| collection, unless the individual concerned has given express | |||||
| consent for a change of use or such use is permitted by law; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| take all reasonably practicable steps to ensure that personal data | |||||
| are protected against unauthorized or accidental access, | |||||
| processing, erasure or other use; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| take all reasonably practicable steps to ensure that a person can | |||||
| be informed of the kinds of personal data that GLD holds and the | |||||
| purposes for which the data are to be used; and | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| permit persons to access and correct personal data of which they | |||||
| are the data subject and process any access/correction requests in | |||||
| a manner permitted or required by law. | |||||
| </li> | |||||
| </ol> | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| Requests for access to or correction of personal data held by us | |||||
| should be addressed to – <br /><br /> | |||||
| Data Protection Officer<br /> | |||||
| Government Logistics Department<br /> | |||||
| 10/F, North Point Government Offices <br /> | |||||
| 333 Java Road North Point<br /> | |||||
| Hong Kong<br /> | |||||
| <br /> | |||||
| (Note: Data access requests should be made on a <a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_e.pdf">form</a> specified by the Privacy Commissioner for Personal Data.) | |||||
| </li> | |||||
| </ol> | |||||
| </div> | |||||
| <style> | |||||
| .privacy-policy { | |||||
| max-width: 900px; | |||||
| margin: 0 auto 2rem; | |||||
| font-size: 1.05rem; | |||||
| line-height: 1.75; | |||||
| text-align: justify; | |||||
| text-justify: inter-word; | |||||
| } | |||||
| .privacy-policy h2, | |||||
| .privacy-policy h3, | |||||
| .privacy-policy h4 { | |||||
| margin: 1.8rem 0 0.9rem; | |||||
| font-weight: 600; | |||||
| text-align: left; /* Updated */ | |||||
| } | |||||
| .privacy-policy h2 { | |||||
| font-size: 1.9rem; | |||||
| } | |||||
| .privacy-policy h3 { | |||||
| font-size: 1.35rem; | |||||
| } | |||||
| .privacy-policy h4 { | |||||
| font-size: 1.15rem; | |||||
| } | |||||
| .privacy-policy p { | |||||
| margin: 0 0 1rem; | |||||
| } | |||||
| .privacy-policy ol { | |||||
| margin: 0.5rem 0 1.6rem; | |||||
| padding-left: 1.4rem; | |||||
| } | |||||
| .privacy-policy ol li { | |||||
| margin: 0.6rem 0; | |||||
| } | |||||
| .privacy-policy a { | |||||
| text-decoration: underline; | |||||
| } | |||||
| .privacy-policy address { | |||||
| font-style: normal; | |||||
| line-height: 1.6; | |||||
| margin-bottom: 1rem; | |||||
| } | |||||
| .privacy-policy .note { | |||||
| font-size: 0.95rem; | |||||
| font-style: italic; | |||||
| } | |||||
| </style> | |||||
| <div class="privacy-policy"> | |||||
| <h2>Privacy Policy</h2> | |||||
| <p> | |||||
| The protection of personal data privacy is the concern of every member of the Government Logistics | |||||
| Department. We respect personal data privacy and are committed to fully implementing and complying | |||||
| with the data protection principles and all relevant provisions of the Personal Data (Privacy) | |||||
| Ordinance. We develop and implement programme controls that give effect to the six data protection | |||||
| principles below: | |||||
| </p> | |||||
| <ol type="a"> | |||||
| <li> | |||||
| collect adequate, but not excessive, personal data by lawful and fair means only for lawful | |||||
| purposes related to our functions or activities; | |||||
| </li> | |||||
| <li> | |||||
| take all reasonably practicable steps to ensure that the personal data collected or retained | |||||
| are accurate, having regard to the purposes for which they are to be used. Erase personal data | |||||
| no longer than necessary for the purposes for which they are to be used; | |||||
| </li> | |||||
| <li> | |||||
| use the personal data collected only for purposes or directly related purposes for which the | |||||
| data were to be used at the time of collection, unless the individual concerned has given express | |||||
| consent for a change of use or such use is permitted by law; | |||||
| </li> | |||||
| <li> | |||||
| take all reasonably practicable steps to ensure that personal data are protected against | |||||
| unauthorized or accidental access, processing, erasure or other use; | |||||
| </li> | |||||
| <li> | |||||
| take all reasonably practicable steps to ensure that a person can be informed of the kinds of | |||||
| personal data that the Government Logistics Department holds and the purposes for which the | |||||
| data are to be used; and | |||||
| </li> | |||||
| <li> | |||||
| permit persons to access and correct personal data of which they are the data subject and | |||||
| process any access/correction requests in a manner permitted or required by law. | |||||
| </li> | |||||
| </ol> | |||||
| <h3>Personal Information Collection Statement</h3> | |||||
| <h4>Purpose of Collection</h4> | |||||
| <p> | |||||
| The personal data provided by the applicant in this website will be used for application of public | |||||
| notice publication and for assumption of liability. The provision of the personal data is voluntary. | |||||
| If the applicant does not provide sufficient information, we may not be able to process publication | |||||
| of the relevant public notice. | |||||
| </p> | |||||
| <h4>Disclosure of Personal Data</h4> | |||||
| <p> | |||||
| The personal data provided in this website may be disclosed to other bureaux / departments. | |||||
| </p> | |||||
| <h4>Access to Personal Data</h4> | |||||
| <p> | |||||
| Requests for access to or correction of personal data held by us should be addressed to: | |||||
| </p> | |||||
| <address> | |||||
| Data Protection Officer<br> | |||||
| Government Logistics Department<br> | |||||
| 10/F, North Point Government Offices<br> | |||||
| 333 Java Road, North Point<br> | |||||
| Hong Kong | |||||
| </address> | |||||
| <p class="note"> | |||||
| Note: Data access requests should be made on a | |||||
| <a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_e.pdf"> | |||||
| form | |||||
| </a> | |||||
| specified by the Privacy Commissioner for Personal Data. | |||||
| </p> | |||||
| </div> | |||||
| ` | ` | ||||
| ; | ; | ||||
| @@ -2,52 +2,112 @@ | |||||
| const AboutUs = () => { | const AboutUs = () => { | ||||
| const content =` | const content =` | ||||
| <style> | |||||
| td.tnc { min-width: 24px; vertical-align: text-top; } div.tnc { text-align: justify; text-justify: inter-word; font-style: normal; } strong.tnc { font-size: large; } li.tnc { margin: 10px 0; } | |||||
| </style> | |||||
| <div class="tnc"> | |||||
| <strong class="tnc" | |||||
| ><h2><center>私隱政策</center></h2></strong | |||||
| > | |||||
| <ol> | |||||
| <li class="tnc"> | |||||
| 申請人在本網站內所提供的個人資料會供申請刊登公共啟事及為承擔法律責任用途。 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 保障個人資料私隱是政府物流服務署每位成員所關注的事宜。我們尊重個人資料私隱,並承諾全面執行及遵從保障資料原則及《個人資料(私隱)條例》的所有相關條文。政府物流服務署建立及實施系統監控,以確保遵從以下六項保障資料原則 | |||||
| – | |||||
| <ol type="a"> | |||||
| <li class="tnc"> | |||||
| 以合法和公平的方法收集足夠但不超乎適度的個人資料,只供用於與政府物流服務署的職能或活動有關的合法目的 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 採取所有切實可行的步驟,以確保在顧及有關的個人資料會被使用於的目的下,所收集或保留的個人資料是準確的。刪除就使用目的而言不再屬有需要的個人資料; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 所收集的個人資料只可用作收集資料時資料會被使用於的目的或直接有關的目的,除非有關個人已就更改使用明示同意或法律准許有關使用; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 採取所有切實可行的步驟,以確保個人資料受保障而不受未獲准許的或意外的查閱、處理、刪除或使用所影響; | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 採取所有切實可行的步驟,以確保任何人能獲政府物流服務署告知所持有的個人資料的種類及資料將會為甚麼目的而使用的;以及 | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 准許資料當事人查閱/改正其個人資料及以法律准許或規定的方式處理任何查閱/改正個人資料的要求。 | |||||
| </li> | |||||
| </ol> | |||||
| </li> | |||||
| <li class="tnc"> | |||||
| 如要查閱或改正本署所持有的個人資料,請向以下人士提出: <br /><br /> | |||||
| 香港北角渣華道333號<br /> | |||||
| 北角政府合署10樓<br /> | |||||
| 政府物流服務署<br /> | |||||
| 保障資料主任<br /> | |||||
| <br /> | |||||
| ( 註:請以個人資料私隱專員指定的<a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_c.pdf">表格</a>提出查閱資料的要求。) | |||||
| </li> | |||||
| </ol> | |||||
| </div> | |||||
| <style> | |||||
| .privacy-policy { | |||||
| max-width: 900px; | |||||
| margin: 0 auto 2rem; | |||||
| font-size: 1.05rem; | |||||
| line-height: 1.75; | |||||
| text-align: justify; | |||||
| text-justify: inter-word; | |||||
| } | |||||
| .privacy-policy h2, | |||||
| .privacy-policy h3, | |||||
| .privacy-policy h4 { | |||||
| margin: 1.8rem 0 0.9rem; | |||||
| font-weight: 600; | |||||
| text-align: left; | |||||
| } | |||||
| .privacy-policy h2 { | |||||
| font-size: 1.9rem; | |||||
| } | |||||
| .privacy-policy h3 { | |||||
| font-size: 1.35rem; | |||||
| } | |||||
| .privacy-policy h4 { | |||||
| font-size: 1.15rem; | |||||
| } | |||||
| .privacy-policy p { | |||||
| margin: 0 0 1rem; | |||||
| } | |||||
| .privacy-policy ol { | |||||
| margin: 0.5rem 0 1.6rem; | |||||
| padding-left: 1.4rem; | |||||
| } | |||||
| .privacy-policy ol li { | |||||
| margin: 0.6rem 0; | |||||
| } | |||||
| .privacy-policy a { | |||||
| text-decoration: underline; | |||||
| } | |||||
| .privacy-policy address { | |||||
| font-style: normal; | |||||
| line-height: 1.6; | |||||
| margin-bottom: 1rem; | |||||
| } | |||||
| .privacy-policy .note { | |||||
| font-size: 0.95rem; | |||||
| font-style: italic; | |||||
| } | |||||
| </style> | |||||
| <div class="privacy-policy"> | |||||
| <h2>私隱政策</h2> | |||||
| <p> | |||||
| 保障個人資料私隱是政府物流服務署每位成員所關注的事宜。我們尊重個人資料私隱,並承諾全面執行及遵從保障資料原則及《個人資料(私隱)條例》的所有相關條文。政府物流服務署建立及實施系統監控,以確保遵從以下六項保障資料原則: | |||||
| </p> | |||||
| <ol type="a"> | |||||
| <li>以合法和公平的方法收集足夠但不超乎適度的個人資料,只供用於與政府物流服務署的職能或活動有關的合法目的;</li> | |||||
| <li>採取所有切實可行的步驟,以確保在顧及有關的個人資料用途下,所收集或保留的個人資料是準確的。刪除就使用目的而言不再屬有需要的個人資料;</li> | |||||
| <li>所收集的個人資料只可用作收集時所指明或直接相關的目的,除非資料當事人明示同意作其他用途,或法律所准許;</li> | |||||
| <li>採取所有切實可行的步驟,以確保個人資料受保障而不受未獲准許或意外的查閱、處理、刪除或使用所影響;</li> | |||||
| <li>採取所有切實可行的步驟,以確保任何人能獲政府物流服務署告知所持有的個人資料種類及資料的使用目的;以及</li> | |||||
| <li>准許資料當事人查閱/改正其個人資料,並以法律准許或規定的方式處理有關查閱/改正要求。</li> | |||||
| </ol> | |||||
| <h3>收集個人資料聲明</h3> | |||||
| <h4>收集資料的目的</h4> | |||||
| <p> | |||||
| 申請人在本網站內提供的個人資料,會用於申請刊登公共啟事及履行相關法律責任。提供資料屬自願性質;如資料不足,我們可能無法處理相關公共啟事的刊登事宜。 | |||||
| </p> | |||||
| <h4>披露個人資料</h4> | |||||
| <p> | |||||
| 政府物流服務署可能會向其他政策局/部門披露你在本網站提供的個人資料。 | |||||
| </p> | |||||
| <h4>查閱個人資料</h4> | |||||
| <p> | |||||
| 如需查閱或改正本署所持有的個人資料,請聯絡: | |||||
| </p> | |||||
| <address> | |||||
| 香港北角渣華道333號<br> | |||||
| 北角政府合署10樓<br> | |||||
| 政府物流服務署<br> | |||||
| 保障資料主任 | |||||
| </address> | |||||
| <p class="note"> | |||||
| 註:請以個人資料私隱專員指定的 | |||||
| <a target="_blank" href="https://www.gld.gov.hk/assets/gld/download-files/privacy-policy/privacy_form_c.pdf">表格</a> | |||||
| 提出查閱資料要求。 | |||||
| </p> | |||||
| </div> | |||||
| ` | ` | ||||
| ; | ; | ||||
| @@ -598,5 +598,7 @@ | |||||
| "userGuidePub10":"10. Payment", | "userGuidePub10":"10. Payment", | ||||
| "Dashboard": "Dashboard", | "Dashboard": "Dashboard", | ||||
| "event": "Event" | |||||
| "event": "Event", | |||||
| "lgce_alt": "2025 Legislative Council General Election", | |||||
| "lgce_title": "2025 Legislative Council General Election" | |||||
| } | } | ||||
| @@ -594,5 +594,7 @@ | |||||
| "userGuidePub10":"10. 付款", | "userGuidePub10":"10. 付款", | ||||
| "Dashboard": "仪表板", | "Dashboard": "仪表板", | ||||
| "event": "活动" | |||||
| "event": "活动", | |||||
| "lgce_alt": "2025年立法会换届选举", | |||||
| "lgce_title": "2025年立法会换届选举" | |||||
| } | } | ||||
| @@ -595,5 +595,7 @@ | |||||
| "userGuidePub10":"10. 付款", | "userGuidePub10":"10. 付款", | ||||
| "Dashboard": "儀表板", | "Dashboard": "儀表板", | ||||
| "event": "活動" | |||||
| "event": "活動", | |||||
| "lgce_alt": "2025年立法會換屆選舉", | |||||
| "lgce_title": "2025年立法會換屆選舉" | |||||
| } | } | ||||