Parcourir la source

Partly finished feature 654

feature/654
djordjemitrovic00 il y a 3 ans
Parent
révision
4404f8ecd2
26 fichiers modifiés avec 494 ajouts et 55 suppressions
  1. 3
    0
      src/AppRoutes.js
  2. 49
    0
      src/components/Cards/CategoryCard/CategoryCard.js
  3. 22
    0
      src/components/Cards/CategoryCard/CategoryCard.styled.js
  4. 21
    0
      src/components/Cards/CategoryCard/CategoryCardName/CategoryCardName.js
  5. 17
    0
      src/components/Cards/CategoryCard/CategoryCardName/CategoryCardName.styled.js
  6. 25
    0
      src/components/Cards/CategoryCard/CategoryCheckButton/CategoryCheckButton.js
  7. 17
    0
      src/components/Cards/CategoryCard/CategoryCheckButton/CategoryCheckButton.styled.js
  8. 23
    0
      src/components/Cards/CategoryCard/CategoryDetail/CategoryDetail.js
  9. 31
    0
      src/components/Cards/CategoryCard/CategoryDetail/CategoryDetail.styled.js
  10. 20
    0
      src/components/Cards/CategoryCard/CategoryEditButton/CategoryEditButton.js
  11. 38
    0
      src/components/Cards/CategoryCard/CategoryEditButton/CategoryEditButton.styled.js
  12. 20
    0
      src/components/Cards/CategoryCard/CategoryRemoveButton/CategoryRemoveButton.js
  13. 38
    0
      src/components/Cards/CategoryCard/CategoryRemoveButton/CategoryRemoveButton.styled.js
  14. 3
    1
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js
  15. 2
    2
      src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js
  16. 42
    28
      src/components/MarketPlace/Header/Header.js
  17. 6
    0
      src/components/MarketPlace/Header/Header.styled.js
  18. 17
    4
      src/components/MarketPlace/Offers/Offers.js
  19. 14
    13
      src/components/TextFields/SearchField/SearchField.js
  20. 5
    6
      src/components/TextFields/SearchField/SearchField.styled.js
  21. 1
    0
      src/constants/pages.js
  22. 7
    0
      src/i18n/resources/rs.js
  23. 44
    0
      src/pages/AdminCategoriesPage/AdminCategoriesPage.js
  24. 15
    0
      src/pages/AdminCategoriesPage/AdminCategoriesPage.styled.js
  25. 11
    0
      src/util/helpers/colorHelper.js
  26. 3
    1
      src/util/helpers/routeHelpers.js

+ 3
- 0
src/AppRoutes.js Voir le fichier

@@ -24,6 +24,7 @@ import {
ABOUT_PAGE,
ADMIN_HOME_PAGE,
ADMIN_USERS_PAGE,
ADMIN_CATEGORIES_PAGE,
// POLICY_PRIVACY_PAGE,
} from "./constants/pages";
import LoginPage from "./pages/LoginPage/LoginPage";
@@ -48,6 +49,7 @@ import AboutPage from "./pages/About/AboutPage";
import AuthRoute from "./components/Router/AuthRoute";
import AdminHomePage from "./pages/AdminHomePage/AdminHomePage";
import AdminUsersPage from "./pages/AdminUsersPage/AdminUsersPage";
import AdminCategoriesPage from "./pages/AdminCategoriesPage/AdminCategoriesPage";
// import PrivacyPolicyPage from "./pages/PrivacyPolicy/PrivacyPolicyPage";

