mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
added users permission card
This commit is contained in:
parent
88b6ad7f4b
commit
c3ae5d3cf5
3 changed files with 178 additions and 0 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
44
src/app/portfolio/[slug]/(portfolio)/settings/roles.tsx
Normal file
44
src/app/portfolio/[slug]/(portfolio)/settings/roles.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue