cart & checkout: apply validation based on required inputs in each service & add phone input in checkout page
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { PlusOutlined } from "@ant-design/icons";
|
||||
import { Card, Divider, Space } from "antd";
|
||||
import { Card, Divider, Form, Space } from "antd";
|
||||
import ArabicPrice from "components/ArabicPrice";
|
||||
import CartActionsButtons from "components/CartActionsButtons/CartActionsButtons.tsx";
|
||||
import ImageWithFallback from "components/ImageWithFallback";
|
||||
@@ -35,7 +35,9 @@ interface CartMobileTabletLayoutProps {
|
||||
form: FormInstance;
|
||||
}
|
||||
|
||||
export default function CartMobileTabletLayout({ form }: CartMobileTabletLayoutProps) {
|
||||
export default function CartMobileTabletLayout({
|
||||
form,
|
||||
}: CartMobileTabletLayoutProps) {
|
||||
const { t } = useTranslation();
|
||||
const { items, collectionMethod } = useAppSelector(selectCart);
|
||||
const { id } = useParams();
|
||||
@@ -235,24 +237,30 @@ export default function CartMobileTabletLayout({ form }: CartMobileTabletLayoutP
|
||||
{/* Collection Method */}
|
||||
{orderType === "pickup" && (
|
||||
<ProInputCard title={t("cart.collectionMethod")}>
|
||||
<ProRatioGroups
|
||||
options={[
|
||||
{ label: t("cart.Cash"), value: "cod", price: "" },
|
||||
{
|
||||
label: t("cart.e-payment"),
|
||||
value: "paymentgateway",
|
||||
price: "",
|
||||
},
|
||||
]}
|
||||
value={collectionMethod}
|
||||
onRatioClick={(value) => {
|
||||
if (value === "cod") {
|
||||
updateCollectionMethod(value);
|
||||
} else {
|
||||
updateCollectionMethod(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Form.Item
|
||||
name="collectionMethod"
|
||||
required
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<ProRatioGroups
|
||||
options={[
|
||||
{ label: t("cart.Cash"), value: "cod", price: "" },
|
||||
{
|
||||
label: t("cart.e-payment"),
|
||||
value: "paymentgateway",
|
||||
price: "",
|
||||
},
|
||||
]}
|
||||
value={collectionMethod}
|
||||
onRatioClick={(value) => {
|
||||
if (value === "cod") {
|
||||
updateCollectionMethod(value);
|
||||
} else {
|
||||
updateCollectionMethod(value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</ProInputCard>
|
||||
)}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "ThemeConstants.ts";
|
||||
import { Button, FormInstance } from "antd";
|
||||
import { Button, FormInstance, message } from "antd";
|
||||
import { selectCart } from "features/order/orderSlice.ts";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
@@ -17,15 +17,15 @@ export default function CartFooter({ form }: CartFooterProps) {
|
||||
const orderType = localStorage.getItem("orderType");
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Check if checkout should be disabled
|
||||
const isCheckoutDisabled = items.length === 0;
|
||||
|
||||
const handleCheckoutClick = async () => {
|
||||
try {
|
||||
await form.validateFields();
|
||||
navigate(`/${id}/checkout`);
|
||||
} catch (error) {
|
||||
console.log("Form validation failed:", error);
|
||||
if (items.length === 0) message.warning(t("cart.pleaseAddItemsToCart"));
|
||||
else {
|
||||
try {
|
||||
await form.validateFields();
|
||||
navigate(`/${id}/checkout`);
|
||||
} catch (error) {
|
||||
console.log("Form validation failed:", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -60,7 +60,6 @@ export default function CartFooter({ form }: CartFooterProps) {
|
||||
color: "white",
|
||||
width: "100%",
|
||||
}}
|
||||
disabled={isCheckoutDisabled}
|
||||
onClick={handleCheckoutClick}
|
||||
>
|
||||
{t("cart.checkout")}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Form } from "antd";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard.tsx";
|
||||
import ProRatioGroups from "components/ProRatioGroups/ProRatioGroups.tsx";
|
||||
import { selectCart, updateEstimateTime } from "features/order/orderSlice.ts";
|
||||
@@ -27,22 +28,24 @@ export default function TimeEstimateCard() {
|
||||
return (
|
||||
<>
|
||||
<ProInputCard title={t("cart.estimateTime")}>
|
||||
<ProRatioGroups
|
||||
options={[
|
||||
{ label: t("cart.now"), value: "now", price: "" },
|
||||
{ label: t("cart.later"), value: "later", price: "" },
|
||||
]}
|
||||
value={estimateWay}
|
||||
onRatioClick={(value) => {
|
||||
if (value === "now") {
|
||||
setEstimateWay(value);
|
||||
handleEstimateTimeSave(new Date(), "now");
|
||||
} else {
|
||||
setEstimateWay(value);
|
||||
setIsEstimateTimeOpen(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Form.Item name="estimateWay" required rules={[{ required: true }]}>
|
||||
<ProRatioGroups
|
||||
options={[
|
||||
{ label: t("cart.now"), value: "now", price: "" },
|
||||
{ label: t("cart.later"), value: "later", price: "" },
|
||||
]}
|
||||
value={estimateWay}
|
||||
onRatioClick={(value) => {
|
||||
if (value === "now") {
|
||||
setEstimateWay(value);
|
||||
handleEstimateTimeSave(new Date(), "now");
|
||||
} else {
|
||||
setEstimateWay(value);
|
||||
setIsEstimateTimeOpen(true);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</ProInputCard>
|
||||
{isDesktop ? (
|
||||
<Dialog
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
.youMightAlsoLikeTitle {
|
||||
margin: 0 16px 16px 16px;
|
||||
}
|
||||
|
||||
.youMightAlsoLikeContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@@ -66,6 +70,9 @@
|
||||
.youMightAlsoLikeContainer {
|
||||
height: 200px !important;
|
||||
}
|
||||
.youMightAlsoLikeTitle {
|
||||
margin: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hover effects for devices that support hover */
|
||||
|
||||
@@ -117,7 +117,7 @@ export default function YouMightAlsoLike() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ margin: 16 }}>
|
||||
<div className={styles.youMightAlsoLikeTitle} >
|
||||
<ProText
|
||||
strong
|
||||
style={{
|
||||
|
||||
Reference in New Issue
Block a user