1- "use client" ;
2-
3- import { useEffect , useState } from "react" ;
41import Link from "next/link" ;
52import SettingsCard from "@/app/home/settings/_components/SettingsCard" ;
63import { H1 } from "@/components/shared/dashboard" ;
74import { settingsCardData } from "@/constants/settings" ;
8- import { createClientClientComponent } from "@/utils/supabase/client" ;
95import PageContainer from "../_components/PageContainer" ;
106
11- import Loading from "./loading" ;
12-
13- type RolePermissions = {
14- dashboard : boolean ;
15- kanban : boolean ;
16- time_tracker : boolean ;
17- interns : boolean ;
18- applicants : boolean ;
19- inhouse : boolean ;
20- clients : boolean ;
21- projects : boolean ;
22- settings : boolean ;
23- orgchart : boolean ;
24- resume ?: boolean ;
25- permissions ?: boolean ;
26- roles ?: boolean ;
27- } ;
28-
29- type PermissionKey = keyof RolePermissions ;
30-
31- // Admin-only cards - only visible to Admin role (role_id = 1)
32- // Hidden from: Codev (10), Intern (4), HR (2), and all other non-admin roles
33- const ADMIN_ONLY_PATHS = [
34- "/home/settings/news-banners" ,
35- "/home/settings/surveys" ,
36- "/home/settings/services" ,
37- ] ;
38-
39- // Map specific settings routes to their respective permission keys
40- const settingsPermissionMap : Record < string , PermissionKey > = {
41- "/home/settings/profile" : "resume" ,
42- "/home/settings/permissions" : "permissions" ,
43- "/home/settings/roles" : "roles" ,
44- } ;
45-
467const Settings = ( ) => {
47- const [ supabase , setSupabase ] = useState < any > ( null ) ;
48- const [ roleId , setRoleId ] = useState < number | null > ( null ) ;
49- const [ rolePermissions , setRolePermissions ] = useState < RolePermissions | null > ( null ) ;
50- const [ loading , setLoading ] = useState < boolean > ( true ) ;
51-
52- // Initialize Supabase client
53- useEffect ( ( ) => {
54- const client = createClientClientComponent ( ) ;
55- setSupabase ( client ) ;
56- } , [ ] ) ;
57-
58- // Get current user's role_id by mapping auth email to codev.role_id
59- useEffect ( ( ) => {
60- if ( ! supabase ) return ;
61-
62- async function fetchUserRole ( ) {
63- try {
64- // Get auth user
65- const { data : { session } , error : sessionError } = await supabase . auth . getSession ( ) ;
66-
67- if ( sessionError || ! session ?. user ?. email ) {
68- setLoading ( false ) ;
69- return ;
70- }
71-
72- // Map email to codev profile to get role_id
73- const { data : codevData , error : codevError } = await supabase
74- . from ( "codev" )
75- . select ( "role_id, first_name, last_name" )
76- . eq ( "email_address" , session . user . email )
77- . single ( ) ;
78-
79- if ( codevError || ! codevData ) {
80- setLoading ( false ) ;
81- return ;
82- }
83-
84- setRoleId ( codevData . role_id ) ;
85- } catch ( err ) {
86- setLoading ( false ) ;
87- }
88- }
89-
90- fetchUserRole ( ) ;
91- } , [ supabase ] ) ;
92-
93- // Fetch role permissions once we have roleId
94- useEffect ( ( ) => {
95- if ( ! supabase || roleId === null ) return ;
96-
97- async function fetchRolePermissions ( ) {
98- try {
99- const { data : roleData , error : roleError } = await supabase
100- . from ( "roles" )
101- . select (
102- "id, name, dashboard, kanban, time_tracker, interns, applicants, inhouse, clients, projects, settings, orgchart, resume, permissions, roles"
103- )
104- . eq ( "id" , roleId )
105- . single ( ) ;
106-
107- if ( roleError || ! roleData ) {
108- setLoading ( false ) ;
109- return ;
110- }
111-
112- setRolePermissions ( roleData ) ;
113- } catch ( err ) {
114- // Error fetching role permissions
115- } finally {
116- setLoading ( false ) ;
117- }
118- }
119-
120- fetchRolePermissions ( ) ;
121- } , [ supabase , roleId ] ) ;
122-
123- // Helper function to check a permission
124- const hasPermission = ( permission : PermissionKey ) : boolean => {
125- return ! ! rolePermissions ?. [ permission ] ;
126- } ;
127-
128- if ( loading ) {
129- return (
130- < PageContainer >
131- < Loading />
132- </ PageContainer >
133- ) ;
134- }
135-
136- if ( ! rolePermissions || roleId === null ) {
137- return (
138- < PageContainer >
139- < div className = "mx-auto p-4" > Unable to determine permissions.</ div >
140- </ PageContainer >
141- ) ;
142- }
143-
144- // Filter settings cards based on role
145- const filteredCards = settingsCardData . filter ( ( card ) => {
146- // Rule 1: Admin-only cards (News Banners, Surveys, Services)
147- // ONLY visible if user has role_id = 1 (Admin)
148- // BLOCKED for: Codev (10), Intern (4), HR (2), all others
149- if ( ADMIN_ONLY_PATHS . includes ( card . path ) ) {
150- return roleId === 1 ;
151- }
152-
153- // Rule 2: Check specific permission mapping
154- // For cards like Profile, Permissions, Roles
155- const permissionKey = settingsPermissionMap [ card . path ] ;
156- if ( permissionKey ) {
157- return hasPermission ( permissionKey ) ;
158- }
159-
160- // Rule 3: Default fallback - require general "settings" permission
161- return hasPermission ( "settings" ) ;
162- } ) ;
163-
1648 return (
1659 < PageContainer maxWidth = "xl" >
16610 < H1 > Settings</ H1 >
16711 < div className = "mt-4 grid w-full grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4" >
168- { filteredCards . map ( ( card ) => (
12+ { settingsCardData . map ( ( card ) => (
16913 < Link key = { card . path } href = { card . path } >
17014 < SettingsCard
17115 imageName = { card . imageName }
@@ -180,4 +24,4 @@ const Settings = () => {
18024 ) ;
18125} ;
18226
183- export default Settings ;
27+ export default Settings ;
0 commit comments