Added base for role table
This commit is contained in:
parent
a11e0d4da3
commit
11d1e33486
|
|
@ -14,7 +14,7 @@
|
|||
"@mantine/form": "^7.4.2",
|
||||
"@mantine/hooks": "^7.4.2",
|
||||
"@mantine/notifications": "^7.4.2",
|
||||
"@prisma/client": "5.7.1",
|
||||
"@prisma/client": "5.8.1",
|
||||
"@tanstack/react-query": "^4.36.1",
|
||||
"@tanstack/react-query-devtools": "^4.36.1",
|
||||
"@tanstack/react-table": "^8.11.7",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ settings:
|
|||
dependencies:
|
||||
'@auth/prisma-adapter':
|
||||
specifier: ^1.0.16
|
||||
version: 1.0.16(@prisma/client@5.7.1)
|
||||
version: 1.0.16(@prisma/client@5.8.1)
|
||||
'@mantine/core':
|
||||
specifier: ^7.4.2
|
||||
version: 7.4.2(@mantine/hooks@7.4.2)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
|
@ -21,8 +21,8 @@ dependencies:
|
|||
specifier: ^7.4.2
|
||||
version: 7.4.2(@mantine/core@7.4.2)(@mantine/hooks@7.4.2)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@prisma/client':
|
||||
specifier: 5.7.1
|
||||
version: 5.7.1(prisma@5.8.1)
|
||||
specifier: 5.8.1
|
||||
version: 5.8.1(prisma@5.8.1)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^4.36.1
|
||||
version: 4.36.1(react-dom@18.2.0)(react@18.2.0)
|
||||
|
|
@ -159,13 +159,13 @@ packages:
|
|||
preact-render-to-string: 5.2.3(preact@10.11.3)
|
||||
dev: false
|
||||
|
||||
/@auth/prisma-adapter@1.0.16(@prisma/client@5.7.1):
|
||||
/@auth/prisma-adapter@1.0.16(@prisma/client@5.8.1):
|
||||
resolution: {integrity: sha512-i7+XCxrbv5n8Yp9r+FznvnOBG7BrjpfmXr4Fl7pL7LPgTGhDJPE10BokVf5tGTsR8SGnAp04qhBzgjTrTrmpPQ==}
|
||||
peerDependencies:
|
||||
'@prisma/client': '>=2.26.0 || >=3 || >=4 || >=5'
|
||||
dependencies:
|
||||
'@auth/core': 0.22.0
|
||||
'@prisma/client': 5.7.1(prisma@5.8.1)
|
||||
'@prisma/client': 5.8.1(prisma@5.8.1)
|
||||
transitivePeerDependencies:
|
||||
- nodemailer
|
||||
dev: false
|
||||
|
|
@ -509,8 +509,8 @@ packages:
|
|||
dev: true
|
||||
optional: true
|
||||
|
||||
/@prisma/client@5.7.1(prisma@5.8.1):
|
||||
resolution: {integrity: sha512-TUSa4nUcC4nf/e7X3jyO1pEd6XcI/TLRCA0KjkA46RDIpxUaRsBYEOqITwXRW2c0bMFyKcCRXrH4f7h4q9oOlg==}
|
||||
/@prisma/client@5.8.1(prisma@5.8.1):
|
||||
resolution: {integrity: sha512-xQtMPfbIwLlbm0VVIVQY2yqQVOxPwRQhvIp7Z3m2900g1bu/zRHKhYZJQWELqmjl6d8YwBy0K2NvMqh47v1ubw==}
|
||||
engines: {node: '>=16.13'}
|
||||
requiresBuild: true
|
||||
peerDependencies:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
-- CreateTable
|
||||
CREATE TABLE `Role` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`code` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
|
||||
UNIQUE INDEX `Role_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Permission` (
|
||||
`id` VARCHAR(191) NOT NULL,
|
||||
`code` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NOT NULL DEFAULT '',
|
||||
|
||||
UNIQUE INDEX `Permission_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `_RoleToUser` (
|
||||
`A` VARCHAR(191) NOT NULL,
|
||||
`B` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `_RoleToUser_AB_unique`(`A`, `B`),
|
||||
INDEX `_RoleToUser_B_index`(`B`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `_PermissionToRole` (
|
||||
`A` VARCHAR(191) NOT NULL,
|
||||
`B` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `_PermissionToRole_AB_unique`(`A`, `B`),
|
||||
INDEX `_PermissionToRole_B_index`(`B`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `_PermissionToUser` (
|
||||
`A` VARCHAR(191) NOT NULL,
|
||||
`B` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `_PermissionToUser_AB_unique`(`A`, `B`),
|
||||
INDEX `_PermissionToUser_B_index`(`B`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_RoleToUser` ADD CONSTRAINT `_RoleToUser_A_fkey` FOREIGN KEY (`A`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_RoleToUser` ADD CONSTRAINT `_RoleToUser_B_fkey` FOREIGN KEY (`B`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_PermissionToRole` ADD CONSTRAINT `_PermissionToRole_A_fkey` FOREIGN KEY (`A`) REFERENCES `Permission`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_PermissionToRole` ADD CONSTRAINT `_PermissionToRole_B_fkey` FOREIGN KEY (`B`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_PermissionToUser` ADD CONSTRAINT `_PermissionToUser_A_fkey` FOREIGN KEY (`A`) REFERENCES `Permission`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `_PermissionToUser` ADD CONSTRAINT `_PermissionToUser_B_fkey` FOREIGN KEY (`B`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE `Permission` ADD COLUMN `isActive` BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Role` ADD COLUMN `isActive` BOOLEAN NOT NULL DEFAULT false;
|
||||
|
|
@ -11,12 +11,14 @@ datasource db {
|
|||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
passwordHash String?
|
||||
photoProfile UserPhotoProfiles?
|
||||
id String @id @default(cuid())
|
||||
name String?
|
||||
email String? @unique
|
||||
emailVerified DateTime?
|
||||
passwordHash String?
|
||||
photoProfile UserPhotoProfiles?
|
||||
roles Role[]
|
||||
directPermissions Permission[]
|
||||
}
|
||||
|
||||
model UserPhotoProfiles {
|
||||
|
|
@ -24,4 +26,24 @@ model UserPhotoProfiles {
|
|||
userId String @unique
|
||||
path String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model Role {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
description String @default("")
|
||||
isActive Boolean @default(false)
|
||||
users User[]
|
||||
permissions Permission[]
|
||||
}
|
||||
|
||||
model Permission {
|
||||
id String @id @default(cuid())
|
||||
code String @unique
|
||||
name String
|
||||
description String @default("")
|
||||
isActive Boolean @default(false)
|
||||
roles Role[]
|
||||
directUsers User[]
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
"use client";
|
||||
import { Table, Text } from "@mantine/core";
|
||||
import {
|
||||
flexRender,
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
} from "@tanstack/react-table";
|
||||
import React from "react";
|
||||
import columns from "./columns";
|
||||
|
||||
export default function RolesTable() {
|
||||
const table = useReactTable({
|
||||
data: [],
|
||||
columns,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
defaultColumn: {
|
||||
cell: (props) => <Text>{props.getValue() as React.ReactNode}</Text>,
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: Add view when data is empty
|
||||
|
||||
return (
|
||||
<Table verticalSpacing="xs" horizontalSpacing="xs">
|
||||
{/* Thead */}
|
||||
<Table.Thead>
|
||||
{table.getHeaderGroups().map((headerGroup) => (
|
||||
<Table.Tr key={headerGroup.id}>
|
||||
{headerGroup.headers.map((header) => (
|
||||
<Table.Th
|
||||
key={header.id}
|
||||
style={{
|
||||
maxWidth: `${header.column.columnDef.maxSize}px`,
|
||||
width: `${header.getSize()}`,
|
||||
}}
|
||||
>
|
||||
{header.isPlaceholder
|
||||
? null
|
||||
: flexRender(
|
||||
header.column.columnDef.header,
|
||||
header.getContext()
|
||||
)}
|
||||
</Table.Th>
|
||||
))}
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Thead>
|
||||
|
||||
{/* Tbody */}
|
||||
<Table.Tbody>
|
||||
{table.getRowModel().rows.map((row) => (
|
||||
<Table.Tr key={row.id}>
|
||||
{row.getVisibleCells().map((cell) => (
|
||||
<Table.Td
|
||||
key={cell.id}
|
||||
style={{
|
||||
maxWidth: `${cell.column.columnDef.maxSize}px`,
|
||||
}}
|
||||
>
|
||||
{flexRender(
|
||||
cell.column.columnDef.cell,
|
||||
cell.getContext()
|
||||
)}
|
||||
</Table.Td>
|
||||
))}
|
||||
</Table.Tr>
|
||||
))}
|
||||
</Table.Tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import { createColumnHelper } from "@tanstack/react-table";
|
||||
import { StringifyOptions } from "querystring";
|
||||
|
||||
export interface RoleRow {
|
||||
id: string,
|
||||
code: string,
|
||||
name: string,
|
||||
permissionCount: number,
|
||||
userCount: number,
|
||||
}
|
||||
|
||||
const columnHelper = createColumnHelper<RoleRow>()
|
||||
|
||||
const columns = [
|
||||
columnHelper.accessor("id",{
|
||||
id: "sequence",
|
||||
header: "#",
|
||||
cell: props => props.row.index + 1,
|
||||
}),
|
||||
|
||||
columnHelper.accessor("code", {
|
||||
header: 'Code',
|
||||
}),
|
||||
|
||||
columnHelper.accessor("name", {
|
||||
header: "Name"
|
||||
}),
|
||||
|
||||
columnHelper.accessor("permissionCount", {
|
||||
header: "Permissions"
|
||||
}),
|
||||
|
||||
columnHelper.accessor("userCount", {
|
||||
header: "Users"
|
||||
}),
|
||||
]
|
||||
|
||||
export default columns;
|
||||
17
src/app/dashboard/(auth)/roles/page.tsx
Normal file
17
src/app/dashboard/(auth)/roles/page.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Card, Stack, Title } from "@mantine/core";
|
||||
import { Metadata } from "next";
|
||||
import React from "react";
|
||||
import RolesTable from "./_tables/RolesTable/RolesTable";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Roles",
|
||||
};
|
||||
|
||||
export default function RolesPage() {
|
||||
return <Stack>
|
||||
<Title order={1}>Roles</Title>
|
||||
<Card>
|
||||
<RolesTable />
|
||||
</Card>
|
||||
</Stack>;
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ export default function UsersTable({users}: Props) {
|
|||
}
|
||||
});
|
||||
|
||||
// TODO: Add view when data is empty
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table verticalSpacing="xs" horizontalSpacing="xs">
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const columnHelper = createColumnHelper<UserRow>()
|
|||
|
||||
const columns = [
|
||||
columnHelper.display({
|
||||
id: "seequence",
|
||||
id: "sequence",
|
||||
header: "#",
|
||||
cell: props => props.row.index + 1,
|
||||
size: 1
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ export default async function UsersPage({searchParams}: Props) {
|
|||
return null;
|
||||
}
|
||||
|
||||
// TODO: Add functinoality for create new user
|
||||
|
||||
return (
|
||||
<Stack className="flex flex-col">
|
||||
<Title order={1}>Users</Title>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const allMenu: MenuItem[] = [
|
|||
color: "grape",
|
||||
children: [
|
||||
{ label: "Users", link: "/users" },
|
||||
{ label: "Roles", link: "#" },
|
||||
{ label: "Roles", link: "/roles" },
|
||||
{ label: "Permissions", link: "#" },
|
||||
],
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user