Ship Expo Router screens, seeded stores, and polished UX so auth, shop, checkout, prescriptions, loyalty, family, and account processes work end-to-end offline. Co-authored-by: Cursor <cursoragent@cursor.com>
86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
import { Share, View } from "react-native";
|
|
import { router } from "expo-router";
|
|
import { useState } from "react";
|
|
import { Alert } from "react-native";
|
|
import { Button } from "@/components/ui/Button";
|
|
import { Card } from "@/components/ui/Card";
|
|
import { Chip } from "@/components/ui/Chip";
|
|
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 { useFamilyStore } from "@/lib/stores/familyStore";
|
|
import { colors, gutter } from "@/lib/theme";
|
|
|
|
const RELATIONS = ["spouse", "child", "parent", "other"] as const;
|
|
|
|
export default function FamilyInviteScreen() {
|
|
const addMember = useFamilyStore((s) => s.addMember);
|
|
const inviteCode = useFamilyStore((s) => s.inviteCode);
|
|
const [name, setName] = useState("");
|
|
const [phone, setPhone] = useState("");
|
|
const [relationship, setRelationship] = useState<(typeof RELATIONS)[number]>("child");
|
|
|
|
return (
|
|
<Screen>
|
|
<AppHeader title="Invite family" subtitle="Share care, orders, and reminders" />
|
|
<View style={{ flex: 1, paddingHorizontal: gutter, gap: 14 }}>
|
|
<Card tone="brand" elevated={false}>
|
|
<Text variant="caption" color={colors.muted}>
|
|
Family invite code
|
|
</Text>
|
|
<Text variant="h2" style={{ marginTop: 4 }}>
|
|
{inviteCode}
|
|
</Text>
|
|
<Button
|
|
title="Share code"
|
|
variant="outline"
|
|
style={{ marginTop: 12 }}
|
|
onPress={() =>
|
|
Share.share({
|
|
message: `Join my Gishen family group with code ${inviteCode}`,
|
|
})
|
|
}
|
|
/>
|
|
</Card>
|
|
|
|
<Text variant="h3">Or add by phone</Text>
|
|
<Field label="Name" value={name} onChangeText={setName} icon="person-outline" />
|
|
<Field
|
|
label="Phone"
|
|
value={phone}
|
|
onChangeText={setPhone}
|
|
keyboardType="phone-pad"
|
|
icon="call-outline"
|
|
/>
|
|
<Text variant="label" color={colors.muted}>
|
|
Relationship
|
|
</Text>
|
|
<View style={{ flexDirection: "row", flexWrap: "wrap", gap: 8 }}>
|
|
{RELATIONS.map((r) => (
|
|
<Chip
|
|
key={r}
|
|
label={r}
|
|
selected={relationship === r}
|
|
onPress={() => setRelationship(r)}
|
|
size="sm"
|
|
/>
|
|
))}
|
|
</View>
|
|
<Button
|
|
title="Send invite"
|
|
onPress={() => {
|
|
if (!name.trim()) {
|
|
Alert.alert("Name required");
|
|
return;
|
|
}
|
|
addMember({ name: name.trim(), phone, relationship });
|
|
Alert.alert("Invited", `${name.trim()} is pending acceptance.`);
|
|
router.back();
|
|
}}
|
|
/>
|
|
</View>
|
|
</Screen>
|
|
);
|
|
}
|