MyOrdersPage.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import { useEffect, useState } from "react";
  2. import { useTranslation } from "react-i18next";
  3. import { useOrder } from "@/hooks/useOrder";
  4. import { OrderFormModal } from "@/components/OrderFormModal";
  5. import { useNavigate } from "react-router-dom";
  6. import {
  7. Card,
  8. CardContent,
  9. CardFooter,
  10. CardHeader,
  11. CardTitle,
  12. } from "@/components/ui/card";
  13. import { Button } from "@/components/ui/button";
  14. import { Badge } from "@/components/ui/badge";
  15. import { Plus, Package, MapPin, Calendar, Inbox, User } from "lucide-react";
  16. export const MyOrdersPage = () => {
  17. const { t } = useTranslation();
  18. const { orders, getMineOrders } = useOrder();
  19. const [isModalOpen, setIsModalOpen] = useState(false);
  20. const navigate = useNavigate();
  21. useEffect(() => {
  22. getMineOrders();
  23. }, []);
  24. return (
  25. <div className="text-foreground min-h-screen p-6">
  26. <div className="mx-auto max-w-5xl">
  27. <div className="mb-8 flex flex-col items-start justify-between gap-4 sm:flex-row sm:items-center">
  28. <h2 className="text-3xl font-bold tracking-tight">
  29. {t("orders.yourOrders")}
  30. </h2>
  31. <Button
  32. onClick={() => setIsModalOpen(true)}
  33. className="gap-2 rounded-xl"
  34. >
  35. <Plus className="h-4 w-4" />
  36. {t("orders.newOrder")}
  37. </Button>
  38. </div>
  39. {!orders || orders.length === 0 ? (
  40. <Card className="flex flex-col items-center justify-center border-dashed p-12 text-center shadow-sm">
  41. <Inbox className="text-muted-foreground/50 mb-4 h-12 w-12" />
  42. <p className="text-muted-foreground text-lg font-medium">
  43. {t("orders.noOrders")}
  44. </p>
  45. </Card>
  46. ) : (
  47. <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
  48. {orders.map((o) => {
  49. const isCanceled = o.status === "ORDER_CANCELED";
  50. const isCompleted = o.status === "DELIVERY_COMPLETED";
  51. return (
  52. <Card
  53. key={o.trackingNumber}
  54. onClick={() => navigate(`/orders/${o.trackingNumber}`)}
  55. className="hover:border-primary/40 cursor-pointer transition-all hover:shadow-md"
  56. >
  57. <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-2">
  58. <CardTitle className="text-primary font-mono text-lg font-bold">
  59. {o.trackingNumber}
  60. </CardTitle>
  61. <Badge
  62. variant={isCanceled ? "destructive" : "default"}
  63. className={`px-3 py-0.5 text-xs ${
  64. !isCanceled && isCompleted
  65. ? "bg-green-500 hover:bg-green-600 dark:bg-green-600 dark:hover:bg-green-700"
  66. : !isCanceled
  67. ? "bg-blue-500 hover:bg-blue-600 dark:bg-blue-600 dark:hover:bg-blue-700"
  68. : ""
  69. }`}
  70. >
  71. {t(`orders.${o.status}`)}
  72. </Badge>
  73. </CardHeader>
  74. <CardContent className="space-y-3 pt-4">
  75. <div className="flex gap-6">
  76. <div className="text-muted-foreground flex items-center gap-2 text-sm">
  77. <Package className="h-4 w-4" />
  78. <span>
  79. {t("orders.weightInfo")}{" "}
  80. <span className="text-foreground font-medium">
  81. {o.weight} kg
  82. </span>
  83. </span>
  84. </div>
  85. {/* DANE ODBIORCY (SKRÓT) */}
  86. {o.recipientFirstName && (
  87. <div className="text-muted-foreground flex items-center gap-2 text-sm">
  88. <User className="h-4 w-4" />
  89. <span className="text-foreground font-medium truncate max-w-[120px]">
  90. {o.recipientFirstName} {o.recipientLastName}
  91. </span>
  92. </div>
  93. )}
  94. </div>
  95. {o.deliveryLocation && (
  96. <div className="text-muted-foreground flex items-start gap-2 text-sm">
  97. <MapPin className="mt-0.5 h-4 w-4 shrink-0" />
  98. <span className="leading-tight">
  99. {t("orders.to")}{" "}
  100. <span className="text-foreground font-medium">
  101. {o.deliveryLocation.city},{" "}
  102. {o.deliveryLocation.streetAddress}
  103. </span>
  104. </span>
  105. </div>
  106. )}
  107. </CardContent>
  108. <CardFooter className="text-muted-foreground border-t pt-4 text-xs">
  109. <div className="flex items-center gap-1.5">
  110. <Calendar className="h-3.5 w-3.5" />
  111. <span>
  112. {t("orders.created")}{" "}
  113. {new Date(o.createdAt).toLocaleDateString()}
  114. </span>
  115. </div>
  116. </CardFooter>
  117. </Card>
  118. );
  119. })}
  120. </div>
  121. )}
  122. </div>
  123. <OrderFormModal
  124. isOpen={isModalOpen}
  125. onClose={() => setIsModalOpen(false)}
  126. />
  127. </div>
  128. );
  129. };