const AppRoutes = () => {
@@ -58,6 +60,7 @@ const AppRoutes = () => {
<AuthRoute exact path={ADMIN_LOGIN_PAGE} component={AdminLoginPage} />
<Route path={ADMIN_HOME_PAGE} component={AdminHomePage} />
<Route path={ADMIN_USERS_PAGE} component={AdminUsersPage} />
<Route path={ADMIN_CATEGORIES_PAGE} component={AdminCategoriesPage} />
<Route path={NOT_FOUND_PAGE} component={NotFoundPage} />
<Route path={ERROR_PAGE} component={ErrorPage} />
<AuthRoute

+ 49
- 0
src/components/Cards/CategoryCard/CategoryCard.js Voir le fichier

@@ -0,0 +1,49 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryCardContainer,
CategoryCardLeftContainer,
CategoryCardRightContainer,
} from "./CategoryCard.styled";
import CategoryCardName from "./CategoryCardName/CategoryCardName";
import CategoryDetail from "./CategoryDetail/CategoryDetail";
import CategoryCheckButton from "./CategoryCheckButton/CategoryCheckButton";
import CategoryEditButton from "./CategoryEditButton/CategoryEditButton";
import CategoryRemoveButton from "./CategoryRemoveButton/CategoryRemoveButton";
import { useTranslation } from "react-i18next";

const CategoryCard = (props) => {
const { t } = useTranslation();
return (
<CategoryCardContainer>
<CategoryCardLeftContainer>
<CategoryCardName categoryName={props?.category?.name} />
<CategoryDetail
label={t("admin.categories.noOfOffers")}
value={props?.category?.offerCount}
/>
{!props.hideSecondLabel && (
<CategoryDetail
label={props?.secondLabel}
value={props?.category?.subcategories?.length}
/>
)}
</CategoryCardLeftContainer>
<CategoryCardRightContainer>
<CategoryRemoveButton />
<CategoryEditButton />
{!props.hideCheckButton && <CategoryCheckButton />}
</CategoryCardRightContainer>
</CategoryCardContainer>
);
};

CategoryCard.propTypes = {
children: PropTypes.node,
category: PropTypes.object,
hideCheckButton: PropTypes.bool,
secondLabel: PropTypes.string,
hideSecondLabel: PropTypes.bool,
};

export default CategoryCard;

+ 22
- 0
src/components/Cards/CategoryCard/CategoryCard.styled.js Voir le fichier

@@ -0,0 +1,22 @@
import { Box } from "@mui/material";
import styled from "styled-components";

export const CategoryCardContainer = styled(Box)`
background: white;
height: 84px;
width: calc(100% - 10px);
margin: 5px;
margin-top: 13px;
margin-bottom: 13px;
display: flex;
flex-direction: row;
justify-content: space-between;
`;
export const CategoryCardLeftContainer = styled(Box)`
display: flex;
flex-direction: row;
`;
export const CategoryCardRightContainer = styled(Box)`
display: flex;
flex-direction: row;
`;

+ 21
- 0
src/components/Cards/CategoryCard/CategoryCardName/CategoryCardName.js Voir le fichier

@@ -0,0 +1,21 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryCardNameContainer,
CategoryCardNameText,
} from "./CategoryCardName.styled";

const CategoryCardName = (props) => {
return (
<CategoryCardNameContainer>
<CategoryCardNameText>{props.categoryName}</CategoryCardNameText>
</CategoryCardNameContainer>
);
};

CategoryCardName.propTypes = {
children: PropTypes.node,
categoryName: PropTypes.string,
};

export default CategoryCardName;

+ 17
- 0
src/components/Cards/CategoryCard/CategoryCardName/CategoryCardName.styled.js Voir le fichier

@@ -0,0 +1,17 @@
import { Box, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";

export const CategoryCardNameContainer = styled(Box)`
padding: 18px;
min-width: 234px;
`;
export const CategoryCardNameText = styled(Typography)`
font-family: ${selectedTheme.fonts.textFont};
font-weight: 700;
font-size: 16px;
line-height: 21px;
padding-top: 12px;
color: ${selectedTheme.colors.primaryPurple};
cursor: pointer;
`;

+ 25
- 0
src/components/Cards/CategoryCard/CategoryCheckButton/CategoryCheckButton.js Voir le fichier

@@ -0,0 +1,25 @@
import React from "react";
import PropTypes from "prop-types";
import selectedTheme from "../../../../themes";
import { CheckButton } from "./CategoryCheckButton.styled";
import { useTranslation } from "react-i18next";

const CategoryCheckButton = () => {
const { t } = useTranslation();
return (
<CheckButton
variant={"outlined"}
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={selectedTheme.colors.primaryPurple}
style={{ fontWeight: "600" }}
>
{t("admin.categories.checkCategory")}
</CheckButton>
);
};

CategoryCheckButton.propTypes = {
category: PropTypes.any,
};

export default CategoryCheckButton;

+ 17
- 0
src/components/Cards/CategoryCard/CategoryCheckButton/CategoryCheckButton.styled.js Voir le fichier

@@ -0,0 +1,17 @@
import styled from "styled-components";
import selectedTheme from "../../../../themes";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";

export const CheckButton = styled(PrimaryButton)`
width: 224px;
height: 48px;
margin-top: 9px;
margin-right: 9px;
& button:hover {
background-color: ${selectedTheme.colors.primaryPurple} !important;
color: white !important;
}
@media (max-width: 850px) {
display: none;
}
`;

+ 23
- 0
src/components/Cards/CategoryCard/CategoryDetail/CategoryDetail.js Voir le fichier

@@ -0,0 +1,23 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryDetailContainer,
CategoryDetailLabel,
CategoryDetailValue,
} from "./CategoryDetail.styled";

