feat: DHL-Sendungsverlauf direkt auf der Tracking-Seite anzeigen
/bestellung-verfolgen holt den Sendungsverlauf serverseitig ueber die DHL Shipment Tracking - Unified API und zeigt ihn im eigenen Layout an, statt Kundschaft auf dhl.de weiterzuleiten. - lib/dhl-tracking.ts: Abfrage mit API-Key, Zod-Validierung, Timeout, Cache pro Sendung (unterwegs 10 min, zugestellt 12 h, Fehler 2 min) - Abfrage erst nach erfolgreicher Pruefung von Bestellnummer + E-Mail, damit die Seite nicht als offener Proxy zu DHL dient - Ohne freigeschalteten Key bleibt die Seite unveraendert (Nummer + Link) - Optional DHL_TRACKING_API_KEY, falls das Tracking in eigener DHL-App liegt - Datenschutzerklaerung um die Statusabfrage bei DHL ergaenzt Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
2659db64bd
commit
01eaca39dc
10 files changed
+674
-5
No files matched your search
@@ -4,7 +4,9 @@ import { Container, SectionHeading, Button } from "@/components/ui";
|
||||
import { OrderStatusBadge, OrderStatusTimeline } from "@/components/account-ui";
|
||||
import { getOrderForTracking } from "@/lib/account-data";
|
||||
import { formatPrice, formatDate } from "@/lib/format";
|
||||
import { getCarrierTrackingUrl } from "@/lib/shipment-tracking";
|
||||
import { getCarrierTrackingUrl, isDhlCarrier } from "@/lib/shipment-tracking";
|
||||
import { getDhlTracking, type DhlTrackingResult } from "@/lib/dhl-tracking";
|
||||
import { ShipmentTrackingHistory } from "@/components/shipment-tracking-history";
|
||||
import { rateLimit, getClientIp } from "@/lib/rate-limit";
|
||||
import { getLocale } from "@/i18n/locale";
|
||||
import { getDictionary } from "@/i18n/get-dictionary";
|
||||
@@ -32,6 +34,18 @@ export default async function TrackOrderPage(props: PageProps<"/bestellung-verfo
|
||||
}
|
||||
}
|
||||
|
||||
// Erst NACH erfolgreicher Pruefung von Bestellnummer + E-Mail bei DHL
|
||||
// nachfragen: sonst liesse sich diese Seite als offener Proxy fuer beliebige
|
||||
// Sendungsabfragen missbrauchen und das DHL-Kontingent leerraeumen.
|
||||
let dhlTracking: DhlTrackingResult = { kind: "disabled" };
|
||||
if (order?.shipment?.trackingNumber && isDhlCarrier(order.shipment.carrier)) {
|
||||
dhlTracking = await getDhlTracking({
|
||||
trackingNumber: order.shipment.trackingNumber,
|
||||
postalCode: order.zip,
|
||||
locale,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="py-20">
|
||||
<Container className="max-w-xl">
|
||||
@@ -150,6 +164,20 @@ export default async function TrackOrderPage(props: PageProps<"/bestellung-verfo
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
<ShipmentTrackingHistory
|
||||
result={dhlTracking}
|
||||
locale={locale}
|
||||
labels={{
|
||||
heading: t.shipmentInfo.historyHeading,
|
||||
ariaLabel: t.shipmentInfo.historyAriaLabel,
|
||||
estimatedDelivery: t.shipmentInfo.estimatedDelivery,
|
||||
notYetScanned: t.shipmentInfo.notYetScanned,
|
||||
unavailable: t.shipmentInfo.historyUnavailable,
|
||||
dataSource: t.shipmentInfo.dataSource,
|
||||
statuses: t.shipmentInfo.statuses,
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="mt-5 flex items-center justify-between gap-4">
|
||||
<p className="text-forest">{formatPrice(order.totalCents, order.currency, locale)}</p>
|
||||
{order.invoice ? (
|
||||
|
||||
Reference in new issue
Block a user