UNPKG

@selfcommunity/react-ui

Version:

React UI Components to integrate a Community created with SelfCommunity Platform.

206 lines (200 loc) • 11.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = tslib_1.__importStar(require("react")); const styles_1 = require("@mui/material/styles"); const material_1 = require("@mui/material"); const api_services_1 = require("@selfcommunity/api-services"); const react_core_1 = require("@selfcommunity/react-core"); const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon")); const react_intl_1 = require("react-intl"); const ConfirmDialog_1 = tslib_1.__importDefault(require("../../shared/ConfirmDialog/ConfirmDialog")); const classnames_1 = tslib_1.__importDefault(require("classnames")); const CircularProgress_1 = tslib_1.__importDefault(require("@mui/material/CircularProgress")); const system_1 = require("@mui/system"); const Errors_1 = require("../../constants/Errors"); const utils_1 = require("@selfcommunity/utils"); const constants_1 = require("./constants"); const classes = { root: `${constants_1.PREFIX}-root`, helpPopover: `${constants_1.PREFIX}-help-popover`, addMenuItem: `${constants_1.PREFIX}-add-menuItem`, delMenuItem: `${constants_1.PREFIX}-del-menuItem` }; const Root = (0, styles_1.styled)(material_1.Box, { name: constants_1.PREFIX, slot: 'Root' })(() => ({})); const messages = (0, react_intl_1.defineMessages)({ imageMaxSize: { id: 'ui.changeCover.button.change.alertMaxSize', defaultMessage: 'ui.changeCover.button.change.alertMaxSize' }, errorLoadImage: { id: 'ui.changeCover.button.change.alertErrorImage', defaultMessage: 'ui.changeCover.button.change.alertErrorImage' } }); /** * > API documentation for the Community-JS Change Cover component. Learn about the available props and the CSS API. * * * This component renders a button that allows users to edit their profile cover and a popover that specifies format and sizes allowed. * Take a look at our <strong>demo</strong> component [here](/docs/sdk/community-js/react-ui/Components/ChangeCover) #### Import ```jsx import {ChangeCover} from '@selfcommunity/react-ui'; ``` #### Component Name The name `SCChangeCoverButton` can be used when providing style overrides in the theme. #### CSS |Rule Name|Global class|Description| |---|---|---| |root|.SCChangeCoverButton-root|Styles applied to the root element.| |helpPopover|.SCChangeCoverButton-help-popover|Styles applied to the help popover element.| |addMenuItem|.SCChangeCoverButton-add-menuItem|Styles applied to the add menu element.| |delMenuItem|.SCChangeCoverButton-del-menuItem|Styles applied to the del menu element.| * @param inProps */ function ChangeCover(inProps) { //PROPS const props = (0, system_1.useThemeProps)({ props: inProps, name: constants_1.PREFIX }); const { onChange, autoHide, className } = props, rest = tslib_1.__rest(props, ["onChange", "autoHide", "className"]); //CONTEXT const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext); //STATE const theme = (0, material_1.useTheme)(); const isMobile = (0, material_1.useMediaQuery)(theme.breakpoints.down('md')); let fileInput = (0, react_1.useRef)(null); const [anchorEl, setAnchorEl] = react_1.default.useState(null); const open = Boolean(anchorEl); const [anchorElPopover, setAnchorElPopover] = react_1.default.useState(null); const [openDeleteCoverDialog, setOpenDeleteCoverDialog] = (0, react_1.useState)(false); const [isDeletingCover, setIsDeletingCover] = (0, react_1.useState)(false); const [loading, setLoading] = (0, react_1.useState)(false); const [alert, setAlert] = (0, react_1.useState)(null); // INTL const intl = (0, react_intl_1.useIntl)(); // HANDLERS const handleOpen = (event) => { setAnchorEl(event.currentTarget); }; const handleClose = () => { setAnchorEl(null); }; const hasCover = scUserContext.user && scUserContext.user.cover !== null; const handleClickHelpButton = (event) => { setAnchorElPopover(event.currentTarget); }; const handleCloseHelpPopover = () => { setAnchorElPopover(null); }; const isOpen = Boolean(anchorElPopover); // Anonymous if (!scUserContext.user) { return null; } /** * Handles file upload * @param event */ const handleUpload = (event) => { var _a; const maxSize = 5 * 1024 * 1024; if (((_a = event.target.files[0]) === null || _a === void 0 ? void 0 : _a.size) <= maxSize) { fileInput = event.target.files[0]; handleSave(); } else { setAlert(intl.formatMessage(messages.imageMaxSize)); setAnchorEl(null); } }; /** * Handles deletion of a specific cover */ function deleteCover() { setIsDeletingCover(true); handleSave(true); } /** * Handles cover saving after upload and delete actions */ function handleSave(performDelete = false) { setLoading(true); const formData = new FormData(); if (!performDelete) { // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore formData.append('cover', fileInput); } else { formData.append('cover', ''); } api_services_1.http .request({ url: api_services_1.Endpoints.UserPatch.url({ id: scUserContext.user['id'] }), method: api_services_1.Endpoints.UserPatch.method, headers: { 'Content-Type': 'multipart/form-data' }, data: formData }) .then((res) => { scUserContext.updateUser({ cover: res.data.cover }); onChange && onChange(res.data.cover); setAnchorEl(null); setLoading(false); if (performDelete) { setIsDeletingCover(false); setOpenDeleteCoverDialog(false); } }) .catch((error) => { utils_1.Logger.error(Errors_1.SCOPE_SC_UI, error); setLoading(false); setAlert(intl.formatMessage(messages.errorLoadImage)); }); } /** * Renders change cover menu items */ function renderMenuItems() { return ((0, jsx_runtime_1.jsx)(material_1.Box, { children: loading ? ((0, jsx_runtime_1.jsx)(material_1.MenuItem, Object.assign({ sx: { justifyContent: 'center' } }, { children: (0, jsx_runtime_1.jsx)(CircularProgress_1.default, { size: 15 }) }))) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("input", { type: "file", onChange: handleUpload, ref: fileInput, hidden: true, accept: ".gif,.png,.jpg,.jpeg" }), (0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ disabled: loading, onClick: () => fileInput.current.click(), className: classes.addMenuItem }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "add_circle_outline" }) }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.changeCover.button.upload", defaultMessage: "ui.changeCover.button.upload" })] })), hasCover && ((0, jsx_runtime_1.jsxs)(material_1.MenuItem, Object.assign({ className: classes.delMenuItem, onClick: () => setOpenDeleteCoverDialog(true) }, { children: [(0, jsx_runtime_1.jsx)(material_1.ListItemIcon, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "delete" }) }), (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.changeCover.button.delete", defaultMessage: "ui.changeCover.button.delete" })] })))] })) })); } /** * Renders change cover menu */ const cc = ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ size: "small", variant: "contained", disabled: loading, onClick: handleOpen }, rest, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "photo_camera" }) })), open && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: isMobile ? ((0, jsx_runtime_1.jsx)(material_1.SwipeableDrawer, Object.assign({ open: true, onClose: handleClose, onOpen: handleOpen, anchor: "bottom", disableSwipeToOpen: true }, { children: renderMenuItems() }))) : ((0, jsx_runtime_1.jsx)(material_1.Menu, Object.assign({ anchorEl: anchorEl, open: true, onClose: handleClose }, { children: renderMenuItems() }))) })), !isMobile && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, Object.assign({ className: classes.helpPopover, variant: "contained", onClick: handleClickHelpButton }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "help_outline" }) })), isOpen && ((0, jsx_runtime_1.jsx)(material_1.Popover, Object.assign({ open: isOpen, anchorEl: anchorElPopover, onClose: handleCloseHelpPopover, anchorOrigin: { vertical: 'bottom', horizontal: 'right' } }, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ sx: { p: '10px' } }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "h3" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.changeCover.button.uploadA", defaultMessage: "ui.changeCover.button.uploadA" }) })), (0, jsx_runtime_1.jsx)(material_1.Divider, {}), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ component: "span" }, { children: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.changeCover.info", defaultMessage: "ui.changeCover.info", values: { // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore li: (chunks) => (0, jsx_runtime_1.jsx)("li", { children: chunks }), // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore ul: (chunks) => (0, jsx_runtime_1.jsx)("ul", { children: chunks }) } }) }))] })) })))] })), openDeleteCoverDialog && ((0, jsx_runtime_1.jsx)(ConfirmDialog_1.default, { open: openDeleteCoverDialog, title: (0, jsx_runtime_1.jsx)(react_intl_1.FormattedMessage, { id: "ui.changeCover.dialog.msg", defaultMessage: "ui.changeCover.dialog.msg" }), onConfirm: deleteCover, isUpdating: isDeletingCover, onClose: () => { setOpenDeleteCoverDialog(false); setAnchorEl(null); } }))] })); /** * If there is an error */ if (alert) { return ((0, jsx_runtime_1.jsx)(material_1.Alert, Object.assign({ color: "error", onClose: () => setAlert(null) }, { children: alert }))); } /** * Renders root object (if not hidden by autoHide prop) */ if (!autoHide) { return ((0, jsx_runtime_1.jsx)(Root, Object.assign({}, rest, { className: (0, classnames_1.default)(classes.root, className) }, { children: cc }))); } return null; } exports.default = ChangeCover;