"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const designSystem = require("@strapi/design-system");
const helperPlugin = require("@strapi/helper-plugin");
const reactHelmet = require("react-helmet");
const reactIntl = require("react-intl");
const reactRouterDom = require("react-router-dom");
const index = require("./index-3649838b.js");
const sortBy = require("lodash/sortBy");
const reactRedux = require("react-redux");
const AuthenticatedApp = require("./AuthenticatedApp-bb793364.js");
const v2 = require("@strapi/design-system/v2");
const Icons = require("@strapi/icons");
const PropTypes = require("prop-types");
const styled = require("styled-components");
const reactQuery = require("react-query");
const produce = require("immer");
const merge = require("lodash/merge");
require("react-dom/client");
require("invariant");
require("lodash/isFunction");
require("lodash/pick");
require("@radix-ui/react-context");
require("formik");
require("lodash/camelCase");
require("yup");
require("lodash/defaultsDeep");
require("lodash/omit");
require("qs");
require("lodash/get");
require("lodash/set");
require("@reduxjs/toolkit");
require("semver/functions/lt");
require("semver/functions/valid");
require("react-dnd");
require("react-dnd-html5-backend");
require("lodash/cloneDeep");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
function _interopNamespace(e) {
  if (e && e.__esModule)
    return e;
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
  if (e) {
    for (const k in e) {
      if (k !== "default") {
        const d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: () => e[k]
        });
      }
    }
  }
  n.default = e;
  return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespace(React);
