| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { useState } from "react"; | import { useState } from "react"; | ||||
| import DeleteCategory from "../../Modals/DeleteCategory/DeleteCategory"; | import DeleteCategory from "../../Modals/DeleteCategory/DeleteCategory"; | ||||
| import EditCategory from "../../Modals/EditCategory/EditCategory"; | |||||
| import history from "../../../store/utils/history"; | |||||
| import { replaceInRoute } from "../../../util/helpers/routeHelpers"; | |||||
| import { ADMIN_SUBCATEGORIES_PAGE } from "../../../constants/pages"; | |||||
| const CategoryCard = (props) => { | const CategoryCard = (props) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const [openedDeleteModal, setOpenedDeleteModal] = useState(false); | const [openedDeleteModal, setOpenedDeleteModal] = useState(false); | ||||
| const [openedEditModal, setOpenedEditModal] = useState(false); | |||||
| const navigateToCategory = () => { | |||||
| if (!props.subcategory) { | |||||
| history.push( | |||||
| replaceInRoute(ADMIN_SUBCATEGORIES_PAGE, { | |||||
| categoryId: props.category._id, | |||||
| }) | |||||
| ); | |||||
| } | |||||
| }; | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <CategoryCardContainer className={props.className}> | <CategoryCardContainer className={props.className}> | ||||
| <CategoryCardLeftContainer> | <CategoryCardLeftContainer> | ||||
| <CategoryCardName categoryName={props?.category?.name} /> | |||||
| <CategoryCardName | |||||
| categoryName={props?.category?.name} | |||||
| onClick={navigateToCategory} | |||||
| /> | |||||
| <CategoryCardDetailsContainer> | <CategoryCardDetailsContainer> | ||||
| <CategoryDetail | <CategoryDetail | ||||
| label={t("admin.categories.noOfOffers")} | label={t("admin.categories.noOfOffers")} | ||||
| </CategoryCardLeftContainer> | </CategoryCardLeftContainer> | ||||
| <CategoryCardRightContainer> | <CategoryCardRightContainer> | ||||
| <CategoryRemoveButton onClick={() => setOpenedDeleteModal(true)} /> | <CategoryRemoveButton onClick={() => setOpenedDeleteModal(true)} /> | ||||
| <CategoryEditButton /> | |||||
| {!props.hideCheckButton && <CategoryCheckButton />} | |||||
| <CategoryEditButton onClick={() => setOpenedEditModal(true)} /> | |||||
| {!props.hideCheckButton && ( | |||||
| <CategoryCheckButton onClick={navigateToCategory} /> | |||||
| )} | |||||
| </CategoryCardRightContainer> | </CategoryCardRightContainer> | ||||
| </CategoryCardContainer> | </CategoryCardContainer> | ||||
| {openedDeleteModal && ( | {openedDeleteModal && ( | ||||
| <DeleteCategory | <DeleteCategory | ||||
| setOpenedDeleteModal={setOpenedDeleteModal} | setOpenedDeleteModal={setOpenedDeleteModal} | ||||
| subcategory={props.subcategory} | |||||
| category={props.category} | category={props.category} | ||||
| type={props.type} | |||||
| /> | |||||
| )} | |||||
| {openedEditModal && ( | |||||
| <EditCategory | |||||
| hideImagePicker | |||||
| setOpenedEditModal={setOpenedEditModal} | |||||
| category={props.category} | |||||
| subcategory={props.subcategory} | |||||
| type={props.type} | |||||
| method="edit" | |||||
| /> | /> | ||||
| )} | )} | ||||
| </> | </> | ||||
| secondLabel: PropTypes.string, | secondLabel: PropTypes.string, | ||||
| hideSecondLabel: PropTypes.bool, | hideSecondLabel: PropTypes.bool, | ||||
| className: PropTypes.string, | className: PropTypes.string, | ||||
| subcategory: PropTypes.bool, | |||||
| type: PropTypes.string, | |||||
| }; | }; | ||||
| export default CategoryCard; | export default CategoryCard; |
| const CategoryCardName = (props) => { | const CategoryCardName = (props) => { | ||||
| return ( | return ( | ||||
| <CategoryCardNameContainer> | |||||
| <CategoryCardNameContainer onClick={props.onClick}> | |||||
| <CategoryCardNameText>{props.categoryName}</CategoryCardNameText> | <CategoryCardNameText>{props.categoryName}</CategoryCardNameText> | ||||
| </CategoryCardNameContainer> | </CategoryCardNameContainer> | ||||
| ); | ); | ||||
| CategoryCardName.propTypes = { | CategoryCardName.propTypes = { | ||||
| children: PropTypes.node, | children: PropTypes.node, | ||||
| categoryName: PropTypes.string, | categoryName: PropTypes.string, | ||||
| onClick: PropTypes.func, | |||||
| }; | }; | ||||
| export default CategoryCardName; | export default CategoryCardName; |
| import { CheckButton } from "./CategoryCheckButton.styled"; | import { CheckButton } from "./CategoryCheckButton.styled"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| const CategoryCheckButton = () => { | |||||
| const CategoryCheckButton = (props) => { | |||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| return ( | return ( | ||||
| <CheckButton | <CheckButton | ||||
| onClick={props.onClick} | |||||
| variant={"outlined"} | variant={"outlined"} | ||||
| buttoncolor={selectedTheme.colors.primaryPurple} | buttoncolor={selectedTheme.colors.primaryPurple} | ||||
| textcolor={selectedTheme.colors.primaryPurple} | textcolor={selectedTheme.colors.primaryPurple} | ||||
| CategoryCheckButton.propTypes = { | CategoryCheckButton.propTypes = { | ||||
| category: PropTypes.any, | category: PropTypes.any, | ||||
| onClick: PropTypes.func, | |||||
| }; | }; | ||||
| export default CategoryCheckButton; | export default CategoryCheckButton; |
| EditIcon, | EditIcon, | ||||
| } from "./CategoryEditButton.styled"; | } from "./CategoryEditButton.styled"; | ||||
| const CategoryEditButton = () => { | |||||
| const CategoryEditButton = (props) => { | |||||
| return ( | return ( | ||||
| <CategoryEditButtonContainer> | |||||
| <CategoryEditButtonContainer onClick={props.onClick}> | |||||
| <EditIcon /> | <EditIcon /> | ||||
| </CategoryEditButtonContainer> | </CategoryEditButtonContainer> | ||||
| ); | ); | ||||
| CategoryEditButton.propTypes = { | CategoryEditButton.propTypes = { | ||||
| category: PropTypes.any, | category: PropTypes.any, | ||||
| onClick: PropTypes.func, | |||||
| }; | }; | ||||
| export default CategoryEditButton; | export default CategoryEditButton; |
| import LabeledCard from "../../Cards/LabeledCard/LabeledCard"; | import LabeledCard from "../../Cards/LabeledCard/LabeledCard"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | ||||
| import { useMemo } from "react"; | |||||
| const DeleteCategory = (props) => { | const DeleteCategory = (props) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| props.setOpenedDeleteModal(false); | props.setOpenedDeleteModal(false); | ||||
| }; | }; | ||||
| const reassuranceText = useMemo(() => { | |||||
| if (props.subcategory) return t("admin.subcategories.reassuranceDelete"); | |||||
| return t("admin.categories.reassuranceDelete"); | |||||
| }, [props]); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <BackdropComponent | <BackdropComponent | ||||
| <LabeledCard icon={<DeleteIcon />}> | <LabeledCard icon={<DeleteIcon />}> | ||||
| <CategoryName>{props.category.name}</CategoryName> | <CategoryName>{props.category.name}</CategoryName> | ||||
| </LabeledCard> | </LabeledCard> | ||||
| <ReassuranceText> | |||||
| {t("admin.categories.reassuranceDelete")} | |||||
| </ReassuranceText> | |||||
| <ReassuranceText>{reassuranceText}</ReassuranceText> | |||||
| <ButtonsContainer> | <ButtonsContainer> | ||||
| <PrimaryButton | <PrimaryButton | ||||
| onClick={handleCancel} | onClick={handleCancel} | ||||
| DeleteCategory.propTypes = { | DeleteCategory.propTypes = { | ||||
| setOpenedDeleteModal: PropTypes.func, | setOpenedDeleteModal: PropTypes.func, | ||||
| category: PropTypes.object, | category: PropTypes.object, | ||||
| subcategory: PropTypes.bool, | |||||
| }; | }; | ||||
| export default DeleteCategory; | export default DeleteCategory; |
| import React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import BackdropComponent from "../../MUI/BackdropComponent"; | |||||
| import { | |||||
| ButtonsContainer, | |||||
| CategoryTitleField, | |||||
| EditCategoryContainer, | |||||
| EditCategoryImagePicker, | |||||
| EditCategoryTitle, | |||||
| FieldLabel, | |||||
| SaveButton, | |||||
| SupportedFormats, | |||||
| XIcon, | |||||
| } from "./EditCategory.styled"; | |||||
| import { useState } from "react"; | |||||
| import { Trans, useTranslation } from "react-i18next"; | |||||
| import { useFormik } from "formik"; | |||||
| import { useMemo } from "react"; | |||||
| const EditCategory = (props) => { | |||||
| const { t } = useTranslation(); | |||||
| const [image, setImage] = useState(""); | |||||
| console.log(props); | |||||
| const title = useMemo(() => { | |||||
| return t(`admin.${props.type}.${props.method}.title`); | |||||
| }, [props.type, props.method]); | |||||
| const placeholder = useMemo(() => { | |||||
| return t(`admin.${props.type}.${props.method}.placeholder`); | |||||
| }, [props.type, props.method]); | |||||
| const fieldLabel = useMemo(() => { | |||||
| return t(`admin.${props.type}.${props.method}.fieldTitle`); | |||||
| }, [props.type, props.method]); | |||||
| const firstButtonText = useMemo(() => { | |||||
| return t(`admin.${props.type}.${props.method}.next`); | |||||
| }, [props.type, props.method]); | |||||
| const secondButtonText = useMemo(() => { | |||||
| return t(`admin.${props.type}.${props.method}.save`); | |||||
| }, [props.type, props.method]); | |||||
| const setImageHandler = (image) => { | |||||
| setImage(image); | |||||
| formik.setFieldValue("image", image); | |||||
| }; | |||||
| const handleSubmit = (values) => { | |||||
| console.log(values); | |||||
| console.log(image); | |||||
| }; | |||||
| const formik = useFormik({ | |||||
| initialValues: { | |||||
| image: "", | |||||
| title: props?.category?.name || "", | |||||
| }, | |||||
| onSubmit: handleSubmit, | |||||
| }); | |||||
| return ( | |||||
| <> | |||||
| <BackdropComponent | |||||
| isLoading | |||||
| handleClose={() => props.setOpenedEditModal(false)} | |||||
| position="fixed" | |||||
| /> | |||||
| <EditCategoryContainer hideImagePicker={props.hideImagePicker}> | |||||
| <XIcon onClick={() => props.setOpenedEditModal(false)} /> | |||||
| <EditCategoryTitle>{title}</EditCategoryTitle> | |||||
| {!props.hideImagePicker && ( | |||||
| <> | |||||
| <EditCategoryImagePicker setImage={setImageHandler} singleImage /> | |||||
| <SupportedFormats> | |||||
| <Trans i18nKey="offer.supportedImagesFormats" /> | |||||
| </SupportedFormats> | |||||
| </> | |||||
| )} | |||||
| <FieldLabel leftText={fieldLabel} /> | |||||
| <CategoryTitleField | |||||
| name="title" | |||||
| placeholder={placeholder} | |||||
| italicPlaceholder | |||||
| margin="normal" | |||||
| value={formik.values.title} | |||||
| onChange={formik.handleChange} | |||||
| error={formik.touched.title && formik.errors.title} | |||||
| helperText={formik.touched.title && formik.errors.title} | |||||
| autoFocus | |||||
| fullWidth | |||||
| /> | |||||
| <ButtonsContainer> | |||||
| {props.method === "add" && ( | |||||
| <SaveButton | |||||
| variant="contained" | |||||
| width="180px" | |||||
| height="48px" | |||||
| onClick={formik.handleSubmit} | |||||
| > | |||||
| {firstButtonText} | |||||
| </SaveButton> | |||||
| )} | |||||
| <SaveButton | |||||
| variant={props.method === "add" ? "outlined" : "contained"} | |||||
| width={props.method === "add" ? "180px" : "376px"} | |||||
| height="48px" | |||||
| onClick={formik.handleSubmit} | |||||
| > | |||||
| {secondButtonText} | |||||
| </SaveButton> | |||||
| </ButtonsContainer> | |||||
| </EditCategoryContainer> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| EditCategory.propTypes = { | |||||
| category: PropTypes.any, | |||||
| setOpenedEditModal: PropTypes.func, | |||||
| hideImagePicker: PropTypes.bool, | |||||
| type: PropTypes.string, | |||||
| method: PropTypes.string, | |||||
| }; | |||||
| export default EditCategory; |
| import { Box, Typography } from "@mui/material"; | |||||
| import styled from "styled-components"; | |||||
| import selectedTheme from "../../../themes"; | |||||
| import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | |||||
| import { Label } from "../../CheckBox/Label"; | |||||
| import ImagePicker from "../../ImagePicker/ImagePicker"; | |||||
| import { TextField } from "../../TextFields/TextField/TextField"; | |||||
| import { ReactComponent as X } from "../../../assets/images/svg/plus.svg"; | |||||
| export const EditCategoryContainer = styled(Box)` | |||||
| position: fixed; | |||||
| width: 623px; | |||||
| height: ${(props) => (props.hideImagePicker ? "296px" : "510px")}; | |||||
| top: ${(props) => | |||||
| props.hideImagePicker ? "calc(50vh - 148px)" : "calc(50vh - 255px)"}; | |||||
| left: calc(50vw - 311px); | |||||
| background: white; | |||||
| z-index: 150; | |||||
| & > * { | |||||
| margin-left: auto; | |||||
| margin-right: auto; | |||||
| } | |||||
| `; | |||||
| export const EditCategoryTitle = styled(Typography)` | |||||
| display: block; | |||||
| font-family: ${selectedTheme.fonts.textFont}; | |||||
| font-weight: 700; | |||||
| font-size: 24px; | |||||
| line-height: 31px; | |||||
| text-align: center; | |||||
| margin-top: 36px; | |||||
| width: 256px; | |||||
| color: ${selectedTheme.colors.primaryPurple}; | |||||
| `; | |||||
| export const EditCategoryImagePicker = styled(ImagePicker)` | |||||
| background: none; | |||||
| margin-top: 36px; | |||||
| background: ${selectedTheme.colors.primaryIconBackgroundColor}; | |||||
| background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='100' ry='100' stroke='%235A3984FF' stroke-width='2' stroke-dasharray='7%2c 12' stroke-dashoffset='44' stroke-linecap='square'/%3e%3c/svg%3e"); | |||||
| border-radius: 100px; | |||||
| overflow: hidden; | |||||
| position: relative; | |||||
| left: calc(50% - 72px); | |||||
| margin-bottom: 18px; | |||||
| `; | |||||
| export const SupportedFormats = styled(Typography)` | |||||
| font-size: 13px; | |||||
| width: 100%; | |||||
| text-align: center; | |||||
| font-family: ${selectedTheme.fonts.textFont}; | |||||
| `; | |||||
| export const CategoryTitleField = styled(TextField)` | |||||
| width: 375px; | |||||
| margin-bottom: 36px; | |||||
| @media (max-width: 600px) { | |||||
| margin-bottom: 0; | |||||
| & div div input { | |||||
| font-size: 12px !important; | |||||
| } | |||||
| & div { | |||||
| height: 40px; | |||||
| } | |||||
| } | |||||
| `; | |||||
| export const FieldLabel = styled(Label)` | |||||
| position: relative; | |||||
| bottom: -14px; | |||||
| width: 376px; | |||||
| margin-top: 22px; | |||||
| & label { | |||||
| font-size: 12px; | |||||
| font-weight: 600; | |||||
| line-height: 20px; | |||||
| color: ${selectedTheme.colors.primaryGrayText}; | |||||
| cursor: auto; | |||||
| letter-spacing: 0.2px; | |||||
| } | |||||
| @media (max-width: 600px) { | |||||
| & label { | |||||
| font-size: 9px; | |||||
| } | |||||
| } | |||||
| `; | |||||
| export const SaveButton = styled(PrimaryButton)` | |||||
| max-width: 376px; | |||||
| height: 48px; | |||||
| & button { | |||||
| letter-spacing: 1.5px; | |||||
| } | |||||
| `; | |||||
| export const XIcon = styled(X)` | |||||
| transform: rotate(45deg); | |||||
| position: absolute; | |||||
| top: 36px; | |||||
| right: 36px; | |||||
| cursor: pointer; | |||||
| width: 26px; | |||||
| height: 26px; | |||||
| & path { | |||||
| stroke: ${selectedTheme.colors.messageText}; | |||||
| stroke-width: 2; | |||||
| } | |||||
| `; | |||||
| export const ButtonsContainer = styled(Box)` | |||||
| display: flex; | |||||
| justify-content: center; | |||||
| flex-direction: row; | |||||
| gap: 18px; | |||||
| margin: 36px auto; | |||||
| `; |
| "Da li ste sigurni da želite da obrišete odabranu kategoriju?", | "Da li ste sigurni da želite da obrišete odabranu kategoriju?", | ||||
| cancel: "Otkaži", | cancel: "Otkaži", | ||||
| delete: "Obriši", | delete: "Obriši", | ||||
| addCategory: "Dodaj kategoriju", | |||||
| edit: { | |||||
| title: "Izmena Kategorije", | |||||
| fieldTitle: "Naslov", | |||||
| placeholder: "Naziv kategorije...", | |||||
| save: "Izmeni" | |||||
| }, | |||||
| add: { | |||||
| title: "Nova Kategorija", | |||||
| fieldTitle: "Naslov", | |||||
| placeholder: "Naziv kategorije...", | |||||
| save: "Dodaj", | |||||
| next: "Sledeća" | |||||
| } | |||||
| }, | }, | ||||
| subcategories: { | subcategories: { | ||||
| noOfOffers: "Broj objava: ", | noOfOffers: "Broj objava: ", | ||||
| headerTitle: "Kategorija", | headerTitle: "Kategorija", | ||||
| subcategoriesHeaderTitle: "Podkategorije", | subcategoriesHeaderTitle: "Podkategorije", | ||||
| placeholder: "Pretražite podkategorije...", | placeholder: "Pretražite podkategorije...", | ||||
| addSubcategory: "Dodaj podkategoriju", | |||||
| reassuranceDelete: "Da li ste sigurni da želite da obrišete odabranu podkategoriju?", | |||||
| edit: { | |||||
| title: "Izmena Podkategorije", | |||||
| fieldTitle: "Naslov", | |||||
| placeholder: "Naziv podkategorije...", | |||||
| save: "Izmeni" | |||||
| }, | |||||
| add: { | |||||
| title: "Nova Podkategorija", | |||||
| fieldTitle: "Naslov", | |||||
| placeholder: "Naziv podkategorije...", | |||||
| save: "Dodaj", | |||||
| next: "Sledeća" | |||||
| } | |||||
| }, | }, | ||||
| }, | }, | ||||
| }; | }; |
| AdminCategoriesHeader, | AdminCategoriesHeader, | ||||
| AdminCategoriesPageContainer, | AdminCategoriesPageContainer, | ||||
| AdminCategoriesSearchField, | AdminCategoriesSearchField, | ||||
| NewCategoryButton, | |||||
| } from "./AdminCategoriesPage.styled"; | } from "./AdminCategoriesPage.styled"; | ||||
| import { selectManualSearchString } from "../../store/selectors/filtersSelectors"; | import { selectManualSearchString } from "../../store/selectors/filtersSelectors"; | ||||
| import { useMemo } from "react"; | import { useMemo } from "react"; | ||||
| import { setManualSearchString } from "../../store/actions/filters/filtersActions"; | import { setManualSearchString } from "../../store/actions/filters/filtersActions"; | ||||
| import selectedTheme from "../../themes"; | |||||
| import { useState } from "react"; | |||||
| import EditCategory from "../../components/Modals/EditCategory/EditCategory"; | |||||
| const AdminCategoriesPage = () => { | const AdminCategoriesPage = () => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const categories = useSelector(selectCategories); | const categories = useSelector(selectCategories); | ||||
| const manualSearchString = useSelector(selectManualSearchString); | const manualSearchString = useSelector(selectManualSearchString); | ||||
| const [openedAddModal, setOpenedAddModal] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(fetchCategories()); | dispatch(fetchCategories()); | ||||
| }, []); | }, []); | ||||
| return []; | return []; | ||||
| }, [categories, manualSearchString]); | }, [categories, manualSearchString]); | ||||
| return ( | return ( | ||||
| <> | |||||
| <AdminCategoriesPageContainer> | <AdminCategoriesPageContainer> | ||||
| <AdminCategoriesSearchField | <AdminCategoriesSearchField | ||||
| isAdmin | isAdmin | ||||
| <CategoryCard | <CategoryCard | ||||
| key={category._id} | key={category._id} | ||||
| category={category} | category={category} | ||||
| type="categories" | |||||
| secondLabel={t("admin.categories.noOfSubcategories")} | secondLabel={t("admin.categories.noOfSubcategories")} | ||||
| /> | /> | ||||
| ))} | ))} | ||||
| <NewCategoryButton | |||||
| variant="contained" | |||||
| buttoncolor={selectedTheme.colors.iconYellowColor} | |||||
| textcolor={selectedTheme.colors.messageText} | |||||
| onClick={() => setOpenedAddModal(true)} | |||||
| > | |||||
| {t("admin.categories.addCategory")} | |||||
| </NewCategoryButton> | |||||
| </AdminCategoriesPageContainer> | </AdminCategoriesPageContainer> | ||||
| {openedAddModal && ( | |||||
| <EditCategory | |||||
| setOpenedEditModal={setOpenedAddModal} | |||||
| type={"categories"} | |||||
| method="add" | |||||
| /> | |||||
| )} | |||||
| </> | |||||
| ); | ); | ||||
| }; | }; | ||||
| import { Box } from "@mui/material"; | import { Box } from "@mui/material"; | ||||
| import styled from "styled-components"; | import styled from "styled-components"; | ||||
| import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton"; | |||||
| import Header from "../../components/MarketPlace/Header/Header"; | import Header from "../../components/MarketPlace/Header/Header"; | ||||
| import SearchField from "../../components/TextFields/SearchField/SearchField"; | import SearchField from "../../components/TextFields/SearchField/SearchField"; | ||||
| export const AdminCategoriesPageContainer = styled(Box)` | export const AdminCategoriesPageContainer = styled(Box)` | ||||
| padding: 60px; | padding: 60px; | ||||
| min-height: 100vh; | |||||
| position: relative; | |||||
| padding-bottom: 100px; | |||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| padding: 18px; | padding: 18px; | ||||
| position: relative; | |||||
| min-height: calc(100vh - 72px); | |||||
| top: 65px; | top: 65px; | ||||
| padding-bottom: 54px; | |||||
| } | } | ||||
| `; | `; | ||||
| export const AdminCategoriesHeader = styled(Header)` | export const AdminCategoriesHeader = styled(Header)` | ||||
| display: none; | display: none; | ||||
| } | } | ||||
| `; | `; | ||||
| export const NewCategoryButton = styled(PrimaryButton)` | |||||
| position: absolute; | |||||
| bottom: 18px; | |||||
| right: 37px; | |||||
| height: 48px; | |||||
| width: 224px; | |||||
| & button { | |||||
| font-weight: 700; | |||||
| } | |||||
| @media (max-width: 600px) { | |||||
| bottom: 18px; | |||||
| right: 16px; | |||||
| } | |||||
| ` |
| AdminSubcategoriesHeader, | AdminSubcategoriesHeader, | ||||
| AdminSubcategoriesPageContainer, | AdminSubcategoriesPageContainer, | ||||
| AdminSubcategoriesSearchField, | AdminSubcategoriesSearchField, | ||||
| NewSubcategoryButton, | |||||
| SponsoredCategoryCard, | SponsoredCategoryCard, | ||||
| } from "./AdminSubcategoriesPage.styled"; | } from "./AdminSubcategoriesPage.styled"; | ||||
| import { selectManualSearchString } from "../../store/selectors/filtersSelectors"; | import { selectManualSearchString } from "../../store/selectors/filtersSelectors"; | ||||
| import { setManualSearchString } from "../../store/actions/filters/filtersActions"; | import { setManualSearchString } from "../../store/actions/filters/filtersActions"; | ||||
| import { useRouteMatch } from "react-router-dom"; | import { useRouteMatch } from "react-router-dom"; | ||||
| import CategoryCard from "../../components/Cards/CategoryCard/CategoryCard"; | import CategoryCard from "../../components/Cards/CategoryCard/CategoryCard"; | ||||
| import selectedTheme from "../../themes"; | |||||
| import { useState } from "react"; | |||||
| import EditCategory from "../../components/Modals/EditCategory/EditCategory"; | |||||
| const AdminSubcategoriesPage = () => { | const AdminSubcategoriesPage = () => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const categories = useSelector(selectCategories); | const categories = useSelector(selectCategories); | ||||
| const routeMatch = useRouteMatch(); | const routeMatch = useRouteMatch(); | ||||
| const manualSearchString = useSelector(selectManualSearchString); | const manualSearchString = useSelector(selectManualSearchString); | ||||
| const [openedAddModal, setOpenedAddModal] = useState(false); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(fetchCategories()); | dispatch(fetchCategories()); | ||||
| }, []); | }, []); | ||||
| hideBackButton | hideBackButton | ||||
| /> | /> | ||||
| <SponsoredCategoryCard | <SponsoredCategoryCard | ||||
| subcategory | |||||
| category={category} | category={category} | ||||
| hideSecondLabel | hideSecondLabel | ||||
| type="categories" | |||||
| hideCheckButton | hideCheckButton | ||||
| /> | /> | ||||
| <AdminSubcategoriesHeader | <AdminSubcategoriesHeader | ||||
| /> | /> | ||||
| {subcategories.map((category) => ( | {subcategories.map((category) => ( | ||||
| <CategoryCard | <CategoryCard | ||||
| subcategory | |||||
| key={category._id} | key={category._id} | ||||
| category={category} | category={category} | ||||
| type="subcategories" | |||||
| hideSecondLabel | hideSecondLabel | ||||
| hideCheckButton | hideCheckButton | ||||
| /> | /> | ||||
| ))} | ))} | ||||
| <NewSubcategoryButton | |||||
| variant="contained" | |||||
| buttoncolor={selectedTheme.colors.iconYellowColor} | |||||
| textcolor={selectedTheme.colors.messageText} | |||||
| onClick={() => setOpenedAddModal(true)} | |||||
| > | |||||
| {t("admin.subcategories.addSubcategory")} | |||||
| </NewSubcategoryButton> | |||||
| </AdminSubcategoriesPageContainer> | </AdminSubcategoriesPageContainer> | ||||
| {openedAddModal && ( | |||||
| <EditCategory | |||||
| hideImagePicker | |||||
| setOpenedEditModal={setOpenedAddModal} | |||||
| type="subcategories" | |||||
| method="add" | |||||
| /> | |||||
| )} | |||||
| </> | </> | ||||
| ); | ); | ||||
| }; | }; |
| import { Box } from "@mui/material"; | import { Box } from "@mui/material"; | ||||
| import styled from "styled-components"; | import styled from "styled-components"; | ||||
| import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton"; | |||||
| import CategoryCard from "../../components/Cards/CategoryCard/CategoryCard"; | import CategoryCard from "../../components/Cards/CategoryCard/CategoryCard"; | ||||
| import Header from "../../components/MarketPlace/Header/Header"; | import Header from "../../components/MarketPlace/Header/Header"; | ||||
| import SearchField from "../../components/TextFields/SearchField/SearchField"; | import SearchField from "../../components/TextFields/SearchField/SearchField"; | ||||
| export const AdminSubcategoriesPageContainer = styled(Box)` | export const AdminSubcategoriesPageContainer = styled(Box)` | ||||
| padding: 60px; | padding: 60px; | ||||
| display: flex; | |||||
| position: relative; | |||||
| padding-bottom: 100px; | |||||
| min-height: 100vh; | |||||
| flex-direction: column; | |||||
| @media (max-width: 600px) { | @media (max-width: 600px) { | ||||
| padding: 18px; | padding: 18px; | ||||
| position: relative; | |||||
| min-height: (100vh - 72px); | |||||
| padding-bottom: 54px; | |||||
| top: 65px; | top: 65px; | ||||
| } | } | ||||
| `; | `; | ||||
| background: ${selectedTheme.colors.backgroundSponsoredColor}; | background: ${selectedTheme.colors.backgroundSponsoredColor}; | ||||
| border: 1px solid ${selectedTheme.colors.borderSponsoredColor}; | border: 1px solid ${selectedTheme.colors.borderSponsoredColor}; | ||||
| `; | `; | ||||
| export const NewSubcategoryButton = styled(PrimaryButton)` | |||||
| position: absolute; | |||||
| bottom: 18px; | |||||
| right: 37px; | |||||
| height: 48px; | |||||
| width: 224px; | |||||
| & button { | |||||
| font-weight: 700; | |||||
| } | |||||
| @media (max-width: 600px) { | |||||
| bottom: 18px; | |||||
| right: 16px; | |||||
| } | |||||
| ` |