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)/profiles/switch.tsx
kirukib 7310a349c5 Add Gishen mobile app with complete demo shopping and care flows.
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>
2026-08-07 01:21:32 +03:00

135 lines
4.6 KiB
TypeScript

import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { useTranslation } from "react-i18next";
import { Pressable, ScrollView, View } from "react-native";
import { Badge } from "@/components/ui/Badge";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { AppHeader } from "@/components/ui/Header";
import { Screen } from "@/components/ui/Screen";
import { Text } from "@/components/ui/Text";
import { routes } from "@/lib/routes";
import { useProfileModeStore } from "@/lib/stores/profileModeStore";
import { colors, gutter } from "@/lib/theme";
import { formatETB } from "@/lib/utils";
export default function ProfileSwitchScreen() {
const { t } = useTranslation();
const mode = useProfileModeStore((s) => s.mode);
const setMode = useProfileModeStore((s) => s.setMode);
const memberships = useProfileModeStore((s) => s.memberships);
const setActiveOrg = useProfileModeStore((s) => s.setActiveOrg);
const activeOrgId = useProfileModeStore((s) => s.activeOrgId);
return (
<Screen>
<AppHeader
title={t("common.switchProfile")}
subtitle="Personal shopping or organisation benefits"
/>
<ScrollView
contentContainerStyle={{
paddingHorizontal: gutter,
paddingBottom: 32,
gap: 12,
}}
>
<Pressable
onPress={() => {
setMode("personal");
setActiveOrg(null);
}}
style={cardStyle(mode === "personal")}
>
<View style={{ flexDirection: "row", alignItems: "center", gap: 12 }}>
<View
style={{
width: 44,
height: 44,
borderRadius: 14,
backgroundColor: colors.brandSoft,
alignItems: "center",
justifyContent: "center",
}}
>
<Ionicons name="person" size={20} color={colors.brandText} />
</View>
<View style={{ flex: 1 }}>
<Text variant="h3">{t("common.personal")}</Text>
<Text variant="caption" color={colors.muted} style={{ marginTop: 2 }}>
Retail shopping, loyalty points, family
</Text>
</View>
{mode === "personal" ? <Badge label="Active" tone="brand" /> : null}
</View>
</Pressable>
{memberships.map((m) => {
const active = mode === "corporate" && activeOrgId === m.orgId;
return (
<Pressable
key={m.orgId}
onPress={() => setActiveOrg(m.orgId)}
style={cardStyle(active)}
>
<View style={{ flexDirection: "row", alignItems: "center", gap: 12 }}>
<View
style={{
width: 44,
height: 44,
borderRadius: 14,
backgroundColor: colors.brandSoft,
alignItems: "center",
justifyContent: "center",
}}
>
<Ionicons name="business" size={20} color={colors.brandText} />
</View>
<View style={{ flex: 1 }}>
<Text variant="h3">{m.orgName}</Text>
<Text variant="caption" color={colors.muted} style={{ marginTop: 2 }}>
{m.planName}
</Text>
<Text variant="label" color={colors.brandText} style={{ marginTop: 6 }}>
{formatETB(m.remainingAllowance)} allowance left
</Text>
</View>
{active ? <Badge label="Active" tone="brand" /> : null}
</View>
</Pressable>
);
})}
{!memberships.length ? (
<Card elevated={false}>
<Text variant="body" color={colors.muted}>
No organisations yet. Join with a demo code from your HR team.
</Text>
<Button
title={t("common.joinOrg")}
onPress={() => router.push(routes.profileJoin)}
style={{ marginTop: 12 }}
/>
</Card>
) : (
<Button
title={t("common.joinOrg")}
variant="outline"
onPress={() => router.push(routes.profileJoin)}
/>
)}
</ScrollView>
</Screen>
);
}
function cardStyle(selected: boolean) {
return {
backgroundColor: colors.surface,
borderRadius: 20,
padding: 16,
borderWidth: selected ? 2 : 1,
borderColor: selected ? colors.brand : colors.line,
};
}