From ed2dd6026349009d7829a034d1318da913548e47 Mon Sep 17 00:00:00 2001 From: Tomas Dvorak Date: Fri, 18 Sep 2026 16:43:52 +0200 Subject: [PATCH] feat(frontend): remove Pro license gates from admin and settings UI Strip ProChip badges, ProDialog upsell modals, and pro-conditional click interception across admin settings, group editing, storage policy selection, custom props, email templates, audit events, and navigation. Feature UI now renders and is reachable without a license. Also fixes a latent upstream ReferenceError: PageNavigation used undeclared proOpen/setProOpen state, which would crash on click of any Pro-gated nav item. "Open user files" in the user dialog now navigates to the admin file list filtered by owner instead of opening an upsell dialog. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../src/component/Admin/Common/ProDialog.tsx | 141 ------------------ .../Admin/File/FileDialog/FileForm.tsx | 2 +- .../CustomProps/CustomPropsSetting.tsx | 7 +- .../CustomProps/DraggableCustomPropsRow.tsx | 2 - .../Group/EditGroup/BasicInfoSection.tsx | 5 +- .../Group/EditGroup/DefaultPinnedSection.tsx | 6 +- .../Group/EditGroup/FileManagementSection.tsx | 18 +-- .../Admin/Group/EditGroup/ShareSection.tsx | 18 +-- .../Group/EditGroup/UploadDownloadSection.tsx | 5 +- frontend/src/component/Admin/Home/Home.tsx | 18 +-- .../Admin/Settings/Email/EmailTemplates.tsx | 18 +-- .../component/Admin/Settings/Event/Events.tsx | 15 +- .../SiteInformation/SiteInformation.tsx | 6 +- .../Settings/UserSession/SSOSettings.tsx | 2 - .../Settings/UserSession/UserSession.tsx | 11 +- .../src/component/Admin/Settings/VAS/VAS.tsx | 32 ++-- .../Admin/StoragePolicy/SelectProvider.tsx | 8 +- .../StoragePolicy/StoragePolicySetting.tsx | 2 - .../Admin/User/UserDialog/UserForm.tsx | 19 ++- .../component/Frame/NavBar/PageNavigation.tsx | 34 +---- .../component/Pages/Setting/SettingForm.tsx | 30 +--- 21 files changed, 60 insertions(+), 339 deletions(-) delete mode 100644 frontend/src/component/Admin/Common/ProDialog.tsx diff --git a/frontend/src/component/Admin/Common/ProDialog.tsx b/frontend/src/component/Admin/Common/ProDialog.tsx deleted file mode 100644 index f9333eca..00000000 --- a/frontend/src/component/Admin/Common/ProDialog.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import { - Alert, - AlertTitle, - Button, - DialogContent, - List, - ListItem, - ListItemIcon, - ListItemText, - Typography, - styled, -} from "@mui/material"; -import dayjs from "dayjs"; -import { useCallback, useMemo } from "react"; -import { Trans, useTranslation } from "react-i18next"; -import DraggableDialog, { StyledDialogActions } from "../../Dialogs/DraggableDialog"; -import CheckmarkCircleFilled from "../../Icons/CheckmarkCircleFilled"; -import Gift from "../../Icons/Gift"; -import { Code } from "../../Common/Code.tsx"; - -export interface ProDialogProps { - open: boolean; - onClose: () => void; -} - -const features = [ - "shareLinkCollabration", - "filePermission", - "multipleStoragePolicy", - "auditAndActivity", - "vasService", - "sso", - "more", -]; - -const StyledButton = styled(Button)(({ theme }) => ({ - background: `linear-gradient(45deg, ${theme.palette.primary.main} 30%, ${theme.palette.primary.light} 90%)`, - color: theme.palette.primary.contrastText, - "&:hover": { - background: `linear-gradient(45deg, ${theme.palette.primary.dark} 30%, ${theme.palette.primary.main} 90%)`, - }, - transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1) !important", -})); - -// TODO: fetch from cloudreve.org -const currentPromotion = { - code: "LX8YL9QP0", - discount: 15, - start: "2026-03-14T02:00:00Z", - end: "2026-06-14T02:00:00Z", -}; - -const ProDialog = ({ open, onClose }: ProDialogProps) => { - const { t } = useTranslation("dashboard"); - const openMore = useCallback((e: React.MouseEvent) => { - e.stopPropagation(); - window.open("https://cloudreve.org/pro", "_blank"); - }, []); - const showPromotion = useMemo(() => { - const now = dayjs(); - return now >= dayjs(currentPromotion.start) && now <= dayjs(currentPromotion.end); - }, []); - return ( - - - - {t("pro.description")} - - - - {t("pro.proInclude")} - - - - {features.map((feature) => ( - - - - - - {t(`pro.${feature}`)} - - - ))} - - {showPromotion && ( - , - }} - severity="info" - sx={{ mt: 2 }} - > - {t("pro.promotionTitle")} - , ]} - /> - - )} - - - - - {t("pro.learnMore")} - - - - ); -}; - -export default ProDialog; diff --git a/frontend/src/component/Admin/File/FileDialog/FileForm.tsx b/frontend/src/component/Admin/File/FileDialog/FileForm.tsx index b8fb4c14..2a6d790d 100644 --- a/frontend/src/component/Admin/File/FileDialog/FileForm.tsx +++ b/frontend/src/component/Admin/File/FileDialog/FileForm.tsx @@ -141,7 +141,7 @@ const FileForm = () => { )} {fileParentLoading && } - + {}} /> diff --git a/frontend/src/component/Admin/FileSystem/CustomProps/CustomPropsSetting.tsx b/frontend/src/component/Admin/FileSystem/CustomProps/CustomPropsSetting.tsx index 4320e096..736b9b57 100644 --- a/frontend/src/component/Admin/FileSystem/CustomProps/CustomPropsSetting.tsx +++ b/frontend/src/component/Admin/FileSystem/CustomProps/CustomPropsSetting.tsx @@ -19,8 +19,6 @@ import { CustomProps, CustomPropsType } from "../../../../api/explorer"; import { NoWrapCell, SecondaryButton, StyledTableContainerPaper } from "../../../Common/StyledComponents"; import { SquareMenuItem } from "../../../FileManager/ContextMenu/ContextMenu"; import Add from "../../../Icons/Add"; -import { ProChip } from "../../../Pages/Setting/SettingForm"; -import ProDialog from "../../Common/ProDialog"; import { SettingContext } from "../../Settings/SettingWrapper"; import DraggableCustomPropsRow, { FieldTypes } from "./DraggableCustomPropsRow"; import EditPropsDialog from "./EditPropsDialog"; @@ -32,7 +30,6 @@ const CustomPropsSetting = () => { const [open, setOpen] = useState(false); const [isNew, setIsNew] = useState(false); const [editProps, setEditProps] = useState(undefined); - const [proOpen, setProOpen] = useState(false); const newPropsPopupState = usePopupState({ variant: "popover", popupId: "newProp", @@ -117,7 +114,6 @@ const CustomPropsSetting = () => { return ( e.preventDefault()}> - setProOpen(false)} /> } {...bindTrigger(newPropsPopupState)}> {t("customProps.add")} @@ -138,12 +134,11 @@ const CustomPropsSetting = () => { const fieldType = FieldTypes[type]; const Icon = fieldType.icon; return ( - (fieldType.pro ? setProOpen(true) : onNewProp(type))}> + onNewProp(type)}> {t(fieldType.title)} - {fieldType.pro && } ); })} diff --git a/frontend/src/component/Admin/FileSystem/CustomProps/DraggableCustomPropsRow.tsx b/frontend/src/component/Admin/FileSystem/CustomProps/DraggableCustomPropsRow.tsx index ec673246..badfa6f8 100644 --- a/frontend/src/component/Admin/FileSystem/CustomProps/DraggableCustomPropsRow.tsx +++ b/frontend/src/component/Admin/FileSystem/CustomProps/DraggableCustomPropsRow.tsx @@ -45,7 +45,6 @@ export interface FieldTypeProps { maxDes?: string; maxRequired?: boolean; showOptions?: boolean; - pro?: boolean; } export const FieldTypes: Record = { @@ -82,7 +81,6 @@ export const FieldTypes: Record = { [CustomPropsType.user]: { title: "customProps.user", icon: PersonOutlined, - pro: true, }, [CustomPropsType.link]: { title: "customProps.link", diff --git a/frontend/src/component/Admin/Group/EditGroup/BasicInfoSection.tsx b/frontend/src/component/Admin/Group/EditGroup/BasicInfoSection.tsx index e7606533..27be3323 100644 --- a/frontend/src/component/Admin/Group/EditGroup/BasicInfoSection.tsx +++ b/frontend/src/component/Admin/Group/EditGroup/BasicInfoSection.tsx @@ -7,7 +7,7 @@ import Boolset from "../../../../util/boolset"; import SizeInput from "../../../Common/SizeInput"; import { DenseFilledTextField } from "../../../Common/StyledComponents"; import InPrivate from "../../../Icons/InPrivate"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../../Settings/Settings"; import { AnonymousGroupID } from "../GroupRow"; import { GroupSettingContext } from "./GroupSettingWrapper"; @@ -81,8 +81,7 @@ const BasicInfoSection = () => { {t("group.availablePoliciesDes")} - - {t("group.availablePolicyDesPro")} + {t("group.availablePolicyDesPro")} diff --git a/frontend/src/component/Admin/Group/EditGroup/DefaultPinnedSection.tsx b/frontend/src/component/Admin/Group/EditGroup/DefaultPinnedSection.tsx index b848f8ee..c86905cc 100644 --- a/frontend/src/component/Admin/Group/EditGroup/DefaultPinnedSection.tsx +++ b/frontend/src/component/Admin/Group/EditGroup/DefaultPinnedSection.tsx @@ -3,7 +3,7 @@ import { useContext } from "react"; import { Trans, useTranslation } from "react-i18next"; import { Link as RouterLink } from "react-router-dom"; import SharesInput from "../../Common/SharesInput"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../../Settings/Settings"; import { AnonymousGroupID } from "../GroupRow"; import { GroupSettingContext } from "./GroupSettingWrapper"; @@ -19,10 +19,10 @@ const DefaultPinnedSection = () => { return ( - {t("group.defaultPinned")} + {t("group.defaultPinned")} - + diff --git a/frontend/src/component/Admin/Group/EditGroup/FileManagementSection.tsx b/frontend/src/component/Admin/Group/EditGroup/FileManagementSection.tsx index d0a5574d..4e3f8914 100644 --- a/frontend/src/component/Admin/Group/EditGroup/FileManagementSection.tsx +++ b/frontend/src/component/Admin/Group/EditGroup/FileManagementSection.tsx @@ -18,8 +18,7 @@ import { GroupPermission } from "../../../../api/user"; import Boolset from "../../../../util/boolset"; import SizeInput from "../../../Common/SizeInput"; import { DenseFilledTextField } from "../../../Common/StyledComponents"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; -import ProDialog from "../../Common/ProDialog"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../../Settings/Settings"; import { AnonymousGroupID } from "../GroupRow"; import { GroupSettingContext } from "./GroupSettingWrapper"; @@ -30,7 +29,6 @@ const MonacoEditor = lazy(() => import("../../../Viewers/CodeViewer/MonacoEditor const FileManagementSection = () => { const { t } = useTranslation("dashboard"); const { values, setGroup } = useContext(GroupSettingContext); - const [proOpen, setProOpen] = useState(false); const theme = useTheme(); const [editedConfig, setEditedConfig] = useState(""); @@ -154,14 +152,8 @@ const FileManagementSection = () => { [setGroup], ); - const onProClick = useCallback((e: React.MouseEvent) => { - e.stopPropagation(); - setProOpen(true); - }, []); - return ( - setProOpen(false)} /> {t("group.fileManagement")} @@ -196,13 +188,12 @@ const FileManagementSection = () => { - + } label={ {t("group.migratePolicy")} - } /> @@ -323,20 +314,19 @@ const FileManagementSection = () => { {t("group.advanceDeleteDes")} - + {t("group.allowedNodesDes")} - + } label={ {t("group.allowSelectNode")} - } /> diff --git a/frontend/src/component/Admin/Group/EditGroup/ShareSection.tsx b/frontend/src/component/Admin/Group/EditGroup/ShareSection.tsx index 840cd5f5..047692e2 100644 --- a/frontend/src/component/Admin/Group/EditGroup/ShareSection.tsx +++ b/frontend/src/component/Admin/Group/EditGroup/ShareSection.tsx @@ -1,11 +1,10 @@ import { Box, FormControl, FormControlLabel, Switch, Typography } from "@mui/material"; -import { useCallback, useContext, useMemo, useState } from "react"; +import { useCallback, useContext, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { GroupEnt } from "../../../../api/dashboard"; import { GroupPermission } from "../../../../api/user"; import Boolset from "../../../../util/boolset"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; -import ProDialog from "../../Common/ProDialog"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../../Settings/Settings"; import { AnonymousGroupID } from "../GroupRow"; import { GroupSettingContext } from "./GroupSettingWrapper"; @@ -13,7 +12,6 @@ import { GroupSettingContext } from "./GroupSettingWrapper"; const ShareSection = () => { const { t } = useTranslation("dashboard"); const { values, setGroup } = useContext(GroupSettingContext); - const [proOpen, setProOpen] = useState(false); const permission = useMemo(() => { return new Boolset(values.permissions ?? ""); @@ -39,14 +37,8 @@ const ShareSection = () => { [setGroup], ); - const onProClick = (e: React.MouseEvent) => { - e.stopPropagation(); - setProOpen(true); - }; - return ( - setProOpen(false)} /> {t("group.share")} @@ -65,13 +57,12 @@ const ShareSection = () => { )} - + } label={ {t("group.shareFree")} - } /> @@ -91,13 +82,12 @@ const ShareSection = () => { {values?.id != AnonymousGroupID && ( - + } label={ {t("group.esclateAnonymity")} - } /> diff --git a/frontend/src/component/Admin/Group/EditGroup/UploadDownloadSection.tsx b/frontend/src/component/Admin/Group/EditGroup/UploadDownloadSection.tsx index 6ac3d51e..04bbfe3d 100644 --- a/frontend/src/component/Admin/Group/EditGroup/UploadDownloadSection.tsx +++ b/frontend/src/component/Admin/Group/EditGroup/UploadDownloadSection.tsx @@ -6,7 +6,7 @@ import { GroupPermission } from "../../../../api/user"; import Boolset from "../../../../util/boolset"; import SizeInput from "../../../Common/SizeInput"; import { DenseFilledTextField } from "../../../Common/StyledComponents"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../../Settings/Settings"; import { AnonymousGroupID } from "../GroupRow"; import { GroupSettingContext } from "./GroupSettingWrapper"; @@ -160,14 +160,13 @@ const UploadDownloadSection = () => { {t("group.reuseDirectLinkDes")} - + } label={ {t("group.folderDirectLink")} - } /> diff --git a/frontend/src/component/Admin/Home/Home.tsx b/frontend/src/component/Admin/Home/Home.tsx index f9ae8cc8..06687659 100644 --- a/frontend/src/component/Admin/Home/Home.tsx +++ b/frontend/src/component/Admin/Home/Home.tsx @@ -29,7 +29,7 @@ import { getDashboardSummary } from "../../../api/api.ts"; import { HomepageSummary } from "../../../api/dashboard.ts"; import { useAppDispatch } from "../../../redux/hooks.ts"; import FacebookCircularProgress from "../../Common/CircularProgress.tsx"; -import { SecondaryButton, SquareChip } from "../../Common/StyledComponents.tsx"; +import { SecondaryButton } from "../../Common/StyledComponents.tsx"; import TimeBadge from "../../Common/TimeBadge.tsx"; import Book from "../../Icons/Book.tsx"; import BoxMultipleFilled from "../../Icons/BoxMultipleFilled.tsx"; @@ -39,11 +39,9 @@ import HomeIcon from "../../Icons/Home.tsx"; import OpenFilled from "../../Icons/OpenFilled.tsx"; import PeopleFilled from "../../Icons/PeopleFilled.tsx"; import ShareFilled from "../../Icons/ShareFilled.tsx"; -import SparkleFilled from "../../Icons/SparkleFilled.tsx"; import Telegram from "../../Icons/Telegram.tsx"; import PageContainer from "../../Pages/PageContainer.tsx"; import PageHeader from "../../Pages/PageHeader.tsx"; -import ProDialog from "../Common/ProDialog.tsx"; import SiteUrlWarning from "./SiteUrlWarning.tsx"; import CommentMultiple from "../../Icons/CommentMultiple.tsx"; @@ -64,7 +62,6 @@ const Home = () => { const [summary, setSummary] = useState(); const [chartLoading, setChartLoading] = useState(false); const [siteUrlWarning, setSiteUrlWarning] = useState(false); - const [proDialogOpen, setProDialogOpen] = useState(false); useEffect(() => { loadSummary(false); }, []); @@ -90,7 +87,6 @@ const Home = () => { return ( - setProDialogOpen(false)} /> setSiteUrlWarning(false)} @@ -313,9 +309,6 @@ const Home = () => { Cloudreve - {summary && summary.version.pro && ( - - )} {summary ? summary.version.version : } @@ -383,14 +376,7 @@ const Home = () => { - {summary && !summary.version.pro && ( - setProDialogOpen(true)}> - - - - - - )} + diff --git a/frontend/src/component/Admin/Settings/Email/EmailTemplates.tsx b/frontend/src/component/Admin/Settings/Email/EmailTemplates.tsx index b05f75e8..7330f163 100644 --- a/frontend/src/component/Admin/Settings/Email/EmailTemplates.tsx +++ b/frontend/src/component/Admin/Settings/Email/EmailTemplates.tsx @@ -1,11 +1,10 @@ import { ExpandMoreRounded } from "@mui/icons-material"; import { Box, Typography } from "@mui/material"; import AccordionDetails from "@mui/material/AccordionDetails"; -import React, { useContext, useState } from "react"; +import React, { useContext } from "react"; import { useTranslation } from "react-i18next"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm.tsx"; +import SettingForm from "../../../Pages/Setting/SettingForm.tsx"; import { MagicVar } from "../../Common/MagicVarDialog.tsx"; -import ProDialog from "../../Common/ProDialog.tsx"; import { SettingContext } from "../SettingWrapper.tsx"; import { SettingSection, SettingSectionContent } from "../Settings.tsx"; import { AccordionSummary, StyledAccordion } from "../UserSession/SSOSettings.tsx"; @@ -15,7 +14,6 @@ interface EmailTemplate { title: string; description: string; magicVars: MagicVar[]; - pro: boolean; } const commonMagicVars: MagicVar[] = [ @@ -77,7 +75,6 @@ const userMagicVars: MagicVar[] = [ const EmailTemplates: React.FC = () => { const { t } = useTranslation("dashboard"); const { setSettings, values } = useContext(SettingContext); - const [proOpen, setProOpen] = useState(false); // Template setting keys const templateSettings = [ @@ -85,7 +82,6 @@ const EmailTemplates: React.FC = () => { key: "mail_receipt_template", title: "receiptEmailTemplate", description: "receiptEmailTemplateDes", - pro: true, }, { key: "mail_activation_template", @@ -105,7 +101,6 @@ const EmailTemplates: React.FC = () => { key: "mail_exceed_quota_template", title: "quotaExceededEmailTemplate", description: "quotaExceededEmailTemplateDes", - pro: true, }, { key: "mail_reset_template", @@ -123,14 +118,8 @@ const EmailTemplates: React.FC = () => { }, ]; - const handleProClick = (e: React.MouseEvent) => { - e.preventDefault(); - setProOpen(true); - }; - return ( - setProOpen(false)} /> {t("settings.emailTemplates")} @@ -139,15 +128,12 @@ const EmailTemplates: React.FC = () => { {templateSettings.map((template) => ( }> {t("settings." + template.title)} - {template.pro && } diff --git a/frontend/src/component/Admin/Settings/Event/Events.tsx b/frontend/src/component/Admin/Settings/Event/Events.tsx index 5326c6d3..acdef70d 100644 --- a/frontend/src/component/Admin/Settings/Event/Events.tsx +++ b/frontend/src/component/Admin/Settings/Event/Events.tsx @@ -9,11 +9,9 @@ import { Stack, Typography, } from "@mui/material"; -import { useContext, useState } from "react"; +import { useContext } from "react"; import { useTranslation } from "react-i18next"; import { AuditLogType } from "../../../../api/explorer"; -import { ProChip } from "../../../Pages/Setting/SettingForm"; -import ProDialog from "../../Common/ProDialog"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../Settings"; import { SettingContext } from "../SettingWrapper"; @@ -131,27 +129,20 @@ export const getEventName = (eventType: number): string => { const Events = () => { const { t } = useTranslation("dashboard"); const { formRef, setSettings, values } = useContext(SettingContext); - const [proOpen, setProOpen] = useState(false); - - const handleProClick = (e: React.MouseEvent) => { - e.preventDefault(); - setProOpen(true); - }; return ( e.preventDefault()}> - setProOpen(false)} /> - {t("settings.auditLog")} + {t("settings.auditLog")} {t("settings.auditLogDes")} {Object.entries(eventCategories).map(([categoryKey, category]) => ( - + {t(category.title)} diff --git a/frontend/src/component/Admin/Settings/SiteInformation/SiteInformation.tsx b/frontend/src/component/Admin/Settings/SiteInformation/SiteInformation.tsx index 2d69b723..d28eefa0 100644 --- a/frontend/src/component/Admin/Settings/SiteInformation/SiteInformation.tsx +++ b/frontend/src/component/Admin/Settings/SiteInformation/SiteInformation.tsx @@ -64,7 +64,7 @@ const SiteInformation = () => { {t("settings.customFooterHTMLDes")} - + {t("settings.announcementDes")} @@ -229,7 +229,7 @@ const SiteInformation = () => { {t("vas.showAppPromotionDes")} - + { {t("vas.appLinkDes")} - + {t("vas.appLinkDes")} diff --git a/frontend/src/component/Admin/Settings/UserSession/SSOSettings.tsx b/frontend/src/component/Admin/Settings/UserSession/SSOSettings.tsx index 4492f18f..8d8c6fae 100644 --- a/frontend/src/component/Admin/Settings/UserSession/SSOSettings.tsx +++ b/frontend/src/component/Admin/Settings/UserSession/SSOSettings.tsx @@ -4,7 +4,6 @@ import MuiAccordionSummary, { AccordionSummaryProps } from "@mui/material/Accord import { useCallback, useState } from "react"; import { useTranslation } from "react-i18next"; import { StyledCheckbox } from "../../../Common/StyledComponents.tsx"; -import ProDialog from "../../Common/ProDialog.tsx"; export const AccordionSummary = styled((props: AccordionSummaryProps) => )( ({ theme }) => ({ @@ -38,7 +37,6 @@ const SSOSettings = () => { }, []); return ( <> - setOpen(false)} />
}> diff --git a/frontend/src/component/Admin/Settings/UserSession/UserSession.tsx b/frontend/src/component/Admin/Settings/UserSession/UserSession.tsx index bb264cc0..b9e24f5d 100644 --- a/frontend/src/component/Admin/Settings/UserSession/UserSession.tsx +++ b/frontend/src/component/Admin/Settings/UserSession/UserSession.tsx @@ -6,7 +6,7 @@ import { isTrueVal } from "../../../../session/utils.ts"; import SizeInput from "../../../Common/SizeInput.tsx"; import { DenseFilledTextField, DenseSelect } from "../../../Common/StyledComponents.tsx"; import { SquareMenuItem } from "../../../FileManager/ContextMenu/ContextMenu.tsx"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm.tsx"; +import SettingForm from "../../../Pages/Setting/SettingForm.tsx"; import { Code } from "../../../Common/Code.tsx"; import GroupSelectionInput from "../../Common/GroupSelectionInput.tsx"; import SharesInput from "../../Common/SharesInput.tsx"; @@ -127,7 +127,7 @@ const UserSession = () => { {t("settings.defaultGroupDes")} - + @@ -139,7 +139,7 @@ const UserSession = () => { - + {["filterEmailProviderDisabled", "filterEmailProviderWhitelist", "filterEmailProviderBlacklist"].map( @@ -159,14 +159,13 @@ const UserSession = () => { {t("vas.filterEmailProviderDes")} - + } label={ <> {t("vas.disableSubAddressEmail")} - } /> @@ -179,7 +178,7 @@ const UserSession = () => { - {t("settings.thirdPartySignIn")} + {t("settings.thirdPartySignIn")} diff --git a/frontend/src/component/Admin/Settings/VAS/VAS.tsx b/frontend/src/component/Admin/Settings/VAS/VAS.tsx index be195991..f2922cb9 100644 --- a/frontend/src/component/Admin/Settings/VAS/VAS.tsx +++ b/frontend/src/component/Admin/Settings/VAS/VAS.tsx @@ -10,11 +10,10 @@ import { Typography, } from "@mui/material"; import { bindTrigger, usePopupState } from "material-ui-popup-state/hooks"; -import { useContext, useMemo, useState } from "react"; +import { useContext, useMemo } from "react"; import { Trans, useTranslation } from "react-i18next"; import { DenseFilledTextField } from "../../../Common/StyledComponents.tsx"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm.tsx"; -import ProDialog from "../../Common/ProDialog.tsx"; +import SettingForm from "../../../Pages/Setting/SettingForm.tsx"; import { NoMarginHelperText, SettingSection, SettingSectionContent } from "../Settings.tsx"; import { SettingContext } from "../SettingWrapper.tsx"; import GiftCodes from "./GiftCodes.tsx"; @@ -30,7 +29,6 @@ interface CurrencyOption { const VAS = () => { const { t } = useTranslation("dashboard"); - const [proOpen, setProOpen] = useState(false); const { formRef, setSettings, values } = useContext(SettingContext); const currencyPopupState = usePopupState({ variant: "popover", @@ -40,20 +38,14 @@ const VAS = () => { const storageProducts = useMemo(() => values.storage_products || "[]", [values.storage_products]); const groupSellData = useMemo(() => values.group_sell_data || "[]", [values.group_sell_data]); - const onProClick = (e: React.MouseEvent) => { - e.preventDefault(); - setProOpen(true); - }; - return ( - setProOpen(false)} /> - {t("settings.creditAndVAS")} + {t("settings.creditAndVAS")} - + } label={t("settings.enableCredit")} /> @@ -134,9 +126,9 @@ const VAS = () => { - {t("settings.paymentSettings")} + {t("settings.paymentSettings")} - + { - {t("settings.storageProductSettings")} + {t("settings.storageProductSettings")} - + @@ -197,9 +189,9 @@ const VAS = () => { - {t("settings.groupProductSettings")} + {t("settings.groupProductSettings")} - + @@ -211,9 +203,9 @@ const VAS = () => { - {t("giftCodes.giftCodesSettings")} + {t("giftCodes.giftCodesSettings")} - + diff --git a/frontend/src/component/Admin/StoragePolicy/SelectProvider.tsx b/frontend/src/component/Admin/StoragePolicy/SelectProvider.tsx index d339985d..17227d72 100644 --- a/frontend/src/component/Admin/StoragePolicy/SelectProvider.tsx +++ b/frontend/src/component/Admin/StoragePolicy/SelectProvider.tsx @@ -15,9 +15,6 @@ import { SecondaryButton } from "../../Common/StyledComponents"; import DraggableDialog from "../../Dialogs/DraggableDialog"; import Open from "../../Icons/Open"; import { PolicyPropsMap } from "./StoragePolicySetting"; -import { useState } from "react"; -import ProDialog from "../Common/ProDialog.tsx"; -import { ProChip } from "../../Pages/Setting/SettingForm.tsx"; export interface SelectProviderProps { open: boolean; @@ -33,7 +30,6 @@ const StyledCard = styled(Card)(({ theme }) => ({ const SelectProvider = ({ open, onClose, onSelect }: SelectProviderProps) => { const { t } = useTranslation("dashboard"); - const [proOpen, setProOpen] = useState(false); return ( { maxWidth: "sm", }} > - setProOpen(false)} /> {Object.values(PolicyType).map((type) => ( @@ -52,13 +47,12 @@ const SelectProvider = ({ open, onClose, onSelect }: SelectProviderProps) => { (PolicyPropsMap[type].pro ? setProOpen(true) : onSelect(type))} + onClick={() => onSelect(type)} > {t(PolicyPropsMap[type].name)} - {PolicyPropsMap[type].pro && } diff --git a/frontend/src/component/Admin/StoragePolicy/StoragePolicySetting.tsx b/frontend/src/component/Admin/StoragePolicy/StoragePolicySetting.tsx index 653455a1..e5fff526 100644 --- a/frontend/src/component/Admin/StoragePolicy/StoragePolicySetting.tsx +++ b/frontend/src/component/Admin/StoragePolicy/StoragePolicySetting.tsx @@ -61,7 +61,6 @@ export interface PolicyProps { credentialDes?: React.ReactNode; corsExposedHeaders?: string[]; endpointNotEnforcePrefix?: boolean; - pro?: boolean; regionCode?: string; regionCodeDes?: React.ReactNode; } @@ -78,7 +77,6 @@ export const PolicyPropsMap: Record = { name: "policy.load_balance", img: "/static/img/lb.svg", wizardSize: "sm", - pro: true, }, [PolicyType.remote]: { name: "policy.remote", diff --git a/frontend/src/component/Admin/User/UserDialog/UserForm.tsx b/frontend/src/component/Admin/User/UserDialog/UserForm.tsx index a5eff881..abcdbcdc 100644 --- a/frontend/src/component/Admin/User/UserDialog/UserForm.tsx +++ b/frontend/src/component/Admin/User/UserDialog/UserForm.tsx @@ -14,8 +14,9 @@ import { useTheme, } from "@mui/material"; import { useSnackbar } from "notistack"; -import { useCallback, useContext, useState } from "react"; +import { useCallback, useContext } from "react"; import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; import { sendCalibrateUserStorage } from "../../../../api/api"; import { UserStatus } from "../../../../api/dashboard"; import { useAppDispatch } from "../../../../redux/hooks"; @@ -24,10 +25,9 @@ import { DenseFilledTextField, DenseSelect, SecondaryButton } from "../../../Com import UserAvatar from "../../../Common/User/UserAvatar"; import { SquareMenuItem } from "../../../FileManager/ContextMenu/ContextMenu"; import Delete from "../../../Icons/Delete"; -import SettingForm, { ProChip } from "../../../Pages/Setting/SettingForm"; +import SettingForm from "../../../Pages/Setting/SettingForm"; import { CapacityBar } from "../../../Pages/Setting/StorageSetting"; import GroupSelectionInput from "../../Common/GroupSelectionInput"; -import ProDialog from "../../Common/ProDialog"; import { NoMarginHelperText } from "../../Settings/Settings"; import { UserDialogContext } from "./UserDialog"; @@ -37,8 +37,8 @@ const UserForm = ({ reload, setLoading }: { reload: () => void; setLoading: (loa const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down("md")); const { t } = useTranslation("dashboard"); + const navigate = useNavigate(); const { formRef, values, setUser } = useContext(UserDialogContext); - const [proOpen, setProOpen] = useState(false); const removeAvatar = useCallback(() => { setUser((prev) => ({ ...prev, avatar: undefined })); @@ -109,7 +109,6 @@ const UserForm = ({ reload, setLoading }: { reload: () => void; setLoading: (loa return ( e.preventDefault()}> - setProOpen(false)} /> @@ -150,11 +149,11 @@ const UserForm = ({ reload, setLoading }: { reload: () => void; setLoading: (loa setProOpen(true)} + onClick={() => navigate(`/admin/file?owner=${values.id}`)} variant="contained" startIcon={} > - {t("user.openUserFiles")} + {t("user.openUserFiles")} @@ -183,7 +182,7 @@ const UserForm = ({ reload, setLoading }: { reload: () => void; setLoading: (loa - + void; setLoading: (loa type={"password"} /> - + {}} @@ -220,7 +219,7 @@ const UserForm = ({ reload, setLoading }: { reload: () => void; setLoading: (loa /> {t("user.originUserGroupDes")} - + {t("user.groupExpiredDes")} diff --git a/frontend/src/component/Frame/NavBar/PageNavigation.tsx b/frontend/src/component/Frame/NavBar/PageNavigation.tsx index 00be5cc2..1b6b9134 100644 --- a/frontend/src/component/Frame/NavBar/PageNavigation.tsx +++ b/frontend/src/component/Frame/NavBar/PageNavigation.tsx @@ -1,14 +1,13 @@ import { Icon as Iconify } from "@iconify/react"; import { Box, SvgIconProps, useTheme } from "@mui/material"; import SvgIcon from "@mui/material/SvgIcon/SvgIcon"; -import { memo, useMemo, useState } from "react"; +import { memo, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { useLocation, useNavigate } from "react-router-dom"; import { GroupPermission } from "../../../api/user.ts"; import { useAppSelector } from "../../../redux/hooks.ts"; import SessionManager from "../../../session"; import { GroupBS } from "../../../session/utils.ts"; -import ProDialog from "../../Admin/Common/ProDialog.tsx"; import BoxMultiple from "../../Icons/BoxMultiple.tsx"; import BoxMultipleFilled from "../../Icons/BoxMultipleFilled.tsx"; import CloudDownload from "../../Icons/CloudDownload.tsx"; @@ -45,7 +44,6 @@ import StorageOutlined from "../../Icons/StorageOutlined.tsx"; import Warning from "../../Icons/Warning.tsx"; import WarningOutlined from "../../Icons/WarningOutlined.tsx"; import WrenchSettings from "../../Icons/WrenchSettings.tsx"; -import { ProChip } from "../../Pages/Setting/SettingForm.tsx"; import NavIconTransition from "./NavIconTransition.tsx"; import SideNavItem from "./SideNavItem.tsx"; @@ -54,7 +52,6 @@ export interface NavigationItem { icon?: ((props: SvgIconProps) => JSX.Element)[] | (typeof SvgIcon)[]; iconifyName?: string; path: string; - pro?: boolean; } let NavigationItems: NavigationItem[]; @@ -89,36 +86,15 @@ export const SideNavItemComponent = ({ item }: { item: NavigationItem }) => { const navigate = useNavigate(); const location = useLocation(); const theme = useTheme(); - const [proOpen, setProOpen] = useState(false); const active = useMemo(() => { return location.pathname == item.path || location.pathname.startsWith(item.path + "/"); }, [location.pathname, item.path]); return ( <> - {item.pro && setProOpen(false)} />} - item.pro ? setProOpen(true) : item.iconifyName ? window.open(item.path, "_blank") : navigate(item.path) - } - label={ - item.pro ? ( - - {t(item.label)} - t.typography.caption.fontSize, - }} - label="Pro" - color="primary" - size="small" - /> - - ) : ( - t(item.label) - ) - } + onClick={() => (item.iconifyName ? window.open(item.path, "_blank") : navigate(item.path))} + label={t(item.label)} active={active} icon={ !item.icon ? ( @@ -211,19 +187,16 @@ AdminNavigationItems = [ label: "dashboard:vas.orders", icon: [PaymentFilled, Payment], path: "/admin/payment", - pro: true, }, { label: "dashboard:nav.events", icon: [SendLoggingFilled, SendLogging], path: "/admin/event", - pro: true, }, { label: "dashboard:nav.abuseReport", icon: [Warning, WarningOutlined], path: "/admin/abuse", - pro: true, }, { label: "dashboard:nav.oauthClients", @@ -253,7 +226,6 @@ export const AdminPageNavigation = memo(() => { }); const PageNavigation = () => { - const shopNavEnabled = useAppSelector((state) => state.siteConfig.basic.config.shop_nav_enabled); const appPromotionEnabled = useAppSelector((state) => state.siteConfig.basic.config.app_promotion); const user = SessionManager.currentLoginOrNull(); const isAdmin = useMemo(() => { diff --git a/frontend/src/component/Pages/Setting/SettingForm.tsx b/frontend/src/component/Pages/Setting/SettingForm.tsx index 29106fee..d55901f1 100644 --- a/frontend/src/component/Pages/Setting/SettingForm.tsx +++ b/frontend/src/component/Pages/Setting/SettingForm.tsx @@ -1,14 +1,5 @@ -import { Chip, Grid2, Typography, styled } from "@mui/material"; -import { useCallback, useEffect, useState } from "react"; -import ProDialog from "../../Admin/Common/ProDialog"; - -export const ProChip = styled(Chip)(({ theme }) => ({ - marginLeft: 8, - height: "20px", - fontSize: "12px", - background: `linear-gradient(45deg, ${theme.palette.primary.main} 30%, ${theme.palette.primary.light} 90%)`, - color: theme.palette.primary.contrastText, -})); +import { Grid2, Typography } from "@mui/material"; +import { useEffect } from "react"; export interface SettingFormProps { title?: React.ReactNode; @@ -18,7 +9,6 @@ export interface SettingFormProps { spacing?: number; anchorId?: string; noContainer?: boolean; - pro?: boolean; } const SettingForm = ({ @@ -29,9 +19,7 @@ const SettingForm = ({ spacing, noContainer, anchorId, - pro, }: SettingFormProps) => { - const [proOpen, setProOpen] = useState(false); useEffect(() => { if (anchorId && window.location.hash === `#${anchorId}`) { const anchor = document.getElementById(`anchor-${anchorId}`); @@ -43,16 +31,6 @@ const SettingForm = ({ } }, [anchorId]); - const handleProClick = useCallback( - (e: React.MouseEvent) => { - if (pro) { - e.stopPropagation(); - setProOpen(true); - } - }, - [pro], - ); - const inner = ( <> {title} - {pro && } )} -
{children}
+ {children}
{secondary && secondary} - {pro && setProOpen(false)} />} ); if (noContainer) {