import React, { useState, useEffect, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { withI18n } from "../../i18n/withTranslation.js";
import {
Box,
Paper,
Alert,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
IconButton,
Tooltip,
CircularProgress,
Typography,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Button,
} from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";
import CancelIcon from "@mui/icons-material/Cancel";
import OrderDetailsDialog from "./OrderDetailsDialog.js";
// Constants
const getStatusTranslation = (status, t) => {
const statusMap = {
new: t ? t('orders.status.new') : "in Bearbeitung",
pending: t ? t('orders.status.pending') : "Neu",
processing: t ? t('orders.status.processing') : "in Bearbeitung",
paid: t ? t('orders.status.paid') : "Bezahlt",
cancelled: t ? t('orders.status.cancelled') : "Storniert",
shipped: t ? t('orders.status.shipped') : "Verschickt",
delivered: t ? t('orders.status.delivered') : "Geliefert",
};
return statusMap[status] || status;
};
const statusEmojis = {
new: "โ๏ธ",
pending: "โณ",
processing: "๐",
paid: "๐ฆ",
cancelled: "โ",
shipped: "๐",
delivered: "โ
",
};
const statusColors = {
new: "#ed6c02", // orange
pending: "#ff9800", // orange for pending
processing: "#2196f3", // blue for processing
paid: "#2e7d32", // green
cancelled: "#d32f2f", // red for cancelled
shipped: "#2e7d32", // green
delivered: "#2e7d32", // green
};
const currencyFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
});
// Orders Tab Content Component
const OrdersTab = ({ orderIdFromHash, t }) => {
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [selectedOrder, setSelectedOrder] = useState(null);
const [isDetailsDialogOpen, setIsDetailsDialogOpen] = useState(false);
const [cancelConfirmOpen, setCancelConfirmOpen] = useState(false);
const [orderToCancel, setOrderToCancel] = useState(null);
const [isCancelling, setIsCancelling] = useState(false);
const navigate = useNavigate();
const handleViewDetails = useCallback(
(orderId) => {
const orderToView = orders.find((order) => order.orderId === orderId);
if (orderToView) {
setSelectedOrder(orderToView);
setIsDetailsDialogOpen(true);
// Update the hash to include the order ID
navigate(`/profile#${orderId}`, { replace: true });
}
},
[orders, navigate]
);
const fetchOrders = useCallback(() => {
setLoading(true);
setError(null);
window.socketManager.emit("getOrders", (response) => {
if (response.success) {
setOrders(response.orders);
} else {
setError(response.error || "Failed to fetch orders.");
}
setLoading(false);
});
}, []);
useEffect(() => {
fetchOrders();
}, [fetchOrders]);
useEffect(() => {
if (orderIdFromHash && orders.length > 0) {
handleViewDetails(orderIdFromHash);
}
}, [orderIdFromHash, orders, handleViewDetails]);
const getStatusDisplay = (status) => {
return getStatusTranslation(status, t);
};
const getStatusEmoji = (status) => {
return statusEmojis[status] || "โ";
};
const getStatusColor = (status) => {
return statusColors[status] || "#757575"; // default gray
};
const handleCloseDetailsDialog = () => {
setIsDetailsDialogOpen(false);
setSelectedOrder(null);
navigate("/profile#orders", { replace: true });
};
// Check if order can be cancelled
const isOrderCancelable = (order) => {
const cancelableStatuses = ['new', 'pending', 'processing'];
return cancelableStatuses.includes(order.status);
};
// Handle cancel button click
const handleCancelClick = (order) => {
setOrderToCancel(order);
setCancelConfirmOpen(true);
};
// Handle cancel confirmation
const handleConfirmCancel = () => {
if (!orderToCancel) return;
setIsCancelling(true);
window.socketManager.emit('cancelOrder', { orderId: orderToCancel.orderId }, (response) => {
setIsCancelling(false);
setCancelConfirmOpen(false);
if (response.success) {
console.log('Order cancelled:', response.orderId);
// Refresh orders list
fetchOrders();
} else {
setError(response.error || 'Failed to cancel order');
}
setOrderToCancel(null);
});
};
// Handle cancel dialog close
const handleCancelDialogClose = () => {
if (!isCancelling) {
setCancelConfirmOpen(false);
setOrderToCancel(null);
}
};
if (loading) {
return (
);
}
if (error) {
return (
{error}
);
}
return (
{orders.length > 0 ? (
{t ? t('orders.table.orderNumber') : 'Bestellnummer'}
{t ? t('orders.table.date') : 'Datum'}
{t ? t('orders.table.status') : 'Status'}
{t ? t('orders.table.items') : 'Artikel'}
{t ? t('orders.table.total') : 'Summe'}
{t ? t('orders.table.actions') : 'Aktionen'}
{orders.map((order) => {
const displayStatus = getStatusDisplay(order.status);
const total = order.items.reduce(
(acc, item) => acc + item.price * item.quantity_ordered,
0
);
return (
{order.orderId}
{new Date(order.created_at).toLocaleDateString()}
{getStatusEmoji(order.status)}
{displayStatus}
{order.items
.filter(item => {
// Exclude delivery items - backend uses deliveryMethod ID as item name
const itemName = item.name || '';
return itemName !== 'DHL' &&
itemName !== 'DPD' &&
itemName !== 'Sperrgut' &&
itemName !== 'Abholung';
})
.reduce(
(acc, item) => acc + item.quantity_ordered,
0
)}
{currencyFormatter.format(total)}
handleViewDetails(order.orderId)}
aria-label={t ? t('orders.tooltips.viewDetails') : 'Details anzeigen'}
>
{isOrderCancelable(order) && (
handleCancelClick(order)}
aria-label={t ? t('orders.tooltips.cancelOrder') : 'Bestellung stornieren'}
>
)}
);
})}
) : (
{t ? t('orders.noOrders') : 'Sie haben noch keine Bestellungen aufgegeben.'}
)}
{/* Cancel Confirmation Dialog */}
);
};
export default withI18n()(OrdersTab);