This repository has been archived on 2026-08-11. You can view files and clone it, but cannot push or open issues or pull requests.
Gishen-Mob/app/(root)/(screens)/orders/index.tsx
kirukib 5391780b9b Ship Rx Care tab, notifications inbox, and guest pickup codes.
Replace the profile tab with prescription management (inline reminders and family invite), add a shared tab top bar, separate notifications from orders, and support any-branch guest checkout with GSH codes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 15:35:51 +03:00

156 lines
5.2 KiB
TypeScript

import { router } from "expo-router";
import { useState } from "react";
import { Alert, Image, ScrollView, View } from "react-native";
import { useTranslation } from "react-i18next";
import { Badge } from "@/components/ui/Badge";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { EmptyState } from "@/components/ui/EmptyState";
import { Field } from "@/components/ui/Field";
import { AppHeader } from "@/components/ui/Header";
import { Screen } from "@/components/ui/Screen";
import { Text } from "@/components/ui/Text";
import { useOrdersStore } from "@/lib/stores/ordersStore";
import { colors, gutter, radii } from "@/lib/theme";
import { formatETB } from "@/lib/utils";
import { routes } from "@/lib/routes";
const toneFor = {
requested: "neutral",
confirmed: "info",
paid: "brand",
dispatched: "warn",
delivered: "brand",
completed: "brand",
cancelled: "danger",
} as const;
export default function OrdersScreen() {
const { t } = useTranslation();
const orders = useOrdersStore((s) => s.orders);
const getByPickupCode = useOrdersStore((s) => s.getByPickupCode);
const [lookup, setLookup] = useState("");
const findByCode = () => {
const order = getByPickupCode(lookup);
if (!order) {
Alert.alert(
"Code not found",
"Check the GSH-XXXX code from checkout. Demo sample: GSH-GUEST"
);
return;
}
router.push(routes.orderDetail(order.id));
};
return (
<Screen>
<AppHeader
title={t("common.orders")}
subtitle="Order history — not the same as notifications"
/>
<ScrollView
contentContainerStyle={{
paddingHorizontal: gutter,
paddingBottom: 40,
gap: 12,
}}
>
<Card elevated={false}>
<Text variant="h3">Find with pickup code</Text>
<Text variant="caption" color={colors.muted} style={{ marginTop: 4 }}>
Guests can open an order by entering the quick code from checkout.
</Text>
<View style={{ marginTop: 12, gap: 10 }}>
<Field
label="Pickup code"
value={lookup}
onChangeText={setLookup}
autoCapitalize="characters"
placeholder="GSH-GUEST"
icon="key-outline"
/>
<Button title="Look up order" variant="outline" onPress={findByCode} />
</View>
</Card>
{orders.length === 0 ? (
<EmptyState
icon="receipt-outline"
title="No orders yet"
body="Your purchases will show up here."
actionTitle="Start shopping"
onAction={() => router.push(routes.shop)}
/>
) : (
orders.map((o) => (
<Card key={o.id} onPress={() => router.push(routes.orderDetail(o.id))}>
<View style={{ flexDirection: "row", justifyContent: "space-between", gap: 12 }}>
<View style={{ flex: 1 }}>
<Text variant="h3">
{o.anyBranch
? "Any-branch pickup"
: o.fulfillment === "pickup"
? "Pickup"
: "Delivery"}{" "}
· {o.areaLabel}
</Text>
<Text variant="caption" color={colors.subtle} style={{ marginTop: 4 }}>
{new Date(o.createdAt).toLocaleString()} · {o.paymentMethod}
{o.pickupCode ? ` · ${o.pickupCode}` : ""}
</Text>
</View>
<Badge label={o.status} tone={toneFor[o.status]} />
</View>
<View style={{ flexDirection: "row", gap: 8, marginTop: 12 }}>
{o.items.slice(0, 3).map((item) => (
<Image
key={item.productId}
source={{ uri: item.image }}
style={{
width: 44,
height: 44,
borderRadius: radii.sm,
backgroundColor: colors.surfaceAlt,
}}
resizeMode="contain"
/>
))}
{o.items.length > 3 ? (
<View
style={{
width: 44,
height: 44,
borderRadius: radii.sm,
backgroundColor: colors.surfaceAlt,
alignItems: "center",
justifyContent: "center",
}}
>
<Text variant="micro">+{o.items.length - 3}</Text>
</View>
) : null}
</View>
<View
style={{
marginTop: 12,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Text variant="price">{formatETB(o.total)}</Text>
<Text variant="label" color={colors.brandText}>
View details
</Text>
</View>
</Card>
))
)}
</ScrollView>
</Screen>
);
}