const CategoryDetail = (props) => {
return (
<CategoryDetailContainer>
<CategoryDetailLabel>{props.label}</CategoryDetailLabel>
<CategoryDetailValue>{props.value}</CategoryDetailValue>
</CategoryDetailContainer>
);
};

CategoryDetail.propTypes = {
label: PropTypes.string,
value: PropTypes.string,
};

export default CategoryDetail;

+ 31
- 0
src/components/Cards/CategoryCard/CategoryDetail/CategoryDetail.styled.js Voir le fichier

@@ -0,0 +1,31 @@
import { Box, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";
import { hexToRGB } from "../../../../util/helpers/colorHelper";

export const CategoryDetailContainer = styled(Box)`
/* display: flex;
flex-direction: row; */
margin-top: 20px;
margin-bottom: 20px;
min-width: 150px;
text-align: center;
border-left: 1px solid ${hexToRGB(selectedTheme.colors.primaryText, 0.13)};

`;
export const CategoryDetailLabel = styled(Typography)`
font-family: ${selectedTheme.fonts.textFont};
color: ${selectedTheme.colors.primaryText};
font-size: 12px;
letter-spacing: 0.01rem;
padding-top: 14px;
padding-right: 3px;
`;
export const CategoryDetailValue = styled(Typography)`
font-family: ${selectedTheme.fonts.textFont};
font-weight: 700;
font-size: 16px;
line-height: 21px;
padding-top: 11px;
color: ${selectedTheme.colors.primaryPurple};
`;

+ 20
- 0
src/components/Cards/CategoryCard/CategoryEditButton/CategoryEditButton.js Voir le fichier

@@ -0,0 +1,20 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryEditButtonContainer,
EditIcon,
} from "./CategoryEditButton.styled";

const CategoryEditButton = () => {
return (
<CategoryEditButtonContainer>
<EditIcon />
</CategoryEditButtonContainer>
);
};

CategoryEditButton.propTypes = {
category: PropTypes.any,
};

export default CategoryEditButton;

+ 38
- 0
src/components/Cards/CategoryCard/CategoryEditButton/CategoryEditButton.styled.js Voir le fichier

@@ -0,0 +1,38 @@
import styled from "styled-components";
import selectedTheme from "../../../../themes";
import { IconButton } from "../../../Buttons/IconButton/IconButton";
import { ReactComponent as Edit } from "../../../../assets/images/svg/edit.svg";

export const CategoryEditButtonContainer = styled(IconButton)`
width: 40px;
height: 40px;
background-color: ${selectedTheme.colors.primaryIconBackgroundColor};
border-radius: 100%;
position: relative;
top: 22px;
margin-right: 18px;
padding-top: 2px;
text-align: center;
@media (max-width: 600px) {
width: 30px;
height: 30px;
top: 16px;
right: 16px;
padding: 0;
${(props) =>
props.vertical &&
`
display: none;
`}
& button svg {
width: 16px;
height: 16px;
position: relative;
top: -3px;
left: -3.5px;
}
}
`;
export const EditIcon = styled(Edit)`
`

+ 20
- 0
src/components/Cards/CategoryCard/CategoryRemoveButton/CategoryRemoveButton.js Voir le fichier

@@ -0,0 +1,20 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryRemoveButtonContainer,
RemoveIcon,
} from "./CategoryRemoveButton.styled";

