Skip to content

(Online shop): online ordering only release #407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 58 additions & 34 deletions src/app/[locale]/seller/sale-items/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Link from 'next/link';

import React, { useEffect, useState, useContext, useRef } from 'react';

import ConfirmDialog from '@/components/shared/confirm';
import ConfirmDialog, { Notification } from '@/components/shared/confirm';
import { Button, OutlineBtn } from '@/components/shared/Forms/Buttons/Buttons';
import { Select, TextArea } from '@/components/shared/Forms/Inputs/Inputs';
import MembershipIcon from '@/components/shared/membership/MembershipIcon';
Expand All @@ -21,7 +21,10 @@ import {
IUser,
SellerItem,
PaymentDataType,
PaymentType
PaymentType,
StockLevelType,
OrderStatusType,
PickedItems
} from '@/constants/types';
import { fetchSellerItems, fetchSingleSeller } from '@/services/sellerApi';
import { fetchSingleUserSettings } from '@/services/userSettingsApi';
Expand All @@ -34,6 +37,7 @@ import {

import { AppContext } from '../../../../../../context/AppContextProvider';
import logger from '../../../../../../logger.config.mjs';
import { createAndUpdateOrder } from '@/services/orderApi';

export default function BuyFromSellerForm({ params }: { params: { id: string } }) {
const SUBHEADER = "font-bold mb-2";
Expand All @@ -51,9 +55,11 @@ export default function BuyFromSellerForm({ params }: { params: { id: string } }
const [buyerDescription, setBuyerDescription] = useState<string>("");
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const { currentUser, autoLoginUser } = useContext(AppContext);
const [pickedItems, setPickedItems] = useState<{ itemId: string; quantity: number }[]>([]);
const { currentUser, autoLoginUser, showAlert } = useContext(AppContext);
const [pickedItems, setPickedItems] = useState<PickedItems[]>([]);
const [isOnlineShoppingEnabled, setOnlineShoppingEnabled] = useState(false);
const [showCheckoutStatus, setShowCheckoutStatus] = useState(false);
const [checkoutStatusMessage, setCheckoutStatusMessage] = useState<string>("")

const observer = useRef<IntersectionObserver | null>(null);

Expand Down Expand Up @@ -140,25 +146,36 @@ export default function BuyFromSellerForm({ params }: { params: { id: string } }
const checkoutOrder = async () => {
if (!currentUser?.pi_uid) return setError('User not logged in for payment');

const paymentData: PaymentDataType = {
amount: totalAmount,
memo: `Map of Pi payment from ${currentUser.pi_username} to ${sellerInfo?.pi_username}`,
metadata: {
payment_type: PaymentType.BuyerCheckout,
OrderPayment: {
items: pickedItems,
buyer: currentUser.pi_uid,
seller: sellerId,
fulfillment_method: sellerShopInfo?.fulfillment_method,
seller_fulfillment_description: sellerShopInfo?.fulfillment_description,
buyer_fulfillment_description: buyerDescription,
}
},
const newOrderData = {
buyerId: currentUser.pi_uid,
sellerId: sellerId,
paymentId: null,
totalAmount: totalAmount,
status: OrderStatusType.Pending,
fulfillmentMethod: sellerShopInfo?.fulfillment_method,
sellerFulfillmentDescription: sellerShopInfo?.fulfillment_description,
buyerFulfillmentDescription: buyerDescription,
};
await payWithPi(paymentData);
setPickedItems([]);
setTotalAmount(0);
setBuyerDescription("");

try {
const newOrder = await createAndUpdateOrder(newOrderData, pickedItems);
if (newOrder && newOrder._id) {
showAlert(`order placed successfully`);
setCheckoutStatusMessage(`order placed successfully with ID: ${newOrder._id.toString()}`);
setShowCheckoutStatus(true);
setPickedItems([]);
setTotalAmount(0);
setBuyerDescription("");
}
return

} catch (error:any) {
logger.error("error creating new order");
setCheckoutStatusMessage("Failed to placed new Order")
setShowCheckoutStatus(true);
return
}

}

// loading condition
Expand Down Expand Up @@ -247,19 +264,21 @@ export default function BuyFromSellerForm({ params }: { params: { id: string } }
header={t('SCREEN.SELLER_REGISTRATION.SELLER_ONLINE_SHOPPING_ITEMS_LIST_LABEL')}
open={false}>
<div className="overflow-x-auto mb-7 mt-3 flex p-2 gap-x-5 w-full">
{dbSellerItems && dbSellerItems.length > 0 &&
dbSellerItems.map((item) => (
<ListItem
key={item._id}
item={item}
pickedItems={pickedItems}
setPickedItems={setPickedItems}
refCallback={handleShopItemRef} // Attach observer
totalAmount={totalAmount}
setTotalAmount={setTotalAmount}
/>
))
{dbSellerItems && dbSellerItems.length > 0 &&
dbSellerItems
.map(item => (
<ListItem
key={item._id}
item={item}
pickedItems={pickedItems}
setPickedItems={setPickedItems}
refCallback={handleShopItemRef}
totalAmount={totalAmount}
setTotalAmount={setTotalAmount}
/>
))
}

</div>
<div>
<h2 className={SUBHEADER}>{t('SCREEN.SELLER_REGISTRATION.FULFILLMENT_METHOD_TYPE.FULFILLMENT_METHOD_TYPE_LABEL')}</h2>
Expand Down Expand Up @@ -334,6 +353,11 @@ export default function BuyFromSellerForm({ params }: { params: { id: string } }
message={t('SHARED.CONFIRM_DIALOG')}
url={linkUrl}
/>

{showCheckoutStatus && <div className='fixed inset-0 flex items-center justify-center'>
<Notification message={checkoutStatusMessage} showDialog={showCheckoutStatus} setShowDialog={setShowCheckoutStatus} />
</div>}

</div>
)}
</div>
Expand Down
9 changes: 5 additions & 4 deletions src/services/orderApi.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import axiosClient from "@/config/client";
import logger from '../../logger.config.mjs';
import { PickedItems } from "@/constants/types";

// Create or Update an Order
export const createOrUpdateOrder = async (orderData: any) => {
// Create and Update an Order
export const createAndUpdateOrder = async (orderData: any, orderItems: PickedItems[]) => {
try {
logger.info("Sending request to create or update order", { orderData });
const response = await axiosClient.post("/orders", orderData);
if (response.status === 201) {
const response = await axiosClient.post("/orders", { orderData, orderItems });
if (response.status === 200) {
logger.info(`Order processed successfully with Status ${response.status}`, {
data: response.data,
});
Expand Down