Add order detail screen

This commit is contained in:
thesn10
2026-07-02 23:04:18 +02:00
parent 494ebdb104
commit fb53341be1

121
app/src/app/orders/[id].tsx Normal file
View File

@@ -0,0 +1,121 @@
import type { JSX } from "react";
import { useMemo, useState } from "react";
import { ScrollView, View } from "react-native";
import { useLocalSearchParams, useRouter } from "expo-router";
import { Button, Typography, useToast } from "heroui-native";
import { ORDERS } from "@/data/mock";
import { orderStatusInfo } from "@/lib/status";
import { AppHeader } from "@/components/AppHeader";
import { StatusChip } from "@/components/StatusChip";
const STEP_LABELS = ["Payment\nHeld", "Seller\nConfirms", "You Confirm\nReceipt"] as const;
export default function OrderDetailScreen(): JSX.Element {
const { id } = useLocalSearchParams<{ id: string }>();
const router = useRouter();
const { toast } = useToast();
const order = useMemo(() => ORDERS.find((item) => item.id === Number(id)) ?? ORDERS[0], [id]);
const [status, setStatus] = useState(order.status);
const statusInfo = orderStatusInfo(status);
const step2Done = status !== "AwaitingConfirm";
const step3Done = status === "Complete";
const activeStepIndex = step3Done ? 2 : step2Done ? 1 : 0;
const canCancel = status === "AwaitingConfirm";
const canConfirm = status === "Active";
const handleCancel = () => {
setStatus("Cancelled");
toast.show({ variant: "success", label: "Order cancelled. Full refund initiated." });
};
const handleConfirmReceipt = () => {
setStatus("Complete");
toast.show({ variant: "success", label: "Receipt confirmed! Seller has been paid." });
};
return (
<ScrollView className="flex-1 bg-background">
<AppHeader title="Order Detail" />
<View className="gap-5 p-4 md:mx-auto md:w-full md:max-w-2xl md:p-8">
<View className="flex-row items-start justify-between gap-3 rounded-xl border border-border bg-surface p-4">
<View className="flex-1 gap-1">
<Typography type="body-xs" color="muted">
Order placed {order.date}
</Typography>
<Typography type="h6">{order.name}</Typography>
<Typography type="body-xs" color="muted">
{order.seller}
</Typography>
</View>
<View className="items-end gap-1.5">
<Typography type="h6">{order.amt}</Typography>
<StatusChip label={statusInfo.label} color={statusInfo.color} />
</View>
</View>
<View className="gap-4 rounded-xl border border-border bg-surface p-4">
<Typography type="body-xs" color="muted">
Order Progress
</Typography>
<View className="flex-row items-start">
{STEP_LABELS.map((label, index) => {
const done = index < activeStepIndex || (index === activeStepIndex && step3Done);
const active = index === activeStepIndex && !step3Done;
return (
<View key={label} className="flex-1 items-center gap-2">
<View
className={`size-7 items-center justify-center rounded-full ${
done ? "bg-success" : active ? "bg-accent" : "bg-surface-secondary"
}`}
>
<Typography type="body-xs" weight="bold" className={done ? "text-black" : "text-white"}>
{done ? "✓" : String(index + 1)}
</Typography>
</View>
<Typography
type="body-xs"
weight="semibold"
align="center"
color={done || active ? undefined : "muted"}
className={done ? "text-success" : active ? "text-accent" : undefined}
>
{label}
</Typography>
</View>
);
})}
</View>
</View>
<View className="gap-1 rounded-xl bg-surface-secondary p-4">
<Typography type="body-sm" color="muted">
<Typography type="body-sm" weight="semibold">
{order.amt}
</Typography>
{" is locked in a secure on-chain escrow. Funds are released to the seller only after you "}
confirm receipt no third party can touch them.
</Typography>
</View>
<View className="flex-row flex-wrap gap-2.5">
{canCancel && (
<Button variant="danger-soft" onPress={handleCancel}>
<Button.Label>Cancel Order (Full Refund)</Button.Label>
</Button>
)}
{canConfirm && (
<Button onPress={handleConfirmReceipt}>
<Button.Label>Confirm Receipt Release Payment</Button.Label>
</Button>
)}
<Button variant="secondary" onPress={() => router.push(`/listing/${order.lid}`)}>
<Button.Label>View Listing </Button.Label>
</Button>
</View>
</View>
</ScrollView>
);
}