Files
Cibello-app/apps/mobile/src/app/household.tsx
T
Sven (AAMOS AI) d95c67d979
CI / Typecheck, test & build (push) Failing after 42s
fix(mobile): plan/hushåll/profil felhantering + streckkod pausar kamera (MIKRO 54)
2026-08-14 18:38:15 +07:00

93 lines
2.6 KiB
TypeScript

import { useQuery } from "@tanstack/react-query";
import { api } from "@/lib/api";
import { t } from "@/lib/i18n";
import {
Body,
Card,
EmptyState,
ErrorView,
Heading,
LoadingView,
Row,
Screen,
Small,
Tag,
} from "@/components/ui";
/** Hushåll (spec §7): medlemmar, inbjudningskod, delat vs privat. */
interface HouseholdDetail {
id: string;
name: string;
inviteCode: string;
members: Array<{ userId: string; displayName: string; role: string; portionFactor: number }>;
storageLocations: Array<{ id: string; name: string; type: string }>;
}
/** Rolletiketter ur i18n-katalogen: household.role.<roll> (12 språk). */
const roleLabel = (role: string): string =>
["owner", "adult", "member", "child"].includes(role) ? t(`household.role.${role}`) : role;
export default function HouseholdScreen() {
const me = useQuery({
queryKey: ["me"],
queryFn: () => api<{ activeHouseholdId: string | null }>("/v1/me"),
});
const householdId = me.data?.activeHouseholdId;
const household = useQuery({
queryKey: ["household", householdId],
queryFn: () => api<HouseholdDetail>(`/v1/households/${householdId}`),
enabled: Boolean(householdId),
});
if (me.isLoading || household.isLoading) return <LoadingView />;
if (me.isError) return <ErrorView onRetry={() => void me.refetch()} />;
if (!householdId) {
return (
<Screen>
<EmptyState text={t("household.empty")} />
</Screen>
);
}
if (household.isError || !household.data) {
return <ErrorView onRetry={() => void household.refetch()} />;
}
const data = household.data;
return (
<Screen>
<Heading>{data.name}</Heading>
<Card>
<Body>{t("household.invite", { code: data.inviteCode })}</Body>
<Small>{t("household.shareCode")}</Small>
</Card>
<Card>
<Heading>{t("household.members")}</Heading>
{data.members.map((member) => (
<Row key={member.userId} style={{ justifyContent: "space-between" }}>
<Body>{member.displayName}</Body>
<Row>
<Tag label={roleLabel(member.role)} />
<Small>{t("household.portionFactor", { factor: member.portionFactor })}</Small>
</Row>
</Row>
))}
</Card>
<Card>
<Heading>{t("household.locations")}</Heading>
{data.storageLocations.map((location) => (
<Body key={location.id}> {location.name}</Body>
))}
</Card>
<Card>
<Small> {t("household.shared")}</Small>
<Small>🔒 {t("household.private")}</Small>
</Card>
</Screen>
);
}