Merge branch 'dev' of penahub.gitlab.yandexcloud.net:frontend/marketplace into dev
This commit is contained in:
commit
392387f1d3
3
src/assets/Icons/cross.svg
Normal file
3
src/assets/Icons/cross.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" stroke="black" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.400391 0.399902L19.6004 19.5999M0.400391 19.5999L19.6004 0.399902" />
|
||||
</svg>
|
After Width: | Height: | Size: 200 B |
@ -1,14 +1,29 @@
|
||||
import { useState } from "react";
|
||||
import { Box, SvgIcon, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import {
|
||||
Box,
|
||||
SvgIcon,
|
||||
IconButton,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
import { removeTariffFromCart } from "@root/stores/user";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { ServiceCartData, getMessageFromFetchError } from "@frontend/kitui";
|
||||
import ExpandIcon from "@components/icons/ExpandIcon";
|
||||
|
||||
import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
|
||||
|
||||
const name: Record<string, string> = { templategen: "Шаблонизатор", squiz: "Опросник", reducer: "Скоращатель ссылок" };
|
||||
import type { MouseEvent } from "react";
|
||||
|
||||
const name: Record<string, string> = {
|
||||
templategen: "Шаблонизатор",
|
||||
squiz: "Опросник",
|
||||
reducer: "Скоращатель ссылок",
|
||||
};
|
||||
|
||||
interface Props {
|
||||
serviceData: ServiceCartData;
|
||||
@ -21,19 +36,36 @@ export default function CustomWrapperDrawer({ serviceData }: Props) {
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
||||
|
||||
function handleItemDeleteClick(tariffId: string) {
|
||||
removeTariffFromCart(tariffId).then(() => {
|
||||
removeTariffFromCart(tariffId)
|
||||
.then(() => {
|
||||
enqueueSnackbar("Тариф удален");
|
||||
}).catch(error => {
|
||||
})
|
||||
.catch((error) => {
|
||||
const message = getMessageFromFetchError(error);
|
||||
if (message) enqueueSnackbar(message);
|
||||
});
|
||||
}
|
||||
|
||||
const deleteService = async (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
|
||||
setIsExpanded(false);
|
||||
|
||||
for (const { tariffId } of serviceData.privileges) {
|
||||
try {
|
||||
await removeTariffFromCart(tariffId);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
enqueueSnackbar("Тарифы удален");
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
overflow: "hidden",
|
||||
borderRadius: "12px",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
@ -56,13 +88,21 @@ export default function CustomWrapperDrawer({ serviceData }: Props) {
|
||||
onClick={() => setIsExpanded((prev) => !prev)}
|
||||
sx={{
|
||||
height: "72px",
|
||||
|
||||
display: "flex",
|
||||
gap: "10px",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
cursor: "pointer",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<ExpandIcon isExpanded={isExpanded} />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
@ -75,7 +115,6 @@ export default function CustomWrapperDrawer({ serviceData }: Props) {
|
||||
>
|
||||
{name[serviceData.serviceKey]}
|
||||
</Typography>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@ -85,23 +124,35 @@ export default function CustomWrapperDrawer({ serviceData }: Props) {
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{ pr: "11px", color: theme.palette.grey3.main, fontSize: upSm ? "20px" : "16px", fontWeight: 500 }}
|
||||
sx={{
|
||||
color: theme.palette.grey3.main,
|
||||
fontSize: upSm ? "20px" : "16px",
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
{currencyFormatter.format(serviceData.price / 100)}
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
paddingLeft: upSm ? "24px" : 0,
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
></Box>
|
||||
</Box>
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={deleteService}
|
||||
sx={{
|
||||
padding: "3px",
|
||||
height: "30px",
|
||||
width: "30px",
|
||||
}}
|
||||
>
|
||||
<CrossIcon
|
||||
style={{
|
||||
height: "24px",
|
||||
width: "24px",
|
||||
stroke: "#7E2AEA",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</Box>
|
||||
{isExpanded &&
|
||||
serviceData.privileges.map(privilege => (
|
||||
serviceData.privileges.map((privilege) => (
|
||||
<Box
|
||||
key={privilege.tariffId + privilege.privilegeId}
|
||||
sx={{
|
||||
@ -142,9 +193,12 @@ export default function CustomWrapperDrawer({ serviceData }: Props) {
|
||||
>
|
||||
{currencyFormatter.format(privilege.price / 100)}
|
||||
</Typography>
|
||||
|
||||
<SvgIcon
|
||||
sx={{ cursor: "pointer", color: "#7E2AEA" }}
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
width: "30px",
|
||||
color: "#7E2AEA",
|
||||
}}
|
||||
onClick={() => handleItemDeleteClick(privilege.tariffId)}
|
||||
component={ClearIcon}
|
||||
/>
|
||||
|
@ -6,11 +6,9 @@ import {
|
||||
useTheme,
|
||||
Box,
|
||||
IconButton,
|
||||
SvgIcon,
|
||||
Badge,
|
||||
} from "@mui/material";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import ClearIcon from "@mui/icons-material/Clear";
|
||||
import { useTickets } from "@frontend/kitui";
|
||||
import SectionWrapper from "./SectionWrapper";
|
||||
import CustomWrapperDrawer from "./CustomWrapperDrawer";
|
||||
@ -34,6 +32,7 @@ import {
|
||||
|
||||
import { ReactComponent as BellIcon } from "@root/assets/Icons/bell.svg";
|
||||
import { ReactComponent as CartIcon } from "@root/assets/Icons/cart.svg";
|
||||
import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
|
||||
|
||||
export default function Drawers() {
|
||||
const [openNotificationsModal, setOpenNotificationsModal] =
|
||||
@ -227,15 +226,22 @@ export default function Drawers() {
|
||||
Корзина
|
||||
</Typography>
|
||||
<IconButton onClick={closeCartDrawer} sx={{ p: 0 }}>
|
||||
<SvgIcon component={ClearIcon} />
|
||||
<CrossIcon />
|
||||
</IconButton>
|
||||
</Box>
|
||||
<Box sx={{ pl: "20px", pr: "20px" }}>
|
||||
{cart.services.map((serviceData) => (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<CustomWrapperDrawer
|
||||
key={serviceData.serviceKey}
|
||||
serviceData={serviceData}
|
||||
/>
|
||||
</Box>
|
||||
))}
|
||||
<Box
|
||||
sx={{
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { Box, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import {
|
||||
Box,
|
||||
IconButton,
|
||||
Typography,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
import SectionWrapper from "@components/SectionWrapper";
|
||||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||||
import TotalPrice from "@components/TotalPrice";
|
||||
@ -6,16 +12,25 @@ import CustomWrapper from "./CustomWrapper";
|
||||
import { useCart } from "@root/utils/hooks/useCart";
|
||||
import { useCustomTariffsStore } from "@root/stores/customTariffs";
|
||||
|
||||
|
||||
export default function Basket() {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const cart = useCart();
|
||||
const summaryPriceBeforeDiscountsMap = useCustomTariffsStore(state => state.summaryPriceBeforeDiscountsMap);
|
||||
const summaryPriceAfterDiscountsMap = useCustomTariffsStore(state => state.summaryPriceAfterDiscountsMap);
|
||||
const summaryPriceBeforeDiscountsMap = useCustomTariffsStore(
|
||||
(state) => state.summaryPriceBeforeDiscountsMap
|
||||
);
|
||||
const summaryPriceAfterDiscountsMap = useCustomTariffsStore(
|
||||
(state) => state.summaryPriceAfterDiscountsMap
|
||||
);
|
||||
|
||||
const basePrice = Object.values(summaryPriceBeforeDiscountsMap).reduce((a, e) => a + e, 0);
|
||||
const discountedPrice = Object.values(summaryPriceAfterDiscountsMap).reduce((a, e) => a + e, 0);
|
||||
const basePrice = Object.values(summaryPriceBeforeDiscountsMap).reduce(
|
||||
(a, e) => a + e,
|
||||
0
|
||||
);
|
||||
const discountedPrice = Object.values(summaryPriceAfterDiscountsMap).reduce(
|
||||
(a, e) => a + e,
|
||||
0
|
||||
);
|
||||
|
||||
const totalPriceBeforeDiscounts = cart.priceBeforeDiscounts + basePrice;
|
||||
const totalPriceAfterDiscounts = cart.priceAfterDiscounts + discountedPrice;
|
||||
@ -37,7 +52,9 @@ export default function Basket() {
|
||||
}}
|
||||
>
|
||||
{!upMd && (
|
||||
<IconButton sx={{ p: 0, height: "28px", width: "28px", color: "black" }}>
|
||||
<IconButton
|
||||
sx={{ p: 0, height: "28px", width: "28px", color: "black" }}
|
||||
>
|
||||
<ArrowBackIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
@ -45,17 +62,22 @@ export default function Basket() {
|
||||
Корзина
|
||||
</Typography>
|
||||
</Box>
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
mt: upMd ? "27px" : "10px",
|
||||
}}>
|
||||
{cart.services.map(serviceData =>
|
||||
}}
|
||||
>
|
||||
{cart.services.map((serviceData) => (
|
||||
<CustomWrapper
|
||||
key={serviceData.serviceKey}
|
||||
serviceData={serviceData}
|
||||
/>
|
||||
)}
|
||||
))}
|
||||
</Box>
|
||||
<TotalPrice priceBeforeDiscounts={totalPriceBeforeDiscounts} priceAfterDiscounts={totalPriceAfterDiscounts} />
|
||||
<TotalPrice
|
||||
priceBeforeDiscounts={totalPriceBeforeDiscounts}
|
||||
priceAfterDiscounts={totalPriceAfterDiscounts}
|
||||
/>
|
||||
</SectionWrapper>
|
||||
);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import {
|
||||
Box,
|
||||
SvgIcon,
|
||||
Typography,
|
||||
IconButton,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} from "@mui/material";
|
||||
@ -14,6 +15,10 @@ import { removeTariffFromCart } from "@root/stores/user";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { ServiceCartData, getMessageFromFetchError } from "@frontend/kitui";
|
||||
|
||||
import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
|
||||
|
||||
import type { MouseEvent } from "react";
|
||||
|
||||
const name: Record<string, string> = {
|
||||
templategen: "Шаблонизатор",
|
||||
squiz: "Опросник",
|
||||
@ -41,6 +46,20 @@ export default function CustomWrapper({ serviceData }: Props) {
|
||||
});
|
||||
}
|
||||
|
||||
const deleteService = async (event: MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation();
|
||||
|
||||
setIsExpanded(false);
|
||||
|
||||
for (const { tariffId } of serviceData.privileges) {
|
||||
try {
|
||||
await removeTariffFromCart(tariffId);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
enqueueSnackbar("Тарифы удален");
|
||||
};
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@ -70,26 +89,39 @@ export default function CustomWrapper({ serviceData }: Props) {
|
||||
sx={{
|
||||
height: "72px",
|
||||
px: "20px",
|
||||
|
||||
display: "flex",
|
||||
gap: "15px",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
cursor: "pointer",
|
||||
userSelect: "none",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "50px",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<ExpandIcon isExpanded={isExpanded} />
|
||||
</Box>
|
||||
<Typography
|
||||
sx={{
|
||||
width: "100%",
|
||||
fontSize: upMd ? "20px" : "16px",
|
||||
lineHeight: upMd ? undefined : "19px",
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.secondary,
|
||||
px: 0,
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
}}
|
||||
>
|
||||
{name[serviceData.serviceKey]}
|
||||
</Typography>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
@ -108,19 +140,13 @@ export default function CustomWrapper({ serviceData }: Props) {
|
||||
>
|
||||
{currencyFormatter.format(serviceData.price / 100)}
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
borderLeft: upSm ? "1px solid #9A9AAF" : "none",
|
||||
paddingLeft: upSm ? "24px" : 0,
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
}}
|
||||
</Box>
|
||||
<IconButton
|
||||
onClick={deleteService}
|
||||
sx={{ padding: 0, height: "22px", width: "22px" }}
|
||||
>
|
||||
<ExpandIcon isExpanded={isExpanded} />
|
||||
</Box>
|
||||
</Box>
|
||||
<CrossIcon style={{ height: "22 px", width: "22px" }} />
|
||||
</IconButton>
|
||||
</Box>
|
||||
{isExpanded &&
|
||||
serviceData.privileges.map((privilege) => (
|
||||
@ -143,17 +169,14 @@ export default function CustomWrapper({ serviceData }: Props) {
|
||||
fontSize: upMd ? undefined : "16px",
|
||||
lineHeight: upMd ? undefined : "19px",
|
||||
color: theme.palette.grey3.main,
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{privilege.description}
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
gap: "10px",
|
||||
alignItems: "center",
|
||||
width: upSm ? "195px" : "123px",
|
||||
width: upSm ? "140px" : "123px",
|
||||
marginRight: upSm ? "65px" : 0,
|
||||
}}
|
||||
>
|
||||
@ -166,27 +189,18 @@ export default function CustomWrapper({ serviceData }: Props) {
|
||||
>
|
||||
{currencyFormatter.format(privilege.price / 100)}
|
||||
</Typography>
|
||||
{upSm ? (
|
||||
<Typography
|
||||
component="div"
|
||||
onClick={() => handleItemDeleteClick(privilege.tariffId)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
color: theme.palette.text.secondary,
|
||||
borderBottom: `1px solid ${theme.palette.text.secondary}`,
|
||||
width: "max-content",
|
||||
lineHeight: "19px",
|
||||
cursor: "pointer",
|
||||
width: "35px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
Удалить
|
||||
</Typography>
|
||||
) : (
|
||||
<SvgIcon
|
||||
onClick={() => handleItemDeleteClick(privilege.tariffId)}
|
||||
component={ClearIcon}
|
||||
sx={{ fill: "#7E2AEA" }}
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<SvgIcon component={ClearIcon} sx={{ fill: "#7E2AEA" }} />
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
|
Loading…
Reference in New Issue
Block a user