feat(admin): edit order status with dropdown and notify partner by email
Some checks failed
Staging Build / build (push) Has been cancelled
Some checks failed
Staging Build / build (push) Has been cancelled
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Download, ExternalLink, Search } from "lucide-react";
|
||||
import { Download, ExternalLink, Search, Loader2 } from "lucide-react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { updateOrderStatus } from "@/lib/actions/orders";
|
||||
|
||||
interface OrdersTableProps {
|
||||
initialOrders: any[];
|
||||
@@ -26,10 +33,29 @@ const statusClass: Record<string, string> = {
|
||||
};
|
||||
|
||||
export function OrdersTable({ initialOrders }: OrdersTableProps) {
|
||||
const [orders, setOrders] = useState(initialOrders);
|
||||
const [search, setSearch] = useState("");
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all");
|
||||
const [updatingId, setUpdatingId] = useState<string | null>(null);
|
||||
|
||||
const filteredOrders = initialOrders.filter((order) => {
|
||||
useEffect(() => {
|
||||
setOrders(initialOrders);
|
||||
}, [initialOrders]);
|
||||
|
||||
const handleStatusChange = async (orderId: string, newStatus: 'pending' | 'active' | 'completed' | 'cancelled') => {
|
||||
setUpdatingId(orderId);
|
||||
try {
|
||||
await updateOrderStatus(orderId, newStatus);
|
||||
setOrders(prev => prev.map(o => o.id === orderId ? { ...o, status: newStatus } : o));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert("Fehler beim Ändern des Status.");
|
||||
} finally {
|
||||
setUpdatingId(null);
|
||||
}
|
||||
};
|
||||
|
||||
const filteredOrders = orders.filter((order) => {
|
||||
const orderNum = (order.order_number || "").toLowerCase();
|
||||
const company = (order.customer_data?.company_name || "").toLowerCase();
|
||||
const contact = `${order.customer_data?.first_name || ""} ${order.customer_data?.last_name || ""}`.toLowerCase();
|
||||
@@ -163,9 +189,31 @@ export function OrdersTable({ initialOrders }: OrdersTableProps) {
|
||||
{new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(order.total_price)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge className={`text-xs px-2 py-0.5 rounded ${statusClass[order.status] ?? 'bg-slate-500/20 text-slate-300'}`}>
|
||||
{statusLabel[order.status] ?? order.status}
|
||||
</Badge>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild disabled={updatingId === order.id}>
|
||||
<button className="focus:outline-none focus:ring-0 active:scale-95 disabled:pointer-events-none transition-transform duration-100">
|
||||
<Badge className={`text-xs px-2 py-0.5 rounded cursor-pointer transition-all duration-200 hover:opacity-85 flex items-center gap-1.5 ${statusClass[order.status] ?? 'bg-slate-500/20 text-slate-300'}`}>
|
||||
{updatingId === order.id ? (
|
||||
<Loader2 className="w-3 h-3 animate-spin mr-1" />
|
||||
) : null}
|
||||
{statusLabel[order.status] ?? order.status}
|
||||
<span className="text-[9px] opacity-70">▼</span>
|
||||
</Badge>
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="bg-slate-900 border-white/10 text-white min-w-[140px]">
|
||||
{Object.entries(statusLabel).map(([key, label]) => (
|
||||
<DropdownMenuItem
|
||||
key={key}
|
||||
disabled={updatingId === order.id}
|
||||
onClick={() => handleStatusChange(order.id, key as any)}
|
||||
className={`text-xs cursor-pointer hover:bg-white/10 transition-colors focus:bg-white/10 focus:text-white ${order.status === key ? 'font-bold text-primary' : ''}`}
|
||||
>
|
||||
{label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
{order.pdf_url ? (
|
||||
|
||||
Reference in New Issue
Block a user