const CategoryRemoveButton = () => {
return (
<CategoryRemoveButtonContainer>
<RemoveIcon />
</CategoryRemoveButtonContainer>
);
};

CategoryRemoveButton.propTypes = {
category: PropTypes.any,
};

export default CategoryRemoveButton;

+ 38
- 0
src/components/Cards/CategoryCard/CategoryRemoveButton/CategoryRemoveButton.styled.js Voir le fichier

@@ -0,0 +1,38 @@
import styled from "styled-components";
import selectedTheme from "../../../../themes";
import { IconButton } from "../../../Buttons/IconButton/IconButton";
import { ReactComponent as Remove } from "../../../../assets/images/svg/trash.svg";

export const CategoryRemoveButtonContainer = styled(IconButton)`
width: 40px;
height: 40px;
background-color: ${selectedTheme.colors.primaryIconBackgroundColor};
border-radius: 100%;
position: relative;
top: 22px;
margin-right: 18px;
padding-top: 2px;
text-align: center;
@media (max-width: 600px) {
width: 30px;
height: 30px;
top: 16px;
right: 16px;
padding: 0;
${(props) =>
props.vertical &&
`
display: none;
`}
& button svg {
width: 16px;
height: 16px;
position: relative;
top: -3px;
left: -3.5px;
}
}
`;
export const RemoveIcon = styled(Remove)`
`

+ 3
- 1
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.js Voir le fichier

