import { jsxs, jsx, Fragment } from "react/jsx-runtime";
import * as React from "react";
import { useReducer, useState, useRef, forwardRef, useImperativeHandle } from "react";
import { Icon, ModalLayout, ModalHeader, Typography, FieldInput, Box, Field, Flex, Button, FieldError, ModalFooter, TextInput, TabGroup, Tabs, Tab, Divider, TabPanels, TabPanel, Card, CardHeader, CardAsset, CardBody, CardContent, CardTitle, CardSubtitle, CardBadge, CarouselInput, CarouselActions, IconButton, CarouselSlide, Grid, GridItem, Layout, Main, Loader, HeaderLayout, ContentLayout } from "@strapi/design-system";
import { useRBACProvider, useAppInfo, useStrapiApp, hasPermissions, useTracking, getFetchClient, pxToRem, useNotification, useFetchClient, useAPIErrorHandler, useRBAC, useFocusWhenNavigate, prefixFileUrlWithBackendUrl, SettingsPageTitle, LoadingIndicatorPage } from "@strapi/helper-plugin";
import { Helmet } from "react-helmet";
import { useIntl } from "react-intl";
import { useLocation, NavLink, useParams, Redirect, Switch, Route } from "react-router-dom";
import { P as SETTINGS_LINKS_CE, p as useEnterprise, u as useConfiguration, d as createRoute } from "./index-466b22f5.mjs";
import sortBy from "lodash/sortBy";
import { useSelector } from "react-redux";
import { s as selectAdminPermissions } from "./AuthenticatedApp-4e25ce97.mjs";
import { SubNav, SubNavHeader, SubNavSections, SubNavSection, SubNavLink } from "@strapi/design-system/v2";
import { Lock, PicturePlus, Plus, Refresh, Check } from "@strapi/icons";
import PropTypes from "prop-types";
import styled from "styled-components";
import { useQuery, useMutation } from "react-query";
import produce from "immer";
import merge from "lodash/merge";
import "react-dom/client";
import "invariant";
import "lodash/isFunction";
import "lodash/pick";
import "@radix-ui/react-context";
import "formik";
import "lodash/camelCase";
import "yup";
import "lodash/defaultsDeep";
import "lodash/omit";
import "qs";
import "lodash/get";
import "lodash/set";
import "@reduxjs/toolkit";
import "semver/functions/lt";
import "semver/functions/valid";
import "react-dnd";
import "react-dnd-html5-backend";
import "lodash/cloneDeep";
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.useState({
    isLoading: true,
    menu: []
  });
  const { allPermissions: userPermissions } = useRBACProvider();
  const { shouldUpdateStrapi } = useAppInfo();
  const { settings } = useStrapiApp();
  const permissions = useSelector(selectAdminPermissions);
  const ceLinks = React.useMemo(() => SETTINGS_LINKS_CE(), []);
  const { admin: adminLinks, global: globalLinks } = useEnterprise(
    ceLinks,
    async () => (await import("./constants-6ecddc43.mjs")).SETTINGS_LINKS_EE(),
    {
      combine(ceLinks2, eeLinks) {
        return {
          admin: [...eeLinks.admin, ...ceLinks2.admin],
          global: [...ceLinks2.global, ...eeLinks.global]
        };
      },
      defaultValue: {
        admin: [],
        global: []
      }
    }
  );
  const addPermissions = React.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.useEffect(() => {
    const getData = async () => {
      const buildMenuPermissions = (sections2) => Promise.all(
        sections2.reduce((acc, section, sectionIndex) => {
          const linksWithPermissions = section.links.map(async (link, linkIndex) => ({
            hasPermission: await 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([...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(Icon)`
  right: 15px;
  position: absolute;
`;
const SettingsNav = ({ menu }) => {
  const { formatMessage } = useIntl();
  const { trackUsage } = useTracking();
  const { pathname } = 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__ */ jsxs(SubNav, { ariaLabel: label, children: [
    /* @__PURE__ */ jsx(SubNavHeader, { label }),
    /* @__PURE__ */ jsx(SubNavSections, { children: sections.map((section) => /* @__PURE__ */ jsx(SubNavSection, { label: formatMessage(section.intlLabel), children: section.links.map((link) => {
      return /* @__PURE__ */ jsxs(
        SubNavLink,
        {
          as: NavLink,
          withBullet: link.hasNotification,
          to: link.to,
          onClick: () => handleClickOnLink(link.to),
          children: [
            formatMessage(link.intlLabel),
            link?.lockIcon && /* @__PURE__ */ jsx(CustomIcon, { width: `${15 / 16}rem`, height: `${15 / 16}rem`, as: Lock })
          ]
        },
        link.id
      );
    }) }, section.id)) })
  ] });
};
SettingsNav.propTypes = {
  menu: PropTypes.array.isRequired
};
const ROUTES_CE = [
  {
    async Component() {
      const component = await import("./index-e50339c6.mjs");
      return component;
    },
    to: "/settings/roles",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-9d8b161e.mjs");
      return component;
    },
    to: "/settings/roles/duplicate/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-9d8b161e.mjs");
      return component;
    },
    to: "/settings/roles/new",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-6fab74f4.mjs");
      return component;
    },
    to: "/settings/roles/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-db4a226c.mjs").then((n) => n.i);
      return component;
    },
    to: "/settings/users",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-96576e39.mjs");
      return component;
    },
    to: "/settings/users/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-c448992c.mjs");
      return component;
    },
    to: "/settings/webhooks/create",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-d33c8b8e.mjs");
      return component;
    },
    to: "/settings/webhooks/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-1d466cd5.mjs");
      return component;
    },
    to: "/settings/webhooks",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-2fa4ed6e.mjs");
      return component;
    },
    to: "/settings/api-tokens",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-e71337a1.mjs");
      return component;
    },
    to: "/settings/api-tokens/create",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-58183476.mjs");
      return component;
    },
    to: "/settings/api-tokens/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-381ad96e.mjs");
      return component;
    },
    to: "/settings/transfer-tokens/create",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-f8ce2619.mjs");
      return component;
    },
    to: "/settings/transfer-tokens",
    exact: true
  },
  {
    async Component() {
      const component = await import("./index-04a8e5b7.mjs");
      return component;
    },
    to: "/settings/transfer-tokens/:id",
    exact: true
  },
  {
    async Component() {
      const component = await import("./SalesPage-56bf9463.mjs");
      return component;
    },
    to: "/settings/purchase-audit-logs",
    exact: true
  },
  {
    async Component() {
      const component = await import("./SalesPage-fceedf48.mjs");
      return component;
    },
    to: "/settings/purchase-review-workflows",
    exact: true
  },
  {
    async Component() {
      const component = await import("./SalesPage-f9597ae7.mjs");
      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(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] = useReducer(reducer$2, initialState$2);
  const { formatMessage } = useIntl();
  const setLocalImage = (asset) => {
    dispatch({
      type: "SET_LOCAL_IMAGE",
      value: asset
    });
  };
  const handleCloseModal = () => {
    goTo(null);
  };
  if (!currentStep) {
    return null;
  }
  return /* @__PURE__ */ jsxs(ModalLayout, { labelledBy: "modal", onClose: handleCloseModal, children: [
    /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", as: "h2", id: "modal", children: formatMessage(modalTitle) }) }),
    /* @__PURE__ */ 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.elementType,
  currentStep: PropTypes.string,
  customLogo: PropTypes.shape({
    name: PropTypes.string,
    url: PropTypes.string,
    width: PropTypes.number,
    height: PropTypes.number,
    ext: PropTypes.string
  }),
  goTo: PropTypes.func.isRequired,
  modalTitle: PropTypes.shape({
    id: PropTypes.string,
    defaultMessage: PropTypes.string
  }),
  next: PropTypes.string,
  onChangeLogo: PropTypes.func.isRequired,
  prev: PropTypes.string
};
const initialState$1 = {
  currentStep: void 0
};
const reducer$1 = (state = initialState$1, action) => produce(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(FieldInput)`
  opacity: 0;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
`;
const FromComputerForm = ({ setLocalImage, goTo, next, onClose }) => {
  const { formatMessage } = useIntl();
  const [dragOver, setDragOver] = useState(false);
  const [fileError, setFileError] = useState(void 0);
  const inputRef = 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__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx("form", { children: /* @__PURE__ */ jsx(Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsx(Field, { name: "logo-upload", error: fileError, children: /* @__PURE__ */ jsx("label", { htmlFor: "logo-upload", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 2, children: [
      /* @__PURE__ */ jsxs(
        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__ */ jsx(
              Icon,
              {
                color: "primary600",
                width: `${60 / 16}rem`,
                height: `${60 / 16}rem`,
                as: PicturePlus,
                "aria-hidden": true
              }
            ),
            /* @__PURE__ */ jsx(Box, { paddingTop: 3, paddingBottom: 5, children: /* @__PURE__ */ jsx(Typography, { variant: "delta", as: "span", children: formatMessage({
              id: "Settings.application.customization.modal.upload.drag-drop",
              defaultMessage: "Drag and Drop here or"
            }) }) }),
            /* @__PURE__ */ 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__ */ jsx(Button, { type: "button", onClick: handleClick, children: formatMessage({
              id: "Settings.application.customization.modal.upload.cta.browse",
              defaultMessage: "Browse files"
            }) }),
            /* @__PURE__ */ jsx(Box, { paddingTop: 6, children: /* @__PURE__ */ jsx(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__ */ jsx(FieldError, {})
    ] }) }) }) }) }),
    /* @__PURE__ */ jsx(
      ModalFooter,
      {
        startActions: /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
          id: "Settings.application.customization.modal.cancel",
          defaultMessage: "Cancel"
        }) })
      }
    )
  ] });
};
FromComputerForm.defaultProps = {
  next: null
};
FromComputerForm.propTypes = {
  goTo: PropTypes.func.isRequired,
  next: PropTypes.string,
  onClose: PropTypes.func.isRequired,
  setLocalImage: PropTypes.func.isRequired
};
const urlToFile = async (url) => {
  try {
    const { get } = 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 } = useIntl();
  const [logoUrl, setLogoUrl] = useState("");
  const [error, setError] = 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__ */ jsxs(
    "form",
    {
      onSubmit: (e) => {
        e.preventDefault();
        handleSubmit();
      },
      children: [
        /* @__PURE__ */ jsx(Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: /* @__PURE__ */ jsx(
          TextInput,
          {
            label: formatMessage({
              id: "Settings.application.customization.modal.upload.from-url.input-label",
              defaultMessage: "URL"
            }),
            error,
            onChange: handleChange,
            value: logoUrl,
            name: "logo-url"
          }
        ) }),
        /* @__PURE__ */ jsx(
          ModalFooter,
          {
            startActions: /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({ id: "app.components.Button.cancel", defaultMessage: "Cancel" }) }),
            endActions: /* @__PURE__ */ jsx(Button, { type: "submit", children: formatMessage({
              id: "Settings.application.customization.modal.upload.next",
              defaultMessage: "Next"
            }) })
          }
        )
      ]
    }
  );
};
FromUrlForm.defaultProps = {
  next: null
};
FromUrlForm.propTypes = {
  goTo: PropTypes.func.isRequired,
  next: PropTypes.string,
  onClose: PropTypes.func.isRequired,
  setLocalImage: PropTypes.func.isRequired
};
const AddLogoDialog = ({ setLocalImage, goTo, next, onClose }) => {
  const { formatMessage } = useIntl();
  return /* @__PURE__ */ jsxs(
    TabGroup,
    {
      label: formatMessage({
        id: "Settings.application.customization.modal.tab.label",
        defaultMessage: "How do you want to upload your assets?"
      }),
      variant: "simple",
      children: [
        /* @__PURE__ */ jsxs(Box, { paddingLeft: 8, paddingRight: 8, children: [
          /* @__PURE__ */ jsxs(Tabs, { children: [
            /* @__PURE__ */ jsx(Tab, { children: formatMessage({
              id: "Settings.application.customization.modal.upload.from-computer",
              defaultMessage: "From computer"
            }) }),
            /* @__PURE__ */ jsx(Tab, { children: formatMessage({
              id: "Settings.application.customization.modal.upload.from-url",
              defaultMessage: "From url"
            }) })
          ] }),
          /* @__PURE__ */ jsx(Divider, {})
        ] }),
        /* @__PURE__ */ jsxs(TabPanels, { children: [
          /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(
            FromComputerForm,
            {
              onClose,
              setLocalImage,
              goTo,
              next
            }
          ) }),
          /* @__PURE__ */ jsx(TabPanel, { children: /* @__PURE__ */ jsx(FromUrlForm, { onClose, setLocalImage, goTo, next }) })
        ] })
      ]
    }
  );
};
AddLogoDialog.defaultProps = {
  next: null
};
AddLogoDialog.propTypes = {
  goTo: PropTypes.func.isRequired,
  next: PropTypes.string,
  onClose: PropTypes.func.isRequired,
  setLocalImage: PropTypes.func.isRequired
};
const ImageCardAsset = ({ asset }) => {
  const { formatMessage } = useIntl();
  return /* @__PURE__ */ jsxs(Card, { children: [
    /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardAsset, { size: "S", src: asset.url }) }),
    /* @__PURE__ */ jsxs(CardBody, { children: [
      /* @__PURE__ */ jsxs(CardContent, { children: [
        /* @__PURE__ */ jsx(CardTitle, { children: asset.name }),
        /* @__PURE__ */ jsx(CardSubtitle, { children: `${asset.ext.toUpperCase()} - ${asset.width}✕${asset.height}` })
      ] }),
      /* @__PURE__ */ jsx(CardBadge, { children: formatMessage({
        id: "Settings.application.customization.modal.pending.card-badge",
        defaultMessage: "image"
      }) })
    ] })
  ] });
};
ImageCardAsset.propTypes = {
  asset: PropTypes.shape({
    name: PropTypes.string,
    url: PropTypes.string,
    width: PropTypes.number,
    height: PropTypes.number,
    ext: PropTypes.string
  }).isRequired
};
const PendingLogoDialog = ({ onClose, asset, prev, next, goTo, setLocalImage, onChangeLogo }) => {
  const { formatMessage } = useIntl();
  const handleGoBack = () => {
    setLocalImage(void 0);
    goTo(prev);
  };
  const handleUpload = () => {
    onChangeLogo(asset);
    goTo(next);
  };
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsxs(Box, { paddingLeft: 8, paddingRight: 8, paddingTop: 6, paddingBottom: 6, children: [
      /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", paddingBottom: 6, children: [
        /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-start", children: [
          /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: formatMessage({
            id: "Settings.application.customization.modal.pending.title",
            defaultMessage: "Logo ready to upload"
          }) }),
          /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: formatMessage({
            id: "Settings.application.customization.modal.pending.subtitle",
            defaultMessage: "Manage the chosen logo before uploading it"
          }) })
        ] }),
        /* @__PURE__ */ jsx(Button, { onClick: handleGoBack, variant: "secondary", children: formatMessage({
          id: "Settings.application.customization.modal.pending.choose-another",
          defaultMessage: "Choose another logo"
        }) })
      ] }),
      /* @__PURE__ */ jsx(Box, { maxWidth: pxToRem(180), children: asset.url ? /* @__PURE__ */ jsx(ImageCardAsset, { asset }) : null })
    ] }),
    /* @__PURE__ */ jsx(
      ModalFooter,
      {
        startActions: /* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "tertiary", children: formatMessage({
          id: "Settings.application.customization.modal.cancel",
          defaultMessage: "Cancel"
        }) }),
        endActions: /* @__PURE__ */ jsx(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.func.isRequired,
  asset: PropTypes.shape({
    name: PropTypes.string,
    url: PropTypes.string,
    width: PropTypes.number,
    height: PropTypes.number,
    ext: PropTypes.string
  }).isRequired,
  next: PropTypes.string,
  onClose: PropTypes.func.isRequired,
  onChangeLogo: PropTypes.func.isRequired,
  prev: PropTypes.string,
  setLocalImage: PropTypes.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] = useReducer(reducer$1, initialState$1);
  const { Component, next, prev, modalTitle } = stepper[currentStep] || {};
  const { formatMessage } = useIntl();
  const goTo = (to) => {
    dispatch({
      type: "GO_TO",
      to
    });
  };
  return /* @__PURE__ */ jsxs(Fragment, { children: [
    /* @__PURE__ */ jsx(
      CarouselInput,
      {
        label,
        selectedSlide: 0,
        hint,
        previousLabel: "",
        nextLabel: "",
        onNext: () => {
        },
        onPrevious: () => {
        },
        secondaryLabel: customLogo?.name || "logo.png",
        actions: /* @__PURE__ */ jsxs(CarouselActions, { children: [
          /* @__PURE__ */ jsx(
            IconButton,
            {
              disabled: !canUpdate,
              onClick: () => goTo(customLogo ? "pending" : "upload"),
              label: formatMessage({
                id: "Settings.application.customization.carousel.change-action",
                defaultMessage: "Change logo"
              }),
              icon: /* @__PURE__ */ jsx(Plus, {})
            }
          ),
          customLogo && /* @__PURE__ */ jsx(
            IconButton,
            {
              disabled: !canUpdate,
              onClick: onResetLogo,
              label: formatMessage({
                id: "Settings.application.customization.carousel.reset-action",
                defaultMessage: "Reset logo"
              }),
              icon: /* @__PURE__ */ jsx(Refresh, {})
            }
          )
        ] }),
        children: /* @__PURE__ */ jsx(
          CarouselSlide,
          {
            label: formatMessage({
              id: "Settings.application.customization.carousel-slide.label",
              defaultMessage: "Logo slide"
            }),
            children: /* @__PURE__ */ jsx(
              Box,
              {
                maxHeight: "40%",
                maxWidth: "40%",
                as: "img",
                src: customLogo?.url || defaultLogo,
                alt: formatMessage({
                  id: "Settings.application.customization.carousel.title",
                  defaultMessage: "Logo"
                })
              }
            )
          }
        )
      }
    ),
    /* @__PURE__ */ jsx(
      LogoModalStepper,
      {
        Component,
        currentStep,
        onChangeLogo,
        customLogo,
        goTo,
        next,
        prev,
        modalTitle
      }
    )
  ] });
};
LogoInput.defaultProps = {
  canUpdate: false,
  customLogo: null,
  hint: null
};
LogoInput.propTypes = {
  canUpdate: PropTypes.bool,
  customLogo: PropTypes.shape({
    url: PropTypes.string,
    name: PropTypes.string
  }),
  label: PropTypes.string.isRequired,
  hint: PropTypes.string,
  defaultLogo: PropTypes.string.isRequired,
  onChangeLogo: PropTypes.func.isRequired,
  onResetLogo: PropTypes.func.isRequired
};
const init = (initialState2, projectSettingsStored) => {
  const copyInitialState = merge(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(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 = forwardRef(({ canUpdate, projectSettingsStored }, ref) => {
  const { formatMessage } = useIntl();
  const { trackUsage } = useTracking();
  const {
    logos: { menu, auth }
  } = useConfiguration();
  const [{ menuLogo, authLogo }, dispatch] = 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"
    });
  };
  useImperativeHandle(ref, () => ({
    getValues: () => ({ menuLogo: menuLogo.submit, authLogo: authLogo.submit })
  }));
  return /* @__PURE__ */ jsxs(
    Box,
    {
      hasRadius: true,
      background: "neutral0",
      shadow: "tableShadow",
      paddingTop: 6,
      paddingBottom: 6,
      paddingRight: 7,
      paddingLeft: 7,
      children: [
        /* @__PURE__ */ jsx(Typography, { variant: "delta", as: "h3", children: formatMessage({
          id: "Settings.application.customization",
          defaultMessage: "Customization"
        }) }),
        /* @__PURE__ */ jsx(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__ */ jsxs(Grid, { paddingTop: 4, gap: 4, children: [
          /* @__PURE__ */ jsx(GridItem, { col: 6, s: 12, children: /* @__PURE__ */ 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__ */ jsx(GridItem, { col: 6, s: 12, children: /* @__PURE__ */ 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.bool,
  projectSettingsStored: PropTypes.shape({
    menuLogo: PropTypes.shape({
      url: PropTypes.string,
      name: PropTypes.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.useRef();
  const toggleNotification = useNotification();
  const { trackUsage } = useTracking();
  const { formatMessage } = useIntl();
  const { get, post } = useFetchClient();
  const { updateProjectSettings } = useConfiguration();
  const permissions = useSelector(selectAdminPermissions);
  const { formatAPIError } = useAPIErrorHandler();
  useAppInfo();
  const AdminSeatInfo = useEnterprise(
    AdminSeatInfoCE,
    async () => (await import("./index-d0afcccb.mjs")).AdminSeatInfoEE
  );
  const {
    allowedActions: { canRead, canUpdate }
  } = useRBAC(permissions.settings["project-settings"]);
  useFocusWhenNavigate();
  const { data, isLoading } = 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: prefixFileUrlWithBackendUrl(data2.authLogo.url)
          } : data2.authLogo,
          menuLogo: data2.menuLogo ? {
            ...data2.menuLogo,
            url: prefixFileUrlWithBackendUrl(data2.menuLogo.url)
          } : data2.menuLogo
        };
      }
    }
  );
  const submitMutation = 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__ */ jsxs(Layout, { children: [
    /* @__PURE__ */ jsx(SettingsPageTitle, { name: "Application" }),
    /* @__PURE__ */ jsx(Main, { children: isLoading ? /* @__PURE__ */ jsx(Loader, { children: formatMessage({
      id: "Settings.application.isLoading",
      defaultMessage: "Loading"
    }) }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
      /* @__PURE__ */ jsx(
        HeaderLayout,
        {
          title: formatMessage({
            id: "Settings.application.title",
            defaultMessage: "Overview"
          }),
          subtitle: formatMessage({
            id: "Settings.application.description",
            defaultMessage: "Administration panel’s global information"
          }),
          primaryAction: canUpdate && /* @__PURE__ */ jsx(Button, { type: "submit", startIcon: /* @__PURE__ */ jsx(Check, {}), children: formatMessage({ id: "global.save", defaultMessage: "Save" }) })
        }
      ),
      /* @__PURE__ */ jsx(ContentLayout, { children: /* @__PURE__ */ jsx(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: canRead && data && /* @__PURE__ */ jsx(
        CustomizationInfos,
        {
          canUpdate,
          ref: inputsRef,
          projectSettingsStored: data
        }
      ) }) })
    ] }) })
  ] });
};
function makeUniqueRoutes(routes) {
  return routes.filter(
    (route, index, refArray) => refArray.findIndex((obj) => obj.key === route.key) === index
  );
}
function SettingsPage() {
  const { settingId } = useParams();
  const { settings } = useStrapiApp();
  const { formatMessage } = useIntl();
  const { isLoading, menu } = useSettingsMenu();
  const routes = useEnterprise(
    ROUTES_CE,
    async () => (await import("./constants-24bb4d36.mjs")).ROUTES_EE,
    {
      combine(ceRoutes, eeRoutes) {
        return [...ceRoutes, ...eeRoutes];
      },
      defaultValue: []
    }
  );
  const adminRoutes = React.useMemo(() => {
    return makeUniqueRoutes(
      routes.map(({ to, Component, exact }) => createRoute(Component, to, exact))
    );
  }, [routes]);
  const pluginsRoutes = Object.values(settings).flatMap((section) => {
    const { links } = section;
    return links.map((link) => createRoute(link.Component, link.to, link.exact || false));
  });
  if (isLoading) {
    return /* @__PURE__ */ jsx(LoadingIndicatorPage, {});
  }
  if (!settingId) {
    return /* @__PURE__ */ jsx(Redirect, { to: "/settings/application-infos" });
  }
  return /* @__PURE__ */ jsxs(Layout, { sideNav: /* @__PURE__ */ jsx(SettingsNav, { menu }), children: [
    /* @__PURE__ */ jsx(
      Helmet,
      {
        title: formatMessage({
          id: "global.settings",
          defaultMessage: "Settings"
        })
      }
    ),
    /* @__PURE__ */ jsxs(Switch, { children: [
      /* @__PURE__ */ jsx(Route, { path: "/settings/application-infos", component: ApplicationInfosPage, exact: true }),
      adminRoutes,
      pluginsRoutes
    ] })
  ] });
}
export {
  SettingsPage
};
//# sourceMappingURL=index-9b4da74a.mjs.map
