diff --git a/web/.eslintrc b/web/.eslintrc index bbda79f0..8d11f257 100644 --- a/web/.eslintrc +++ b/web/.eslintrc @@ -1,6 +1,7 @@ { "root": true, "env": { + "node": true, "browser": true, "es2021": true }, @@ -43,7 +44,7 @@ "react/jsx-uses-react": "error", "react/jsx-uses-vars": "error", "react/react-in-jsx-scope": "off", - "no-undef": "off", + "no-undef": "error", "react/display-name": "off", "react/jsx-filename-extension": "off", "no-param-reassign": "off", diff --git a/web/src/contexts/StatusContext.js b/web/src/contexts/StatusContext.js index f79436ae..d39f54e6 100644 --- a/web/src/contexts/StatusContext.js +++ b/web/src/contexts/StatusContext.js @@ -1,6 +1,6 @@ import { useEffect, useCallback, createContext } from 'react'; import { API } from 'utils/api'; -import { showNotice } from 'utils/common'; +import { showNotice, showError } from 'utils/common'; import { SET_SITE_INFO } from 'store/actions'; import { useDispatch } from 'react-redux'; diff --git a/web/src/ui-component/cards/SubCard.js b/web/src/ui-component/cards/SubCard.js index 05f9abb7..b0d93812 100644 --- a/web/src/ui-component/cards/SubCard.js +++ b/web/src/ui-component/cards/SubCard.js @@ -62,7 +62,8 @@ SubCard.propTypes = { secondary: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), sx: PropTypes.object, contentSX: PropTypes.object, - title: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]) + title: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]), + subTitle: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]) }; SubCard.defaultProps = { diff --git a/web/src/ui-component/cards/UserCard.js b/web/src/ui-component/cards/UserCard.js index e157a57f..793064b9 100644 --- a/web/src/ui-component/cards/UserCard.js +++ b/web/src/ui-component/cards/UserCard.js @@ -28,6 +28,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +import PropTypes from 'prop-types'; import { Box, Avatar } from '@mui/material'; import { alpha } from '@mui/material/styles'; import Card from '@mui/material/Card'; @@ -119,3 +120,7 @@ export default function UserCard({ children }) { ); } + +UserCard.propTypes = { + children: PropTypes.node +}; diff --git a/web/src/views/Authentication/Auth/GitHubOAuth.js b/web/src/views/Authentication/Auth/GitHubOAuth.js index dfea5d53..ef9ffd45 100644 --- a/web/src/views/Authentication/Auth/GitHubOAuth.js +++ b/web/src/views/Authentication/Auth/GitHubOAuth.js @@ -49,6 +49,7 @@ const GitHubOAuth = () => { let code = searchParams.get('code'); let state = searchParams.get('state'); sendCode(code, state, 0).then(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/web/src/views/Authentication/AuthForms/AuthRegister.js b/web/src/views/Authentication/AuthForms/AuthRegister.js index c286faad..3be43a43 100644 --- a/web/src/views/Authentication/AuthForms/AuthRegister.js +++ b/web/src/views/Authentication/AuthForms/AuthRegister.js @@ -80,7 +80,6 @@ const RegisterForm = ({ ...others }) => { return; } }; - useEffect(() => { let affCode = searchParams.get('aff'); if (affCode) { @@ -92,6 +91,7 @@ const RegisterForm = ({ ...others }) => { setTurnstileEnabled(true); setTurnstileSiteKey(siteInfo.turnstile_site_key); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [siteInfo]); return ( diff --git a/web/src/views/Authentication/AuthForms/ForgetPasswordForm.js b/web/src/views/Authentication/AuthForms/ForgetPasswordForm.js index 82135bf0..06107a07 100644 --- a/web/src/views/Authentication/AuthForms/ForgetPasswordForm.js +++ b/web/src/views/Authentication/AuthForms/ForgetPasswordForm.js @@ -15,7 +15,7 @@ import { Formik } from 'formik'; import AnimateButton from 'ui-component/extended/AnimateButton'; // assets -import { showError, showInfo } from 'utils/common'; +import { showError, showInfo, showSuccess } from 'utils/common'; // ===========================|| FIREBASE - REGISTER ||=========================== // diff --git a/web/src/views/Authentication/AuthForms/ResetPasswordForm.js b/web/src/views/Authentication/AuthForms/ResetPasswordForm.js index 632bbde3..226c0e5c 100644 --- a/web/src/views/Authentication/AuthForms/ResetPasswordForm.js +++ b/web/src/views/Authentication/AuthForms/ResetPasswordForm.js @@ -6,6 +6,7 @@ import { Button, Stack, Typography, Alert } from '@mui/material'; // assets import { showError, showInfo } from 'utils/common'; +import { API } from 'utils/api'; // ===========================|| FIREBASE - REGISTER ||=========================== // @@ -37,6 +38,7 @@ const ResetPasswordForm = () => { token, email }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/web/src/views/Channel/component/EditModal.js b/web/src/views/Channel/component/EditModal.js index efbb53ce..c774a057 100644 --- a/web/src/views/Channel/component/EditModal.js +++ b/web/src/views/Channel/component/EditModal.js @@ -231,6 +231,7 @@ const EditModal = ({ open, channelId, onCancel, onOk }) => { initChannel(1); setInitialInput({ ...defaultConfig.input, is_edit: false }); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [channelId]); return ( diff --git a/web/src/views/Channel/component/TableRow.js b/web/src/views/Channel/component/TableRow.js index d2efcc4f..6bea8076 100644 --- a/web/src/views/Channel/component/TableRow.js +++ b/web/src/views/Channel/component/TableRow.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { useState } from 'react'; -import { showInfo, showError } from 'utils/common'; +import { showInfo, showError, renderNumber } from 'utils/common'; import { API } from 'utils/api'; import { CHANNEL_OPTIONS } from 'constants/ChannelConstants'; diff --git a/web/src/views/Channel/index.js b/web/src/views/Channel/index.js index 5b7f1722..1d6d0bc9 100644 --- a/web/src/views/Channel/index.js +++ b/web/src/views/Channel/index.js @@ -189,6 +189,7 @@ export default function ChannelPage() { .catch((reason) => { showError(reason); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/web/src/views/Dashboard/component/StatisticalBarChart.js b/web/src/views/Dashboard/component/StatisticalBarChart.js index 8b0f8a19..3dc7cd0f 100644 --- a/web/src/views/Dashboard/component/StatisticalBarChart.js +++ b/web/src/views/Dashboard/component/StatisticalBarChart.js @@ -58,7 +58,8 @@ const StatisticalBarChart = ({ isLoading, chartDatas }) => { }; StatisticalBarChart.propTypes = { - isLoading: PropTypes.bool + isLoading: PropTypes.bool, + chartDatas: PropTypes.oneOfType([PropTypes.array, PropTypes.object]) }; export default StatisticalBarChart; diff --git a/web/src/views/Dashboard/component/StatisticalLineChartCard.js b/web/src/views/Dashboard/component/StatisticalLineChartCard.js index 53cd46b0..483ba1c4 100644 --- a/web/src/views/Dashboard/component/StatisticalLineChartCard.js +++ b/web/src/views/Dashboard/component/StatisticalLineChartCard.js @@ -116,7 +116,9 @@ const StatisticalLineChartCard = ({ isLoading, title, chartData, todayValue }) = StatisticalLineChartCard.propTypes = { isLoading: PropTypes.bool, - title: PropTypes.string + title: PropTypes.string, + chartData: PropTypes.oneOfType([PropTypes.array, PropTypes.object]), + todayValue: PropTypes.oneOfType([PropTypes.number, PropTypes.string]) }; export default StatisticalLineChartCard; diff --git a/web/src/views/Log/component/TableToolBar.js b/web/src/views/Log/component/TableToolBar.js index b5631d92..416eb673 100644 --- a/web/src/views/Log/component/TableToolBar.js +++ b/web/src/views/Log/component/TableToolBar.js @@ -1,4 +1,3 @@ -require('dayjs/locale/zh-cn'); import PropTypes from 'prop-types'; import { useTheme } from '@mui/material/styles'; import { IconUser, IconKey, IconBrandGithubCopilot, IconSitemap } from '@tabler/icons-react'; @@ -7,6 +6,7 @@ import { LocalizationProvider, DateTimePicker } from '@mui/x-date-pickers'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import dayjs from 'dayjs'; import LogType from '../type/LogType'; +require('dayjs/locale/zh-cn'); // ---------------------------------------------------------------------- export default function TableToolBar({ filterName, handleFilterName, userIsAdmin }) { diff --git a/web/src/views/Log/index.js b/web/src/views/Log/index.js index da24b4fd..3acfa832 100644 --- a/web/src/views/Log/index.js +++ b/web/src/views/Log/index.js @@ -98,6 +98,7 @@ export default function Log() { showError(reason); }); setInitPage(false); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [initPage]); return ( diff --git a/web/src/views/Profile/component/EmailModal.js b/web/src/views/Profile/component/EmailModal.js index febbd487..1e6dcc86 100644 --- a/web/src/views/Profile/component/EmailModal.js +++ b/web/src/views/Profile/component/EmailModal.js @@ -15,7 +15,7 @@ import { FormHelperText } from '@mui/material'; import { Formik } from 'formik'; -import { showError } from 'utils/common'; +import { showError, showSuccess } from 'utils/common'; import { useTheme } from '@mui/material/styles'; import * as Yup from 'yup'; import useRegister from 'hooks/useRegister'; @@ -167,5 +167,6 @@ export default EmailModal; EmailModal.propTypes = { open: PropTypes.bool, - handleClose: PropTypes.func + handleClose: PropTypes.func, + turnstileToken: PropTypes.string }; diff --git a/web/src/views/Redemption/component/EditModal.js b/web/src/views/Redemption/component/EditModal.js index 10b321ed..5d3c45c6 100644 --- a/web/src/views/Redemption/component/EditModal.js +++ b/web/src/views/Redemption/component/EditModal.js @@ -91,6 +91,7 @@ const EditModal = ({ open, redemptiondId, onCancel, onOk }) => { } else { setInputs(originInputs); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [redemptiondId]); return ( diff --git a/web/src/views/Redemption/index.js b/web/src/views/Redemption/index.js index fc2d02f1..436f1199 100644 --- a/web/src/views/Redemption/index.js +++ b/web/src/views/Redemption/index.js @@ -137,6 +137,7 @@ export default function Redemption() { .catch((reason) => { showError(reason); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/web/src/views/Setting/component/OperationSetting.js b/web/src/views/Setting/component/OperationSetting.js index 3835751b..c23ec6dc 100644 --- a/web/src/views/Setting/component/OperationSetting.js +++ b/web/src/views/Setting/component/OperationSetting.js @@ -1,4 +1,3 @@ -require('dayjs/locale/zh-cn'); import { useState, useEffect } from 'react'; import SubCard from 'ui-component/cards/SubCard'; import { Stack, FormControl, InputLabel, OutlinedInput, Checkbox, Button, FormControlLabel, TextField } from '@mui/material'; @@ -8,6 +7,7 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import dayjs from 'dayjs'; +require('dayjs/locale/zh-cn'); const OperationSetting = () => { let now = new Date(); diff --git a/web/src/views/Setting/component/OtherSetting.js b/web/src/views/Setting/component/OtherSetting.js index a3a81147..e3c7ebd4 100644 --- a/web/src/views/Setting/component/OtherSetting.js +++ b/web/src/views/Setting/component/OtherSetting.js @@ -53,6 +53,7 @@ const OtherSetting = () => { useEffect(() => { getOptions().then(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const updateOption = async (key, value) => { diff --git a/web/src/views/Setting/index.js b/web/src/views/Setting/index.js index 733a16dc..4ad26de5 100644 --- a/web/src/views/Setting/index.js +++ b/web/src/views/Setting/index.js @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import PropTypes from 'prop-types'; import { Tabs, Tab, Box, Card } from '@mui/material'; import { IconSettings2, IconActivity, IconSettings } from '@tabler/icons-react'; @@ -35,11 +35,14 @@ const Setting = () => { const location = useLocation(); const navigate = useNavigate(); const hash = location.hash.replace('#', ''); - const tabMap = { - operation: 0, - system: 1, - other: 2 - }; + const tabMap = useMemo( + () => ({ + operation: 0, + system: 1, + other: 2 + }), + [] + ); const [value, setValue] = useState(tabMap[hash] || 0); const handleChange = (event, newValue) => { diff --git a/web/src/views/Token/component/EditModal.js b/web/src/views/Token/component/EditModal.js index 079cc360..d0d277d5 100644 --- a/web/src/views/Token/component/EditModal.js +++ b/web/src/views/Token/component/EditModal.js @@ -1,4 +1,3 @@ -require('dayjs/locale/zh-cn'); import PropTypes from 'prop-types'; import * as Yup from 'yup'; import { Formik } from 'formik'; @@ -26,6 +25,7 @@ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { renderQuotaWithPrompt, showSuccess, showError } from 'utils/common'; import { API } from 'utils/api'; +require('dayjs/locale/zh-cn'); const validationSchema = Yup.object().shape({ is_edit: Yup.boolean(), @@ -88,6 +88,7 @@ const EditModal = ({ open, tokenId, onCancel, onOk }) => { if (tokenId) { loadToken().then(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [tokenId]); return ( diff --git a/web/src/views/Token/index.js b/web/src/views/Token/index.js index 1c8dee85..03daaedb 100644 --- a/web/src/views/Token/index.js +++ b/web/src/views/Token/index.js @@ -54,6 +54,7 @@ export default function Token() { .catch((reason) => { showError(reason); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const onPaginationChange = (event, activePage) => { diff --git a/web/src/views/User/component/EditModal.js b/web/src/views/User/component/EditModal.js index f6b533e2..8de37345 100644 --- a/web/src/views/User/component/EditModal.js +++ b/web/src/views/User/component/EditModal.js @@ -122,6 +122,7 @@ const EditModal = ({ open, userId, onCancel, onOk }) => { } else { setInputs(originInputs); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [userId]); return ( diff --git a/web/src/views/User/index.js b/web/src/views/User/index.js index 463f525a..da65abeb 100644 --- a/web/src/views/User/index.js +++ b/web/src/views/User/index.js @@ -135,6 +135,7 @@ export default function Users() { .catch((reason) => { showError(reason); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return (