@@ -28,7 +28,7 @@ const BigProfileCard = (props) => {
const blockUser = () => {};
return (
<>
<ProfileCardContainer>
<ProfileCardContainer halfwidth={props.halfwidth}>
<ProfileCardWrapper variant="outlined">
<EditButton onClick={() => setEditProfileModal(true)}>
<EditIcon />
@@ -46,6 +46,7 @@ const BigProfileCard = (props) => {
<ProfileContact profile={props.profile} isAdmin />
</ProfileInfoContainer>
<CheckButton
halfwidth={props.halfwidth}
variant={"outlined"}
buttoncolor={selectedTheme.colors.primaryPurple}
textcolor={selectedTheme.colors.primaryPurple}
@@ -70,6 +71,7 @@ const BigProfileCard = (props) => {

BigProfileCard.propTypes = {
profile: PropTypes.any,
halfwidth: PropTypes.bool,
};

export default BigProfileCard;

+ 2
- 2
src/components/Cards/ProfileCard/BigProfileCard/BigProfileCard.styled.js Voir le fichier

@@ -12,7 +12,7 @@ import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
// import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";

export const ProfileCardContainer = styled(Box)`
width: 100%;
width: ${(props) => (props.halfwidth ? `49%` : `100%`)};
box-sizing: border-box;
max-height: 184px;
margin-top: 34px;
@@ -30,7 +30,6 @@ export const EditIcon = styled(Edit)`
}
`;


export const MessageButton = styled(IconButton)`
width: 40px;
height: 40px;
@@ -92,6 +91,7 @@ export const CheckButton = styled(PrimaryButton)`
position: absolute;
bottom: 25px;
right: 9px;
display: ${(props) => (props.halfwidth ? `none` : `block`)};
& button:hover {
background-color: ${selectedTheme.colors.primaryPurple} !important;
color: white !important;

+ 42
- 28
src/components/MarketPlace/Header/Header.js Voir le fichier

@@ -4,6 +4,7 @@ import {
ButtonContainer,
// ButtonContainer,
CategoryHeaderIcon,
CategoryIcon,
HeaderAltLocation,
HeaderButton,
HeaderButtons,
@@ -89,6 +90,7 @@ const Header = (props) => {
<>
<SkeletonHeader skeleton={props?.skeleton} myOffers={props?.myOffers} />
<HeaderWrapperContainer
className={props.className}
skeleton={props?.skeleton}
isAdmin={props?.isAdmin}
>
@@ -129,10 +131,18 @@ const Header = (props) => {
<>
{!isMobile ? (
<HeaderTitleContainer>
{props.users ? <UserIcon /> : <SwapsHeaderIcon />}
{props.users ? (
<UserIcon />
) : props.categories ? (
<CategoryIcon />
) : (
<SwapsHeaderIcon />
)}
<HeaderTitleText>
{props.users
? t("admin.users.headerTitle")
: props.categories
? t("admin.categories.headerTitle")
: t("header.myOffers")}
</HeaderTitleText>
</HeaderTitleContainer>
@@ -149,33 +159,35 @@ const Header = (props) => {
{/* ^^^^^^ */}

<HeaderOptions>
<HeaderButtons>
{/* Setting display of offer cards to full width */}
<HeaderButton
iconColor={
props?.isGrid
? selectedTheme.colors.iconStrokeColor
: selectedTheme.colors.primaryPurple
}
onClick={() => props?.setIsGrid(false)}
>
<GridLine />
</HeaderButton>
{/* ^^^^^^ */}
{!props.hideGrid && (
<HeaderButtons>
{/* Setting display of offer cards to full width */}
<HeaderButton
iconColor={
props?.isGrid
? selectedTheme.colors.iconStrokeColor
: selectedTheme.colors.primaryPurple
}
onClick={() => props?.setIsGrid(false)}
>
<GridLine />
</HeaderButton>
{/* ^^^^^^ */}

{/* Setting display of offer cards to half width (Grid) */}
<HeaderButton
iconColor={
props?.isGrid
? selectedTheme.colors.primaryPurple
: selectedTheme.colors.iconStrokeColor
}
onClick={() => props?.setIsGrid(true)}
>
<GridSquare />
</HeaderButton>
{/* ^^^^^^ */}
</HeaderButtons>
{/* Setting display of offer cards to half width (Grid) */}
<HeaderButton
iconColor={
props?.isGrid
? selectedTheme.colors.primaryPurple
: selectedTheme.colors.iconStrokeColor
}
onClick={() => props?.setIsGrid(true)}
>
<GridSquare />
</HeaderButton>
{/* ^^^^^^ */}
</HeaderButtons>
)}

{/* Select option to choose sorting */}
<HeaderSelect
@@ -224,12 +236,14 @@ Header.propTypes = {
setIsGrid: PropTypes.func,
isGrid: PropTypes.bool,
offers: PropTypes.any,
category: PropTypes.string,
myOffers: PropTypes.bool,
skeleton: PropTypes.bool,
sorting: PropTypes.any,
isAdmin: PropTypes.bool,
users: PropTypes.bool,
categories: PropTypes.bool,
hideGrid: PropTypes.bool,
className: PropTypes.string,
};
Header.defaultProps = {
isGrid: false,

+ 6
- 0
src/components/MarketPlace/Header/Header.styled.js Voir le fichier

@@ -7,6 +7,7 @@ import Select from "../../Select/Select";
import { ReactComponent as Swaps } from "../../../assets/images/svg/swaps.svg";
import { ReactComponent as CategoryHeader } from "../../../assets/images/svg/category-header.svg";
import { ReactComponent as User } from "../../../assets/images/svg/user.svg";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";

export const HeaderWrapperContainer = styled(Box)`
display: ${(props) => (props.skeleton ? "none" : "block")};
@@ -194,6 +195,11 @@ export const CategoryHeaderIcon = styled(CategoryHeader)`
top: 1px;
}
`;
export const CategoryIcon = styled(Category)`
position: relative;
top: 4px;
right: 2px;
`
export const PageTitleContainer = styled(Box)`
position: relative;
left: 6px;

+ 17
- 4
src/components/MarketPlace/Offers/Offers.js Voir le fichier

@@ -8,14 +8,17 @@ import { selectLatestChats } from "../../../store/selectors/chatSelectors";
import { selectUserId } from "../../../store/selectors/loginSelectors";
import { startChat } from "../../../util/helpers/chatHelper";
import OffersNotFound from "./OffersNotFound";
import HeadersMyOffers from "./HeaderMyOffers.js/HeadersMyOffers";
// import HeadersMyOffers from "./SearchBar/SearchBar";
import SkeletonOfferCard from "../../Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard";
import BigProfileCard from "../../Cards/ProfileCard/BigProfileCard/BigProfileCard";
import SearchField from "../../TextFields/SearchField/SearchField";
import { useTranslation } from "react-i18next";

const Offers = (props) => {
const chats = useSelector(selectLatestChats);
const offersRef = useRef(null);
const userId = useSelector(selectUserId);
const { t } = useTranslation();
const offers = props?.offers;
// For skeleton screen
const arrayForMapping = Array.apply(null, Array(4)).map(() => {});
@@ -40,12 +43,18 @@ const Offers = (props) => {
<FilterIcon />
</FilterContainer>
{(props?.myOffers || props?.isAdmin) && (
<HeadersMyOffers
// <HeadersMyOffers
<SearchField
searchMyOffers={offers?.search?.searchOffers}
handleSearch={offers?.apply}
isAdmin={props?.isAdmin}
offers={offers}
isUsers={props.isUsers}
placeholder={
props.isUsers
? t("admin.users.searchPlaceholder")
: t("header.searchOffers")
}
/>
)}
{offers?.allOffersToShow?.length === 0 ? (
@@ -54,7 +63,11 @@ const Offers = (props) => {
<OffersContainer ref={offersRef}>
{props.isUsers
? props.users?.map((item) => (
<BigProfileCard key={item._id} profile={item} />
<BigProfileCard
key={item._id}
profile={item}
halfwidth={props?.isGrid}
/>
))
: offers?.allOffersToShow?.map((item) => {
return (
@@ -102,7 +115,7 @@ Offers.propTypes = {

Offers.defaultProps = {
myOffers: false,
users: []
users: [],
};

export default Offers;

src/components/MarketPlace/Offers/HeaderMyOffers.js/HeadersMyOffers.js → src/components/TextFields/SearchField/SearchField.js Voir le fichier

@@ -1,13 +1,11 @@
import React, { useCallback, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import { EndIcon, SearchIcon, SearchInput } from "./HeadersMyOffers.styled";
import { useTranslation } from "react-i18next";
import useSearch from "../../../../hooks/useOffers/useSearch";
import { EndIcon, SearchIcon, SearchInput } from "./SearchField.styled";
import useSearch from "../../../hooks/useOffers/useSearch";

const HeadersMyOffers = (props) => {
const SearchField = (props) => {
const searchRef = useRef(null);
const search = useSearch(() => {});
const { t } = useTranslation();
let listener = useCallback(
(event) => {
// Event keycode 13 = ENTER keycode
@@ -39,7 +37,7 @@ const HeadersMyOffers = (props) => {
return (
<SearchInput
isAdmin={props.isAdmin}
fullWidth
fullWidth={props.fullWidth}
InputProps={{
endAdornment: (
<EndIcon size="36px">
@@ -47,25 +45,28 @@ const HeadersMyOffers = (props) => {
</EndIcon>
),
}}
placeholder={
props.isUsers
? t("admin.users.searchPlaceholder")
: t("header.searchOffers")
}
placeholder={props.placeholder}
onFocus={handleFocusSearch}
onBlur={handleBlurSearch}
ref={searchRef}
className={props.className}
/>
);
};

HeadersMyOffers.propTypes = {
SearchField.propTypes = {
children: PropTypes.node,
searchMyOffers: PropTypes.func,
handleSearch: PropTypes.func,
isAdmin: PropTypes.bool,
offers: PropTypes.any,
isUsers: PropTypes.bool,
fullWidth: PropTypes.bool,
className: PropTypes.string,
placeholder: PropTypes.string,
};
SearchField.defaultProps = {
fullWidth: true,
};

export default HeadersMyOffers;
export default SearchField;

src/components/MarketPlace/Offers/HeaderMyOffers.js/HeadersMyOffers.styled.js → src/components/TextFields/SearchField/SearchField.styled.js Voir le fichier

@@ -1,11 +1,10 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import { Icon } from "../../../Icon/Icon";
import { ReactComponent as Search } from "../../../../assets/images/svg/magnifying-glass.svg";
import selectedTheme from "../../../../themes";
import { TextField } from "../../../TextFields/TextField/TextField";
import selectedTheme from "../../../themes";
import { Icon } from "../../Icon/Icon";
import { TextField } from "../TextField/TextField";
import { ReactComponent as Search } from "../../../assets/images/svg/magnifying-glass.svg";


export const HeadersMyOffersContainer = styled(Box)``;
export const EndIcon = styled(Icon)``;
export const SearchIcon = styled(Search)`
position: relative;

+ 1
- 0
src/constants/pages.js Voir le fichier

@@ -20,3 +20,4 @@ export const PRICES_PAGE = "/prices";
export const POLICY_PRIVACY_PAGE = "/policy";
export const ADMIN_HOME_PAGE = "/admin/home";
export const ADMIN_USERS_PAGE = "/admin/users";
export const ADMIN_CATEGORIES_PAGE = "/admin/categories";

+ 7
- 0
src/i18n/resources/rs.js Voir le fichier

@@ -429,5 +429,12 @@ export default {
searchPlaceholder: "Pretražite korisnike....",
checkProfile: "Pogledaj profil"
},
categories: {
checkCategory: "Pogledaj podkategorije",
noOfOffers: "Broj objava: ",
noOfSubcategories: "Broj potkategorija: ",
headerTitle: "Kategorije",
placeholder: "Pretražite kategorije..."
}
},
};

+ 44
- 0
src/pages/AdminCategoriesPage/AdminCategoriesPage.js Voir le fichier

@@ -0,0 +1,44 @@
import React from "react";
import PropTypes from "prop-types";
import CategoryCard from "../../components/Cards/CategoryCard/CategoryCard";
import { useDispatch, useSelector } from "react-redux";
import { useEffect } from "react";
import { fetchCategories } from "../../store/actions/categories/categoriesActions";
import { selectCategories } from "../../store/selectors/categoriesSelectors";
import { useTranslation } from "react-i18next";
import {
AdminCategoriesHeader,
AdminCategoriesPageContainer,
AdminCategoriesSearchField,
} from "./AdminCategoriesPage.styled";

const AdminCategoriesPage = () => {
const { t } = useTranslation();
const dispatch = useDispatch();
const categories = useSelector(selectCategories);
useEffect(() => {
dispatch(fetchCategories());
}, []);
return (
<AdminCategoriesPageContainer>
<AdminCategoriesSearchField
isAdmin
placeholder={t("admin.categories.placeholder")}
/>
<AdminCategoriesHeader myOffers categories hideGrid isAdmin />
{categories.map((category) => (
<CategoryCard
key={category._id}
category={category}
secondLabel={t("admin.categories.noOfSubcategories")}
/>
))}
</AdminCategoriesPageContainer>
);
};

AdminCategoriesPage.propTypes = {
children: PropTypes.node,
};

export default AdminCategoriesPage;

+ 15
- 0
src/pages/AdminCategoriesPage/AdminCategoriesPage.styled.js Voir le fichier

@@ -0,0 +1,15 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import Header from "../../components/MarketPlace/Header/Header";
import SearchField from "../../components/TextFields/SearchField/SearchField";

export const AdminCategoriesPageContainer = styled(Box)`
padding: 60px;
`;
export const AdminCategoriesHeader = styled(Header)`
/* top: 40px; */
top: 0;
`
export const AdminCategoriesSearchField = styled(SearchField)`
top: -15px;
`

+ 11
- 0
src/util/helpers/colorHelper.js Voir le fichier

@@ -0,0 +1,11 @@
export const hexToRGB = (hex, opacity) => {
var r = parseInt(hex.slice(1, 3), 16),
g = parseInt(hex.slice(3, 5), 16),
b = parseInt(hex.slice(5, 7), 16);

if (opacity) {
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
} else {
return `rgb(${r}, ${g}, ${b})`;
}
}

+ 3
- 1
src/util/helpers/routeHelpers.js Voir le fichier

@@ -1,4 +1,5 @@
import {
ADMIN_CATEGORIES_PAGE,
ADMIN_HOME_PAGE,
ADMIN_LOGIN_PAGE,
ADMIN_USERS_PAGE,
@@ -46,7 +47,8 @@ export const isAdminRoute = () => {
if (
routeMatches(ADMIN_LOGIN_PAGE) ||
routeMatches(ADMIN_HOME_PAGE) ||
routeMatches(ADMIN_USERS_PAGE)
routeMatches(ADMIN_USERS_PAGE) ||
routeMatches(ADMIN_CATEGORIES_PAGE)
)
return true;
return false;

Chargement…
Annuler
Enregistrer