added users permission card

This commit is contained in:
Jun-te Kim 2025-09-08 11:39:37 +00:00
parent 88b6ad7f4b
commit c3ae5d3cf5
3 changed files with 178 additions and 0 deletions

View file

@ -34,6 +34,7 @@ import { PortfolioStatus as PortfolioStatusOptions } from "@/app/db/schema/portf
import { PortfolioGoal as PortfolioGoalOptions } from "@/app/db/schema/portfolio";
import { useSession } from "next-auth/react";
import PortfolioPlanTable from "@/app/components/portfolio/measures/PlanTable";
import { UsersPermissionsCard } from "./UsersPermissionsCard";
// dropdown selection component for both goal and status
@ -459,6 +460,7 @@ export default function PortfolioSettings({
</TableBody>
</Table>
</div>
<UsersPermissionsCard/>
<div className="rounded-md border border-red-500 mt-2">
<Table>
<TableHead className="text-lg text-brandblue">Danger Zone:</TableHead>

View file

@ -0,0 +1,132 @@
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/app/shadcn_components/ui/table";
import { Input } from "@/app/shadcn_components/ui/input";
import { Button } from "@/app/shadcn_components/ui/button";
import { useState } from "react";
import { Role, RoleDropdown, Collaborator } from "@/app/portfolio/[slug]/(portfolio)/settings/roles";
export function UsersPermissionsCard({
}: {
}) {
const [inviteEmail, setInviteEmail] = useState("");
const [inviteRole, setInviteRole] = useState<Role>("read");
const collaborators: Collaborator[] = [
{ name: "Name 1", email: "name1@example.com", role: "read" },
{ name: "Name 2", email: "name2@example.com", role: "read" },
];
function handleInvite() {
console.log("handle invite")
}
function onChangeRole(email:string, role:Role) {
console.log(`on change role ${email} ${role}`)
}
function onRemove(email:string) {
console.log(`remove user ${email}`)
}
return (
<div className="rounded-md border border-gray-700 mt-2">
<Table>
<TableBody>
<TableRow>
<TableHead className="text-brandblue">
Users Permission:
<p className="text-xs text-gray-500">Add users and manage roles</p>
</TableHead>
</TableRow>
{/* Invite row */}
<TableRow>
<TableHead className="text-brandblue">
Add a user
<p className="text-xs text-gray-500">
Invite by email and choose a role
</p>
</TableHead>
<TableCell className="flex gap-2 items-center">
<Input
type="email"
placeholder="email@example.com"
value={inviteEmail}
onChange={(e) => setInviteEmail(e.target.value)}
/>
<div className="min-w-40">
<RoleDropdown value={inviteRole} onChange={setInviteRole} />
</div>
</TableCell>
<TableCell className="text-right">
<Button className="w-28" onClick={handleInvite} disabled={!inviteEmail}>
Invite
</Button>
</TableCell>
</TableRow>
{/* Current collaborators list */}
<TableRow>
<TableHead className="text-brandblue">
Current users
<p className="text-xs text-gray-500">
Update roles or remove access
</p>
</TableHead>
<TableCell colSpan={2}>
<div className="rounded-md border border-gray-200">
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Role</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{collaborators.length === 0 ? (
<TableRow>
<TableCell colSpan={4} className="text-sm text-gray-500">
No users yet.
</TableCell>
</TableRow>
) : (
collaborators.map((c) => (
<TableRow key={c.email}>
<TableCell>{c.name || "—"}</TableCell>
<TableCell>{c.email}</TableCell>
<TableCell className="min-w-40">
<RoleDropdown
value={c.role}
onChange={(r) => onChangeRole(c.email, r)}
/>
</TableCell>
<TableCell className="text-right">
<Button
variant="destructive"
className="bg-red-700"
onClick={() => onRemove(c.email)}
>
Remove
</Button>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
);
}

View file

@ -0,0 +1,44 @@
import {
Select,
SelectTrigger,
SelectValue,
SelectContent,
SelectGroup,
SelectItem,
} from "@/app/shadcn_components/ui/select";
// Roles you support in your app (adjust as needed)
const ROLE_OPTIONS = ["read", "write"] as const;
export type Role = typeof ROLE_OPTIONS[number];
export type Collaborator = {
name?: string | null;
email: string;
role: Role;
};
// Small role dropdown using shadcn Select
export function RoleDropdown({
value,
onChange,
}: {
value: Role;
onChange: (role: Role) => void;
}) {
return (
<Select value={value} onValueChange={(v) => onChange(v as Role)}>
<SelectTrigger className="w-full">
<SelectValue placeholder={value} />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{ROLE_OPTIONS.map((r) => (
<SelectItem key={r} value={r}>
{r}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
);
}