This commit is contained in:
gpt-engineer-app[bot]
2025-12-19 16:02:31 +00:00
parent d410b5b7c1
commit e569c2cf7e
12 changed files with 1282 additions and 48 deletions

View File

@@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { Separator } from "@/components/ui/separator";
import { formatIDR, formatDate } from "@/lib/format";
import { ArrowLeft, Package, CreditCard, Calendar, Clock } from "lucide-react";
import { ArrowLeft, Package, CreditCard, Calendar, AlertCircle } from "lucide-react";
interface OrderItem {
id: string;
@@ -42,36 +42,64 @@ export default function OrderDetail() {
const navigate = useNavigate();
const [order, setOrder] = useState<Order | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (!authLoading && !user) navigate("/auth");
else if (user && id) fetchOrder();
}, [user, authLoading, id]);
const fetchOrder = async () => {
const { data, error } = await supabase
.from("orders")
.select(`
*,
order_items (
id,
product_id,
quantity,
price,
products (title, type, slug)
)
`)
.eq("id", id)
.eq("user_id", user!.id)
.single();
if (error || !data) {
navigate("/orders");
if (authLoading) return;
if (!user) {
navigate("/auth");
return;
}
setOrder(data as Order);
setLoading(false);
if (id) {
fetchOrder();
}
}, [user, authLoading, id]);
const fetchOrder = async () => {
if (!user || !id) return;
setLoading(true);
setError(null);
try {
const { data, error: queryError } = await supabase
.from("orders")
.select(`
*,
order_items (
id,
product_id,
quantity,
price,
products (title, type, slug)
)
`)
.eq("id", id)
.eq("user_id", user.id)
.single();
if (queryError) {
console.error("Order fetch error:", queryError);
setError("Gagal mengambil data order");
setLoading(false);
return;
}
if (!data) {
setError("Order tidak ditemukan");
setLoading(false);
return;
}
setOrder(data as Order);
} catch (err) {
console.error("Unexpected error:", err);
setError("Terjadi kesalahan");
} finally {
setLoading(false);
}
};
const getStatusColor = (status: string) => {
@@ -127,6 +155,33 @@ export default function OrderDetail() {
);
}
if (error) {
return (
<AppLayout>
<div className="container mx-auto px-4 py-8 max-w-3xl">
<Button
variant="ghost"
onClick={() => navigate("/orders")}
className="mb-4"
>
<ArrowLeft className="w-4 h-4 mr-2" />
Kembali ke Riwayat Order
</Button>
<Card className="border-2 border-destructive">
<CardContent className="py-8 text-center">
<AlertCircle className="w-12 h-12 mx-auto mb-4 text-destructive" />
<h2 className="text-xl font-bold mb-2">Error</h2>
<p className="text-muted-foreground mb-4">{error}</p>
<Button onClick={() => navigate("/orders")}>
Kembali ke Riwayat Order
</Button>
</CardContent>
</Card>
</div>
</AppLayout>
);
}
if (!order) return null;
return (