Add household seeding & session (task 07)
- scripts/seed.ts: idempotent pnpm db:seed inserts "Home" household if none exists (powered by tsx)
- signIn callback: first member of household gets owner role, subsequent users get member
- src/lib/session.ts: getCurrentSession() returns { user, household, role }, throws if unauthenticated or unmembered
- /settings/household: member list for all roles; rename form gated to owner only (server action also enforces)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
5da472d6ff
commit
6710c8b231
@@ -0,0 +1,61 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "@/lib/db";
|
||||
import { getCurrentSession } from "@/lib/session";
|
||||
import { householdMembers, users } from "@/modules/_core/schema";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { renameHousehold } from "./actions";
|
||||
|
||||
export default async function HouseholdSettingsPage() {
|
||||
const { household, role } = await getCurrentSession();
|
||||
|
||||
const members = await db
|
||||
.select({ user: users, role: householdMembers.role })
|
||||
.from(householdMembers)
|
||||
.innerJoin(users, eq(householdMembers.userId, users.id))
|
||||
.where(eq(householdMembers.householdId, household.id));
|
||||
|
||||
return (
|
||||
<div className="container max-w-2xl py-8 space-y-6">
|
||||
<h1 className="text-2xl font-semibold">Household Settings</h1>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Members</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ul className="space-y-2">
|
||||
{members.map(({ user, role: memberRole }) => (
|
||||
<li key={user.id} className="flex items-center justify-between">
|
||||
<span>{user.name ?? user.email}</span>
|
||||
<span className="text-sm text-muted-foreground capitalize">
|
||||
{memberRole}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{role === "owner" && (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Rename Household</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<form action={renameHousehold} className="flex gap-2">
|
||||
<Input name="name" defaultValue={household.name} required />
|
||||
<Button type="submit">Save</Button>
|
||||
</form>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user