const sortBy__default = /* @__PURE__ */ _interopDefault(sortBy);
const PropTypes__default = /* @__PURE__ */ _interopDefault(PropTypes);
const styled__default = /* @__PURE__ */ _interopDefault(styled);
const produce__default = /* @__PURE__ */ _interopDefault(produce);
const merge__default = /* @__PURE__ */ _interopDefault(merge);
const formatLinks = (menu) => menu.map((menuSection) => {
  const formattedLinks = menuSection.links.map((link) => ({
    ...link,
    isDisplayed: false
  }));
  return { ...menuSection, links: formattedLinks };
});
const useSettingsMenu = () => {
  const [{ isLoading, menu }, setData] = React__namespace.useState({
    isLoading: true,
    menu: []
  });
  const { allPermissions: userPermissions } = helperPlugin.useRBACProvider();
  const { shouldUpdateStrapi } = helperPlugin.useAppInfo();
  const { settings } = helperPlugin.useStrapiApp();
  const permissions = reactRedux.useSelector(AuthenticatedApp.selectAdminPermissions);
  const ceLinks = React__namespace.useMemo(() => index.SETTINGS_LINKS_CE(), []);
  const { admin: adminLinks, global: globalLinks } = index.useEnterprise(
    ceLinks,
    async () => (await Promise.resolve().then(() => require("./constants-7596f6f3.js"))).SETTINGS_LINKS_EE(),
    {
      combine(ceLinks2, eeLinks) {
        return {
          admin: [...eeLinks.admin, ...ceLinks2.admin],
          global: [...ceLinks2.global, ...eeLinks.global]
        };
      },
      defaultValue: {
        admin: [],
        global: []
      }
    }
  );
  const addPermissions = React__namespace.useCallback(
    (link) => {
      if (!link.id) {
        throw new Error("The settings menu item must have an id attribute.");
      }
      return {
        ...link,
        permissions: permissions.settings?.[link.id]?.main ?? []
      };
    },
    [permissions.settings]
  );
  React__namespace.useEffect(() => {
    const getData = async () => {
      const buildMenuPermissions = (sections2) => Promise.all(
        sections2.reduce((acc, section, sectionIndex) => {
          const linksWithPermissions = section.links.map(async (link, linkIndex) => ({
            hasPermission: await helperPlugin.hasPermissions(userPermissions, link.permissions),
            sectionIndex,
            linkIndex
          }));
          return [...acc, ...linksWithPermissions];
        }, [])
      );
      const menuPermissions = await buildMenuPermissions(sections);
      setData((prev) => {
        return {
          ...prev,
          isLoading: false,
          menu: sections.map((section, sectionIndex) => ({
            ...section,
            links: section.links.map((link, linkIndex) => {
              const permission = menuPermissions.find(
                (permission2) => permission2.sectionIndex === sectionIndex && permission2.linkIndex === linkIndex
              );
              return {
                ...link,
                isDisplayed: Boolean(permission?.hasPermission)
              };
            })
          }))
        };
      });
    };
    const { global, ...otherSections } = settings;
    const sections = formatLinks([
      {
        ...global,
        links: sortBy__default.default([...global.links, ...globalLinks.map(addPermissions)], (link) => link.id).map(
          (link) => ({
            ...link,
            hasNotification: link.id === "000-application-infos" && shouldUpdateStrapi
          })
        )
      },
      {
        id: "permissions",
        intlLabel: { id: "Settings.permissions", defaultMessage: "Administration Panel" },
        links: adminLinks.map(addPermissions)
      },
      ...Object.values(otherSections)
    ]);
    getData();
  }, [adminLinks, globalLinks, userPermissions, settings, shouldUpdateStrapi, addPermissions]);
  return {
    isLoading,
    menu: menu.map((menuItem) => ({
      ...menuItem,
      links: menuItem.links.filter((link) => link.isDisplayed)
    }))
  };
};
const CustomIcon = styled__default.default(designSystem.Icon)`
  right: 15px;
  position: absolute;
`;
const SettingsNav = ({ menu }) => {
  const { formatMessage } = reactIntl.useIntl();
  const { trackUsage } = helperPlugin.useTracking();
  const { pathname } = reactRouterDom.useLocation();
  const filteredMenu = menu.filter(
    (section) => !section.links.every((link) => link.isDisplayed === false)
  );
  const sections = filteredMenu.map((section) => {
    return {
      ...section,
      title: section.intlLabel,
      links: section.links.map((link) => {
        return {
          ...link,
          title: link.intlLabel,
          name: link.id
        };
      })
    };
  });
  const label = formatMessage({
    id: "global.settings",
    defaultMessage: "Settings"
  });
  const handleClickOnLink = (destination = null) => {
    trackUsage("willNavigate", { from: pathname, to: destination });
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(v2.SubNav, { ariaLabel: label, children: [
    /* @__PURE__ */ jsxRuntime.jsx(v2.SubNavHeader, { label }),
    /* @__PURE__ */ jsxRuntime.jsx(v2.SubNavSections, { children: sections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(v2.SubNavSection, { label: formatMessage(section.intlLabel), children: section.links.map((link) => {
      return /* @__PURE__ */ jsxRuntime.jsxs(
        v2.SubNavLink,
        {
          as: reactRouterDom.NavLink,
          withBullet: link.hasNotification,
          to: link.to,
          onClick: () => handleClickOnLink(link.to),
          children: [
            formatMessage(link.intlLabel),
            link?.lockIcon && /* @__PURE__ */ jsxRuntime.jsx(CustomIcon, { width: `${15 / 16}rem`, height: `${15 / 16}rem`, as: Icons.Lock })
          ]
        },
        link.id
      );
    }) }, section.id)) })
  ] });
};
SettingsNav.propTypes = {
  menu: PropTypes__default.default.array.isRequired
};
const ROUTES_CE = [
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-c42be44a.js"));
      return component;
    },
    to: "/settings/roles",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-aed4a645.js"));
      return component;
    },
    to: "/settings/roles/duplicate/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-aed4a645.js"));
      return component;
    },
    to: "/settings/roles/new",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-6207c6dd.js"));
      return component;
    },
    to: "/settings/roles/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-ee2f0d5e.js")).then((n) => n.index);
      return component;
    },
    to: "/settings/users",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-47cd65b8.js"));
      return component;
    },
    to: "/settings/users/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-8244d212.js"));
      return component;
    },
    to: "/settings/webhooks/create",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-e18df7fe.js"));
      return component;
    },
    to: "/settings/webhooks/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-709c75fe.js"));
      return component;
    },
    to: "/settings/webhooks",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-22ba8e69.js"));
      return component;
    },
    to: "/settings/api-tokens",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-695b3387.js"));
      return component;
    },
    to: "/settings/api-tokens/create",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-c5e5c8b4.js"));
      return component;
    },
    to: "/settings/api-tokens/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-1688d470.js"));
      return component;
    },
    to: "/settings/transfer-tokens/create",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-7af010f9.js"));
      return component;
    },
    to: "/settings/transfer-tokens",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./index-4610913e.js"));
      return component;
    },
    to: "/settings/transfer-tokens/:id",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./SalesPage-d0cdc1a7.js"));
      return component;
    },
    to: "/settings/purchase-audit-logs",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./SalesPage-4a0a68fb.js"));
      return component;
    },
    to: "/settings/purchase-review-workflows",
    exact: true
  },
  {
    async Component() {
      const component = await Promise.resolve().then(() => require("./SalesPage-66f9ea32.js"));
      return component;
    },
    to: "/settings/purchase-single-sign-on",
    exact: true
  }
];
const DIMENSION = 750;
const SIZE = 100;
const ACCEPTED_FORMAT = ["image/jpeg", "image/png", "image/svg+xml"];
const initialState$2 = {
  localImage: void 0
};
const reducer$2 = (state = initialState$2, action) => produce__default.default(state, (draftState) => {
  switch (action.type) {
    case "SET_LOCAL_IMAGE": {
      draftState.localImage = action.value;
      break;
    }
    default: {
      return draftState;
    }
  }
});
const LogoModalStepper = ({
  onChangeLogo,
  customLogo,
  goTo,
  Component,
  modalTitle,
  next,
  prev,
  currentStep
}) => {
  const [{ localImage }, dispatch] = React.useReducer(reducer$2, initialState$2);
  const { formatMessage } = reactIntl.useIntl();
  const setLocalImage = (asset) => {
    dispatch({
      type: "SET_LOCAL_IMAGE",
      value: asset
    });
  };
  const handleCloseModal = () => {
    goTo(null);
  };
  if (!currentStep) {
    return null;
  }
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.ModalLayout, { labelledBy: "modal", onClose: handleCloseModal, children: [
    /* @__PURE__ */ jsxRuntime.jsx(designSystem.ModalHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", as: "h2", id: "modal", children: formatMessage(modalTitle) }) }),
    /* @__PURE__ */ jsxRuntime.jsx(
      Component,
      {
        setLocalImage,
        goTo,
        next,
        prev,
        onClose: handleCloseModal,
        asset: localImage || customLogo,
        onChangeLogo
      }
    )
  ] });
};
LogoModalStepper.defaultProps = {
  Component: void 0,
  currentStep: void 0,
  customLogo: void 0,
  modalTitle: void 0,
  next: null,
  prev: null
};
LogoModalStepper.propTypes = {
  Component: PropTypes__default.default.elementType,
  currentStep: PropTypes__default.default.string,
  customLogo: PropTypes__default.default.shape({
    name: PropTypes__default.default.string,
    url: PropTypes__default.default.string,
    width: PropTypes__default.default.number,
    height: PropTypes__default.default.number,
    ext: PropTypes__default.default.string
  }),
  goTo: PropTypes__default.default.func.isRequired,
  modalTitle: PropTypes__default.default.shape({
    id: PropTypes__default.default.string,
    defaultMessage: PropTypes__default.default.string
  }),
  next: PropTypes__default.default.string,
  onChangeLogo: PropTypes__default.default.func.isRequired,
  prev: PropTypes__default.default.string
};
const initialState$1 = {
  currentStep: void 0
};
const reducer$1 = (state = initialState$1, action) => produce__default.default(state, (draftState) => {
  switch (action.type) {
    case "GO_TO": {
      draftState.currentStep = action.to;
      break;
    }
    default: {
      return draftState;
    }
  }
});
const FILE_FORMAT_ERROR_MESSAGE = {
  id: "Settings.application.customization.modal.upload.error-format",
  defaultMessage: "Wrong format uploaded (accepted formats only: jpeg, jpg, png, svg)."
};
const FILE_SIZING_ERROR_MESSAGE = {
  id: "Settings.application.customization.modal.upload.error-size",
  defaultMessage: "The file uploaded is too large (max dimension: {dimension}x{dimension}, max file size: {size}KB)"
};
const getFileDimensions = (file) => {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onload = () => {
      const img = new Image();
      img.onload = function() {
        resolve({ width: img.width, height: img.height });
      };
      img.src = reader.result;
    };
    reader.readAsDataURL(file);
  });
};
const rawFileToAsset = (rawFile, fileDimensions) => {
  return {
    ext: rawFile.name.split(".").pop(),
    size: rawFile.size / 1e3,
    name: rawFile.name,
    url: URL.createObjectURL(rawFile),
    rawFile,
    width: fileDimensions.width,
    height: fileDimensions.height
  };
};
const parseFileMetadatas = async (file) => {
  let error;
  const isFormatAuthorized = ACCEPTED_FORMAT.includes(file.type);
  if (!isFormatAuthorized) {
    error = new Error("File format");
    error.displayMessage = FILE_FORMAT_ERROR_MESSAGE;
    throw error;
  }
  const fileDimensions = await getFileDimensions(file);
  const areDimensionsAuthorized = fileDimensions.width <= DIMENSION && fileDimensions.height <= DIMENSION;
  if (!areDimensionsAuthorized) {
    error = new Error("File sizing");
    error.displayMessage = FILE_SIZING_ERROR_MESSAGE;
    throw error;
  }
  const asset = rawFileToAsset(file, fileDimensions);
  const isSizeAuthorized = asset.size <= SIZE;
  if (!isSizeAuthorized) {
    error = new Error("File sizing");
    error.displayMessage = FILE_SIZING_ERROR_MESSAGE;
    throw error;
  }
  return asset;
};
const FileInput = styled__default.default(designSystem.FieldInput)`
  opacity: 0;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
`;
const FromComputerForm = ({ setLocalImage, goTo, next, onClose }) => {
  const { formatMessage } = reactIntl.useIntl();
  const [dragOver, setDragOver] = React.useState(false);
  const [fileError, setFileError] = React.useState(void 0);
  const inputRef = React.useRef(null);
  const handleDragEnter = () => setDragOver(true);
  const handleDragLeave = () => setDragOver(false);
  const handleClick = (e) => {
    e.preventDefault();
    inputRef.current.click();
  };
  const handleChange = async () => {
    handleDragLeave();
    const file = inputRef.current.files[0];
    if (!file) {
      return;
    }
    try {
      const asset = await parseFileMetadatas(file);
      setLocalImage(asset);
      goTo(next);
    } catch (err) {
      if (err.displayMessage) {
        setFileError(formatMessage(err.displayMessage, { size: SIZE, dimension: DIMENSION }));
        inputRef.current.focus();
      } else {
        throw err;
      }
    }
  };
  const getBorderColor = () => {
    if (dragOver) {
      return "primary500";
    }
    if (fileError) {
      return "danger600";
    }
    return "neutral300";
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    /* @__PURE__ */ jsxRuntime.jsx("form", { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field, { name: "logo-upload", error: fileError, children: /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "logo-upload", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
      /* @__PURE__ */ jsxRuntime.jsxs(
        designSystem.Flex,
        {
          paddingTop: 9,
          paddingBottom: 7,
          hasRadius: true,
          justifyContent: "center",
          direction: "column",
          background: dragOver ? "primary100" : "neutral100",
          borderColor: getBorderColor(),
          borderStyle: "dashed",
          borderWidth: "1px",
          position: "relative",
          onDragEnter: handleDragEnter,
          onDragLeave: handleDragLeave,
          children: [
            /* @__PURE__ */ jsxRuntime.jsx(
              designSystem.Icon,
              {
                color: "primary600",
                width: `${60 / 16}rem`,
                height: `${60 / 16}rem`,
                as: Icons.PicturePlus,
                "aria-hidden": true
              }
            ),
            /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 3, paddingBottom: 5, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", as: "span", children: formatMessage({
              id: "Settings.application.customization.modal.upload.drag-drop",
              defaultMessage: "Drag and Drop here or"
            }) }) }),
            /* @__PURE__ */ jsxRuntime.jsx(
              FileInput,
              {
                accept: ACCEPTED_FORMAT,
                cursor: "pointer",
                as: "input",
                type: "file",
                name: "files",
                tabIndex: -1,
                zIndex: 1,
                onChange: handleChange,
                ref: inputRef,
                id: "logo-upload"
              }
            ),
            /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "button", onClick: handleClick, children: formatMessage({
              id: "Settings.application.customization.modal.upload.cta.browse",
              defaultMessage: "Browse files"
            }) }),
            /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
              {
                id: "Settings.application.customization.modal.upload.file-validation",
                defaultMessage: "Max dimension: {dimension}x{dimension}, Max size: {size}KB"
              },
              { size: SIZE, dimension: DIMENSION }
            ) }) })
          ]
        }
      ),
      /* @__PURE__ */ jsxRuntime.jsx(designSystem.FieldError, {})
    ] }) }) }) }) }),
    /* @__PURE__ */ jsxRuntime.jsx(
      designSystem.ModalFooter,
      {
        startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
          id: "Settings.application.customization.modal.cancel",
          defaultMessage: "Cancel"
        }) })
      }
    )
  ] });
};
FromComputerForm.defaultProps = {
  next: null
};
FromComputerForm.propTypes = {
  goTo: PropTypes__default.default.func.isRequired,
  next: PropTypes__default.default.string,
  onClose: PropTypes__default.default.func.isRequired,
  setLocalImage: PropTypes__default.default.func.isRequired
};
const urlToFile = async (url) => {
  try {
    const { get } = helperPlugin.getFetchClient();
    const res = await get(url, { responseType: "blob", timeout: 8e3 });
    const loadedFile = new File([res.data], res.config.url, {
      type: res.headers["content-type"]
    });
    return loadedFile;
  } catch (err) {
    err.displayMessage = {
      id: "Settings.application.customization.modal.upload.error-network",
      defaultMessage: "Network error"
    };
    throw err;
  }
};
const FromUrlForm = ({ goTo, next, onClose, setLocalImage }) => {
  const { formatMessage } = reactIntl.useIntl();
  const [logoUrl, setLogoUrl] = React.useState("");
  const [error, setError] = React.useState(null);
  const handleChange = (e) => {
    setLogoUrl(e.target.value);
  };
  const handleSubmit = async () => {
    try {
      const file = await urlToFile(logoUrl);
      const asset = await parseFileMetadatas(file);
      setLocalImage(asset);
      goTo(next);
    } catch (err) {
      if (err.displayMessage) {
        setError(formatMessage(err.displayMessage, { size: SIZE, dimension: DIMENSION }));
      } else {
        throw err;
      }
    }
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(
    "form",
    {
      onSubmit: (e) => {
        e.preventDefault();
        handleSubmit();
      },
      children: [
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsxRuntime.jsx(
          designSystem.TextInput,
          {
            label: formatMessage({
              id: "Settings.application.customization.modal.upload.from-url.input-label",
              defaultMessage: "URL"
            }),
            error,
            onChange: handleChange,
            value: logoUrl,
            name: "logo-url"
          }
        ) }),
        /* @__PURE__ */ jsxRuntime.jsx(
          designSystem.ModalFooter,
          {
            startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }),
            endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", children: formatMessage({
              id: "Settings.application.customization.modal.upload.next",
              defaultMessage: "Next"
            }) })
          }
        )
      ]
    }
  );
};
FromUrlForm.defaultProps = {
  next: null
};
FromUrlForm.propTypes = {
  goTo: PropTypes__default.default.func.isRequired,
  next: PropTypes__default.default.string,
  onClose: PropTypes__default.default.func.isRequired,
  setLocalImage: PropTypes__default.default.func.isRequired
};
const AddLogoDialog = ({ setLocalImage, goTo, next, onClose }) => {
  const { formatMessage } = reactIntl.useIntl();
  return /* @__PURE__ */ jsxRuntime.jsxs(
    designSystem.TabGroup,
    {
      label: formatMessage({
        id: "Settings.application.customization.modal.tab.label",
        defaultMessage: "How do you want to upload your assets?"
      }),
      variant: "simple",
      children: [
        /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingLeft: 8, paddingRight: 8, children: [
          /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tabs, { children: [
            /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
              id: "Settings.application.customization.modal.upload.from-computer",
              defaultMessage: "From computer"
            }) }),
            /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tab, { children: formatMessage({
              id: "Settings.application.customization.modal.upload.from-url",
              defaultMessage: "From url"
            }) })
          ] }),
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.Divider, {})
        ] }),
        /* @__PURE__ */ jsxRuntime.jsxs(designSystem.TabPanels, { children: [
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(
            FromComputerForm,
            {
              onClose,
              setLocalImage,
              goTo,
              next
            }
          ) }),
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.TabPanel, { children: /* @__PURE__ */ jsxRuntime.jsx(FromUrlForm, { onClose, setLocalImage, goTo, next }) })
        ] })
      ]
    }
  );
};
AddLogoDialog.defaultProps = {
  next: null
};
AddLogoDialog.propTypes = {
  goTo: PropTypes__default.default.func.isRequired,
  next: PropTypes__default.default.string,
  onClose: PropTypes__default.default.func.isRequired,
  setLocalImage: PropTypes__default.default.func.isRequired
};
const ImageCardAsset = ({ asset }) => {
  const { formatMessage } = reactIntl.useIntl();
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Card, { children: [
    /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardAsset, { size: "S", src: asset.url }) }),
    /* @__PURE__ */ jsxRuntime.jsxs(designSystem.CardBody, { children: [
      /* @__PURE__ */ jsxRuntime.jsxs(designSystem.CardContent, { children: [
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardTitle, { children: asset.name }),
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardSubtitle, { children: `${asset.ext.toUpperCase()} - ${asset.width}✕${asset.height}` })
      ] }),
      /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardBadge, { children: formatMessage({
        id: "Settings.application.customization.modal.pending.card-badge",
        defaultMessage: "image"
      }) })
    ] })
  ] });
};
ImageCardAsset.propTypes = {
  asset: PropTypes__default.default.shape({
    name: PropTypes__default.default.string,
    url: PropTypes__default.default.string,
    width: PropTypes__default.default.number,
    height: PropTypes__default.default.number,
    ext: PropTypes__default.default.string
  }).isRequired
};
const PendingLogoDialog = ({ onClose, asset, prev, next, goTo, setLocalImage, onChangeLogo }) => {
  const { formatMessage } = reactIntl.useIntl();
  const handleGoBack = () => {
    setLocalImage(void 0);
    goTo(prev);
  };
  const handleUpload = () => {
    onChangeLogo(asset);
    goTo(next);
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: [
      /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", paddingBottom: 6, children: [
        /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-start", children: [
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
            id: "Settings.application.customization.modal.pending.title",
            defaultMessage: "Logo ready to upload"
          }) }),
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: formatMessage({
            id: "Settings.application.customization.modal.pending.subtitle",
            defaultMessage: "Manage the chosen logo before uploading it"
          }) })
        ] }),
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleGoBack, variant: "secondary", children: formatMessage({
          id: "Settings.application.customization.modal.pending.choose-another",
          defaultMessage: "Choose another logo"
        }) })
      ] }),
      /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { maxWidth: helperPlugin.pxToRem(180), children: asset.url ? /* @__PURE__ */ jsxRuntime.jsx(ImageCardAsset, { asset }) : null })
    ] }),
    /* @__PURE__ */ jsxRuntime.jsx(
      designSystem.ModalFooter,
      {
        startActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
          id: "Settings.application.customization.modal.cancel",
          defaultMessage: "Cancel"
        }) }),
        endActions: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: handleUpload, children: formatMessage({
          id: "Settings.application.customization.modal.pending.upload",
          defaultMessage: "Upload logo"
        }) })
      }
    )
  ] });
};
PendingLogoDialog.defaultProps = {
  next: null,
  prev: null
};
PendingLogoDialog.propTypes = {
  goTo: PropTypes__default.default.func.isRequired,
  asset: PropTypes__default.default.shape({
    name: PropTypes__default.default.string,
    url: PropTypes__default.default.string,
    width: PropTypes__default.default.number,
    height: PropTypes__default.default.number,
    ext: PropTypes__default.default.string
  }).isRequired,
  next: PropTypes__default.default.string,
  onClose: PropTypes__default.default.func.isRequired,
  onChangeLogo: PropTypes__default.default.func.isRequired,
  prev: PropTypes__default.default.string,
  setLocalImage: PropTypes__default.default.func.isRequired
};
const stepper = {
  upload: {
    Component: AddLogoDialog,
    modalTitle: {
      id: "Settings.application.customization.modal.upload",
      defaultMessage: "Upload logo"
    },
    next: "pending",
    prev: null
  },
  pending: {
    Component: PendingLogoDialog,
    modalTitle: {
      id: "Settings.application.customization.modal.pending",
      defaultMessage: "Pending logo"
    },
    next: null,
    prev: "upload"
  }
};
const LogoInput = ({
  canUpdate,
  customLogo,
  defaultLogo,
  hint,
  label,
  onChangeLogo,
  onResetLogo
}) => {
  const [{ currentStep }, dispatch] = React.useReducer(reducer$1, initialState$1);
  const { Component, next, prev, modalTitle } = stepper[currentStep] || {};
  const { formatMessage } = reactIntl.useIntl();
  const goTo = (to) => {
    dispatch({
      type: "GO_TO",
      to
    });
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
    /* @__PURE__ */ jsxRuntime.jsx(
      designSystem.CarouselInput,
      {
        label,
        selectedSlide: 0,
        hint,
        previousLabel: "",
        nextLabel: "",
        onNext: () => {
        },
        onPrevious: () => {
        },
        secondaryLabel: customLogo?.name || "logo.png",
        actions: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.CarouselActions, { children: [
          /* @__PURE__ */ jsxRuntime.jsx(
            designSystem.IconButton,
            {
              disabled: !canUpdate,
              onClick: () => goTo(customLogo ? "pending" : "upload"),
              label: formatMessage({
                id: "Settings.application.customization.carousel.change-action",
                defaultMessage: "Change logo"
              }),
              icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Plus, {})
            }
          ),
          customLogo && /* @__PURE__ */ jsxRuntime.jsx(
            designSystem.IconButton,
            {
              disabled: !canUpdate,
              onClick: onResetLogo,
              label: formatMessage({
                id: "Settings.application.customization.carousel.reset-action",
                defaultMessage: "Reset logo"
              }),
              icon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Refresh, {})
            }
          )
        ] }),
        children: /* @__PURE__ */ jsxRuntime.jsx(
          designSystem.CarouselSlide,
          {
            label: formatMessage({
              id: "Settings.application.customization.carousel-slide.label",
              defaultMessage: "Logo slide"
            }),
            children: /* @__PURE__ */ jsxRuntime.jsx(
              designSystem.Box,
              {
                maxHeight: "40%",
                maxWidth: "40%",
                as: "img",
                src: customLogo?.url || defaultLogo,
                alt: formatMessage({
                  id: "Settings.application.customization.carousel.title",
                  defaultMessage: "Logo"
                })
              }
            )
          }
        )
      }
    ),
    /* @__PURE__ */ jsxRuntime.jsx(
      LogoModalStepper,
      {
        Component,
        currentStep,
        onChangeLogo,
        customLogo,
        goTo,
        next,
        prev,
        modalTitle
      }
    )
  ] });
};
LogoInput.defaultProps = {
  canUpdate: false,
  customLogo: null,
  hint: null
};
LogoInput.propTypes = {
  canUpdate: PropTypes__default.default.bool,
  customLogo: PropTypes__default.default.shape({
    url: PropTypes__default.default.string,
    name: PropTypes__default.default.string
  }),
  label: PropTypes__default.default.string.isRequired,
  hint: PropTypes__default.default.string,
  defaultLogo: PropTypes__default.default.string.isRequired,
  onChangeLogo: PropTypes__default.default.func.isRequired,
  onResetLogo: PropTypes__default.default.func.isRequired
};
const init = (initialState2, projectSettingsStored) => {
  const copyInitialState = merge__default.default(initialState2, {
    menuLogo: {
      display: projectSettingsStored.menuLogo
    },
    authLogo: {
      display: projectSettingsStored.authLogo
    }
  });
  return copyInitialState;
};
const initialState = {
  menuLogo: {
    display: null,
    submit: {
      rawFile: null,
      isReset: false
    }
  },
  authLogo: {
    display: null,
    submit: {
      rawFile: null,
      isReset: false
    }
  }
};
const reducer = (state = initialState, action) => produce__default.default(state, (draftState) => {
  switch (action.type) {
    case "SET_CUSTOM_MENU_LOGO": {
      draftState.menuLogo.display = action.value;
      draftState.menuLogo.submit.rawFile = action.value.rawFile;
      break;
    }
    case "SET_CUSTOM_AUTH_LOGO": {
      draftState.authLogo.display = action.value;
      draftState.authLogo.submit.rawFile = action.value.rawFile;
      break;
    }
    case "RESET_CUSTOM_MENU_LOGO": {
      draftState.menuLogo.display = null;
      draftState.menuLogo.submit = {
        rawFile: null,
        isReset: true
      };
      break;
    }
    case "RESET_CUSTOM_AUTH_LOGO": {
      draftState.authLogo.display = null;
      draftState.authLogo.submit = {
        rawFile: null,
        isReset: true
      };
      break;
    }
    default: {
      return draftState;
    }
  }
});
const CustomizationInfos = React.forwardRef(({ canUpdate, projectSettingsStored }, ref) => {
  const { formatMessage } = reactIntl.useIntl();
  const { trackUsage } = helperPlugin.useTracking();
  const {
    logos: { menu, auth }
  } = index.useConfiguration();
  const [{ menuLogo, authLogo }, dispatch] = React.useReducer(
    reducer,
    initialState,
    () => init(initialState, projectSettingsStored)
  );
  const handleChangeMenuLogo = (asset) => {
    dispatch({
      type: "SET_CUSTOM_MENU_LOGO",
      value: asset
    });
  };
  const handleResetMenuLogo = () => {
    trackUsage("didClickResetLogo", {
      logo: "menu"
    });
    dispatch({
      type: "RESET_CUSTOM_MENU_LOGO"
    });
  };
  const handleChangeAuthLogo = (asset) => {
    dispatch({
      type: "SET_CUSTOM_AUTH_LOGO",
      value: asset
    });
  };
  const handleResetAuthLogo = () => {
    trackUsage("didClickResetLogo", {
      logo: "auth"
    });
    dispatch({
      type: "RESET_CUSTOM_AUTH_LOGO"
    });
  };
  React.useImperativeHandle(ref, () => ({
    getValues: () => ({ menuLogo: menuLogo.submit, authLogo: authLogo.submit })
  }));
  return /* @__PURE__ */ jsxRuntime.jsxs(
    designSystem.Box,
    {
      hasRadius: true,
      background: "neutral0",
      shadow: "tableShadow",
      paddingTop: 6,
      paddingBottom: 6,
      paddingRight: 7,
      paddingLeft: 7,
      children: [
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", as: "h3", children: formatMessage({
          id: "Settings.application.customization",
          defaultMessage: "Customization"
        }) }),
        /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: formatMessage(
          {
            id: "Settings.application.customization.size-details",
            defaultMessage: "Max dimension: {dimension}×{dimension}, Max file size: {size}KB"
          },
          { dimension: DIMENSION, size: SIZE }
        ) }),
        /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid, { paddingTop: 4, gap: 4, children: [
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
            LogoInput,
            {
              canUpdate,
              customLogo: menuLogo.display,
              defaultLogo: menu.default,
              hint: formatMessage({
                id: "Settings.application.customization.menu-logo.carousel-hint",
                defaultMessage: "Replace the logo in the main navigation"
              }),
              label: formatMessage({
                id: "Settings.application.customization.carousel.menu-logo.title",
                defaultMessage: "Menu logo"
              }),
              onChangeLogo: handleChangeMenuLogo,
              onResetLogo: handleResetMenuLogo
            }
          ) }),
          /* @__PURE__ */ jsxRuntime.jsx(designSystem.GridItem, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(
            LogoInput,
            {
              canUpdate,
              customLogo: authLogo.display,
              defaultLogo: auth.default,
              hint: formatMessage({
                id: "Settings.application.customization.auth-logo.carousel-hint",
                defaultMessage: "Replace the logo in the authentication pages"
              }),
              label: formatMessage({
                id: "Settings.application.customization.carousel.auth-logo.title",
                defaultMessage: "Auth logo"
              }),
              onChangeLogo: handleChangeAuthLogo,
              onResetLogo: handleResetAuthLogo
            }
          ) })
        ] })
      ]
    }
  );
});
CustomizationInfos.defaultProps = {
  canUpdate: false,
  projectSettingsStored: null
};
CustomizationInfos.propTypes = {
  canUpdate: PropTypes__default.default.bool,
  projectSettingsStored: PropTypes__default.default.shape({
    menuLogo: PropTypes__default.default.shape({
      url: PropTypes__default.default.string,
      name: PropTypes__default.default.string
    })
  })
};
const getFormData = (data) => {
  const formData = new FormData();
  Object.entries(data).forEach(([key, value]) => {
    if (value && value.rawFile instanceof File) {
      formData.append(key, value.rawFile);
    }
    if (value && value.isReset) {
      formData.append(key, null);
    }
  });
  return formData;
};
const AdminSeatInfoCE = () => null;
const ApplicationInfosPage = () => {
  const inputsRef = React__namespace.useRef();
  const toggleNotification = helperPlugin.useNotification();
  const { trackUsage } = helperPlugin.useTracking();
  const { formatMessage } = reactIntl.useIntl();
  const { get, post } = helperPlugin.useFetchClient();
  const { updateProjectSettings } = index.useConfiguration();
  const permissions = reactRedux.useSelector(AuthenticatedApp.selectAdminPermissions);
  const { formatAPIError } = helperPlugin.useAPIErrorHandler();
  helperPlugin.useAppInfo();
  const AdminSeatInfo = index.useEnterprise(
    AdminSeatInfoCE,
    async () => (await Promise.resolve().then(() => require("./index-68490081.js"))).AdminSeatInfoEE
  );
  const {
    allowedActions: { canRead, canUpdate }
  } = helperPlugin.useRBAC(permissions.settings["project-settings"]);
  helperPlugin.useFocusWhenNavigate();
  const { data, isLoading } = reactQuery.useQuery(
    ["project-settings"],
    async () => {
      const { data: data2 } = await get("/admin/project-settings");
      return data2;
    },
    {
      cacheTime: 0,
      enabled: canRead,
      select(data2) {
        return {
          ...data2,
          authLogo: data2.authLogo ? {
            ...data2.authLogo,
            url: helperPlugin.prefixFileUrlWithBackendUrl(data2.authLogo.url)
          } : data2.authLogo,
          menuLogo: data2.menuLogo ? {
            ...data2.menuLogo,
            url: helperPlugin.prefixFileUrlWithBackendUrl(data2.menuLogo.url)
          } : data2.menuLogo
        };
      }
    }
  );
  const submitMutation = reactQuery.useMutation(
    (body) => post("/admin/project-settings", body, {
      headers: {
        "Content-Type": "multipart/form-data"
      }
    }),
    {
      onError(error) {
        toggleNotification({
          type: "warning",
          message: formatAPIError(error)
        });
      },
      async onSuccess(data2) {
        const { menuLogo, authLogo } = data2;
        updateProjectSettings({ menuLogo: menuLogo?.url, authLogo: authLogo?.url });
        if (menuLogo?.rawFile) {
          trackUsage("didChangeLogo", {
            logo: "menu"
          });
        }
        if (authLogo?.rawFile) {
          trackUsage("didChangeLogo", {
            logo: "auth"
          });
        }
        toggleNotification({
          type: "success",
          message: formatMessage({ id: "app", defaultMessage: "Saved" })
        });
      }
    }
  );
  const handleSubmit = (e) => {
    e.preventDefault();
    submitMutation.mutate(getFormData(inputsRef.current.getValues()));
  };
  if (!AdminSeatInfo) {
    return null;
  }
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Layout, { children: [
    /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.SettingsPageTitle, { name: "Application" }),
    /* @__PURE__ */ jsxRuntime.jsx(designSystem.Main, { children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: formatMessage({
      id: "Settings.application.isLoading",
      defaultMessage: "Loading"
    }) }) : /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
      /* @__PURE__ */ jsxRuntime.jsx(
        designSystem.HeaderLayout,
        {
          title: formatMessage({
            id: "Settings.application.title",
            defaultMessage: "Overview"
          }),
          subtitle: formatMessage({
            id: "Settings.application.description",
            defaultMessage: "Administration panel’s global information"
          }),
          primaryAction: canUpdate && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", startIcon: /* @__PURE__ */ jsxRuntime.jsx(Icons.Check, {}), children: formatMessage({ id: "global.save", defaultMessage: "Save" }) })
        }
      ),
      /* @__PURE__ */ jsxRuntime.jsx(designSystem.ContentLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 6, children: canRead && data && /* @__PURE__ */ jsxRuntime.jsx(
        CustomizationInfos,
        {
          canUpdate,
          ref: inputsRef,
          projectSettingsStored: data
        }
      ) }) })
    ] }) })
  ] });
};
function makeUniqueRoutes(routes) {
  return routes.filter(
    (route, index2, refArray) => refArray.findIndex((obj) => obj.key === route.key) === index2
  );
}
function SettingsPage() {
  const { settingId } = reactRouterDom.useParams();
  const { settings } = helperPlugin.useStrapiApp();
  const { formatMessage } = reactIntl.useIntl();
  const { isLoading, menu } = useSettingsMenu();
  const routes = index.useEnterprise(
    ROUTES_CE,
    async () => (await Promise.resolve().then(() => require("./constants-edb5f8ce.js"))).ROUTES_EE,
    {
      combine(ceRoutes, eeRoutes) {
        return [...ceRoutes, ...eeRoutes];
      },
      defaultValue: []
    }
  );
  const adminRoutes = React__namespace.useMemo(() => {
    return makeUniqueRoutes(
      routes.map(({ to, Component, exact }) => index.createRoute(Component, to, exact))
    );
  }, [routes]);
  const pluginsRoutes = Object.values(settings).flatMap((section) => {
    const { links } = section;
    return links.map((link) => index.createRoute(link.Component, link.to, link.exact || false));
  });
  if (isLoading) {
    return /* @__PURE__ */ jsxRuntime.jsx(helperPlugin.LoadingIndicatorPage, {});
  }
  if (!settingId) {
    return /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Redirect, { to: "/settings/application-infos" });
  }
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Layout, { sideNav: /* @__PURE__ */ jsxRuntime.jsx(SettingsNav, { menu }), children: [
    /* @__PURE__ */ jsxRuntime.jsx(
      reactHelmet.Helmet,
      {
        title: formatMessage({
          id: "global.settings",
          defaultMessage: "Settings"
        })
      }
    ),
    /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Switch, { children: [
      /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "/settings/application-infos", component: ApplicationInfosPage, exact: true }),
      adminRoutes,
      pluginsRoutes
    ] })
  ] });
}
exports.SettingsPage = SettingsPage;
//# sourceMappingURL=index-2af177e7.js.map
