Skip to content

Commit

Permalink
feature: permission management in employee page
Browse files Browse the repository at this point in the history
  • Loading branch information
Dragonprod committed Feb 26, 2024
1 parent baa642d commit f57f0dc
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 113 deletions.
36 changes: 33 additions & 3 deletions app/employees/Employee.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, { useState } from "react"
import React, { useEffect, useState } from "react"
import { ChevronDownIcon } from "@radix-ui/react-icons"

import { Database } from "@/lib/supabase/db-types"
import { useSupabase } from "@/lib/supabase/supabase-provider"
import { roleMapper } from "@/lib/utils"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
Expand All @@ -24,6 +26,7 @@ type Profile = Database["rtu_mirea"]["Tables"]["profiles"]["Row"]
export interface EmployeeProps {
employee: Employee & {
profile?: Profile
role?: string
}
}

Expand All @@ -36,10 +39,33 @@ const getName = (employee: Employee & { profile?: Profile }) => {
}

export function Employee({ employee }: EmployeeProps) {
const { supabase } = useSupabase()
const [role, setRole] = useState("Просмотр")

const handleRoleChange = (role: string) => {
useEffect(() => {
setRole(roleMapper.get(employee.role as string) || "Просмотр")
}, [employee.role])

const handleRoleChange = async (role: string) => {
setRole(role)

role === "Просмотр" &&
(await supabase
.schema("rtu_mirea")
.from("extended_permissions")
.delete()
.eq("user_id", employee.user_id!))

role !== "Просмотр" &&
(await supabase
.schema("rtu_mirea")
.from("extended_permissions")
.upsert({
department: employee.department!,
human_uuid: employee.human_uuid!,
role: role === "Админ" ? "admin" : "editor",
user_id: employee.user_id!,
}))
}

return (
Expand All @@ -63,7 +89,11 @@ export function Employee({ employee }: EmployeeProps) {
</div>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" className="ml-auto">
<Button
variant="outline"
className="ml-auto"
disabled={!employee.user_id!}
>
{role}
<ChevronDownIcon className="ml-2 h-4 w-4 text-muted-foreground" />
</Button>
Expand Down
23 changes: 21 additions & 2 deletions app/employees/EmployeesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,29 @@ export function EmployeesList({
)
).map((res) => res.data) as Profile[]

const permissions = (
await Promise.all(
employees
.filter((employee) => employee.human_uuid)
.map((employee) => {
return supabase
.schema("rtu_mirea")
.from("extended_permissions")
.select("*")
.eq("human_uuid", employee.human_uuid)
.maybeSingle()
})
)
).map((res) => res.data) as ExtendedPermission[]

const res = employees.map((employee) => {
return {
...employee,
profile: profiles.find((profile) => profile.id === employee.user_id),
role: permissions
.filter(Boolean)
.find((permission) => permission.human_uuid === employee.human_uuid)
?.role,
}
})

Expand Down Expand Up @@ -136,8 +155,8 @@ export function EmployeesList({
key={i}
className="flex flex-row items-center justify-between"
>
<Skeleton key={i} className="h-10 w-80" />
<Skeleton key={i} className="h-10 w-24" />
<Skeleton key={i + 1} className="h-10 w-80" />
<Skeleton key={i + 2} className="h-10 w-24" />
</div>
))}

Expand Down
133 changes: 26 additions & 107 deletions app/students/StudentsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"

import React, { useState } from "react"
import React from "react"
import { useQuery } from "@tanstack/react-query"
import { User2Icon } from "lucide-react"

Expand Down Expand Up @@ -42,89 +42,25 @@ export default function StudentsTable({
string[]
>([])

const [count, setCount] = useState(0)
const [page, setPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
const [count, setCount] = React.useState(0)
const [page, setPage] = React.useState(1)
const [pageSize, setPageSize] = React.useState(10)
const [searchQuery, setSearchQuery] = React.useState("")

// const {
// data: employees,
// error,
// isLoading,
// } = useQuery(
// [
// "students",
// page,
// pageSize,
// availableGroups,
// availableDisciplines,
// selectedGroups,
// selectedDisciplines,
// searchQuery,
// ],
// async () => {
// let students
//
// if (!searchQuery) {
// const { data } = (await supabase
// .schema("rtu_mirea")
// .from("students")
// .select("*")
// .range((page - 1) * pageSize, page * pageSize - 1)
// .throwOnError()) as unknown as { data: Student[] }
//
// students = data ?? []
// } else {
// if (searchQuery.length < 3) return []
// const { data } = await supabase
// .schema("rtu_mirea")
// .rpc("search_students", {
// _limit: pageSize,
// _offset: (page - 1) * pageSize,
// _department: department ?? undefined,
// _academic_groups:
// selectedGroups.length > 0 ? selectedGroups : undefined,
// _debts_disciplines:
// selectedDisciplines.length > 0 ? selectedDisciplines : undefined,
// _name: searchQuery,
// })
// .throwOnError()
//
// if (
// !searchQuery &&
// (selectedGroups.length || selectedDisciplines.length)
// ) {
// const { data } = await supabase
// .schema("rtu_mirea")
// .rpc("search_students", {
// _limit: pageSize,
// _offset: (page - 1) * pageSize,
// _department: department ?? undefined,
// _academic_groups:
// selectedGroups.length > 0 ? selectedGroups : undefined,
// _debts_disciplines:
// selectedDisciplines.length > 0
// ? selectedDisciplines
// : undefined,
// })
// .throwOnError()
// }
// students = data ?? []
// }
//
// const { count } = await supabase
// .schema("rtu_mirea")
// .from("students")
// .select("id", { count: "exact", head: true })
//
// setCount(count ?? 0)
//
// return students
// },
// {
// refetchOnWindowFocus: false,
// }
// )
const getCount = async () => {
const { data } = await supabase
.schema("rtu_mirea")
.rpc("search_students_count", {
_department: department ?? undefined,
_academic_groups:
selectedGroups.length > 0 ? selectedGroups : undefined,
_debts_disciplines:
selectedDisciplines.length > 0 ? selectedDisciplines : undefined,
_name: searchQuery.length > 0 ? searchQuery : undefined,
})
.throwOnError()
setCount(data ?? 0)
}

const { data, error, isLoading } = useQuery(
[
Expand All @@ -139,8 +75,8 @@ export default function StudentsTable({
const { data } = await supabase
.schema("rtu_mirea")
.rpc("search_students", {
_limit: 2000,
_offset: 0,
_limit: pageSize,
_offset: (page - 1) * pageSize,
_department: department ?? undefined,
_academic_groups:
selectedGroups.length > 0 ? selectedGroups : undefined,
Expand All @@ -149,6 +85,9 @@ export default function StudentsTable({
_name: searchQuery.length > 0 ? searchQuery : undefined,
})
.throwOnError()

await getCount()

return (data ?? [])
.filter((student) => student)
.map((student) => ({
Expand All @@ -161,28 +100,7 @@ export default function StudentsTable({
}
)

const {
data: length,
error: lengthError,
isLoading: lengthIsLoading,
} = useQuery(
["length", availableGroups, availableDisciplines],
async () => {
const { data } = await supabase
.schema("rtu_mirea")
.rpc("get_debtors_count", {
_department: department ?? undefined,
})
.throwOnError()

return data
},
{
refetchOnWindowFocus: false,
}
)

return lengthIsLoading ? (
return isLoading ? (
<Skeleton className="w-[300px]" />
) : (
<DataTable
Expand Down Expand Up @@ -212,7 +130,8 @@ export default function StudentsTable({
}
}}
tableOptions={{
pageCount: Math.ceil(data?.length ?? 0 / 10),
manualPagination: true,
pageCount: Math.ceil(count / pageSize),
}}
/>
)
Expand Down
1 change: 0 additions & 1 deletion components/table/DataTablePagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {

interface DataTablePaginationProps<TData> {
table: Table<TData>

count?: number
page?: number
pageSize?: number
Expand Down
12 changes: 12 additions & 0 deletions lib/supabase/db-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -829,20 +829,23 @@ export interface Database {
Row: {
created_at: string
department: string | null
human_uuid: string
id: number
role: string
user_id: string
}
Insert: {
created_at?: string
department?: string | null
human_uuid: string
id?: number
role: string
user_id: string
}
Update: {
created_at?: string
department?: string | null
human_uuid: string
id?: number
role?: string
user_id?: string
Expand Down Expand Up @@ -1169,6 +1172,15 @@ export interface Database {
updated_at: string | null
}[]
}
search_students_count: {
Args: {
_name?: string
_academic_groups?: string[]
_debts_disciplines?: string[]
_department?: string
}
Returns: number
}
}
Enums: {
[_ in never]: never
Expand Down
5 changes: 5 additions & 0 deletions lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

export const roleMapper = new Map<string, string>([
["admin", "Админ"],
["editor", "Редактор"],
])

0 comments on commit f57f0dc

Please sign in to comment.