2026-03-25 22:15:06 +01:00
|
|
|
|
import { A, useNavigate } from '@solidjs/router';
|
|
|
|
|
|
import { createResource, createSignal, For, Show } from 'solid-js';
|
|
|
|
|
|
import { Search } from 'lucide-solid';
|
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
|
|
|
|
import AdminShell from '~/components/AdminShell';
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
|
|
|
|
|
|
const API = '/api/gateway';
|
|
|
|
|
|
|
|
|
|
|
|
type Role = {
|
|
|
|
|
|
id: string;
|
2026-03-25 22:15:06 +01:00
|
|
|
|
key: string;
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
name: string;
|
2026-03-25 22:15:06 +01:00
|
|
|
|
audience: string;
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
description?: string;
|
2026-03-25 22:15:06 +01:00
|
|
|
|
department_name?: string;
|
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
|
users_assigned: number;
|
|
|
|
|
|
permissions_count: number;
|
|
|
|
|
|
created_at: string;
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-25 22:15:06 +01:00
|
|
|
|
type ListResponse = {
|
|
|
|
|
|
roles: Role[];
|
|
|
|
|
|
total: number;
|
|
|
|
|
|
page: number;
|
|
|
|
|
|
per_page: number;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
async function loadRoles(params: { q: string; page: number }): Promise<ListResponse> {
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
try {
|
2026-03-25 22:15:06 +01:00
|
|
|
|
const qs = new URLSearchParams({
|
|
|
|
|
|
audience: 'INTERNAL',
|
|
|
|
|
|
q: params.q,
|
|
|
|
|
|
page: String(params.page),
|
|
|
|
|
|
per_page: '8',
|
|
|
|
|
|
});
|
|
|
|
|
|
const res = await fetch(`${API}/api/admin/roles?${qs}`);
|
|
|
|
|
|
if (!res.ok) throw new Error('Failed');
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
const data = await res.json();
|
2026-03-25 22:15:06 +01:00
|
|
|
|
if (data.roles) return data;
|
|
|
|
|
|
// flat array fallback
|
|
|
|
|
|
return { roles: Array.isArray(data) ? data : [], total: 0, page: 1, per_page: 8 };
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
return { roles: [], total: 0, page: 1, per_page: 8 };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function formatDate(iso: string) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const d = new Date(iso);
|
|
|
|
|
|
return d.toISOString().slice(0, 10);
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
} catch {
|
2026-03-25 22:15:06 +01:00
|
|
|
|
return '—';
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-25 22:15:06 +01:00
|
|
|
|
export default function InternalRolesListPage() {
|
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
|
const [search, setSearch] = createSignal('');
|
|
|
|
|
|
const [debouncedSearch, setDebouncedSearch] = createSignal('');
|
|
|
|
|
|
const [page, setPage] = createSignal(1);
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
const [deleting, setDeleting] = createSignal('');
|
2026-03-25 22:15:06 +01:00
|
|
|
|
|
|
|
|
|
|
let debounceTimer: ReturnType<typeof setTimeout>;
|
|
|
|
|
|
const handleSearch = (val: string) => {
|
|
|
|
|
|
setSearch(val);
|
|
|
|
|
|
clearTimeout(debounceTimer);
|
|
|
|
|
|
debounceTimer = setTimeout(() => {
|
|
|
|
|
|
setDebouncedSearch(val);
|
|
|
|
|
|
setPage(1);
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const [data, { refetch }] = createResource(
|
|
|
|
|
|
() => ({ q: debouncedSearch(), page: page() }),
|
|
|
|
|
|
loadRoles,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const totalPages = () => {
|
|
|
|
|
|
const d = data();
|
|
|
|
|
|
if (!d || d.per_page === 0) return 1;
|
|
|
|
|
|
return Math.max(1, Math.ceil(d.total / d.per_page));
|
|
|
|
|
|
};
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
|
|
|
|
|
|
const handleDelete = async (id: string, name: string) => {
|
|
|
|
|
|
if (!confirm(`Delete role "${name}"? This cannot be undone.`)) return;
|
2026-03-25 22:15:06 +01:00
|
|
|
|
setDeleting(id);
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
try {
|
|
|
|
|
|
const res = await fetch(`${API}/api/admin/roles/${id}`, { method: 'DELETE' });
|
2026-03-25 22:15:06 +01:00
|
|
|
|
if (!res.ok) throw new Error('Failed');
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
refetch();
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setDeleting('');
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<AdminShell>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
<div class="flex flex-col -mx-6 -mt-6 min-h-full">
|
|
|
|
|
|
<div class="p-6 flex-1 max-w-[1600px] mx-auto w-full">
|
|
|
|
|
|
{/* Header & Title */}
|
|
|
|
|
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between mb-8">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<h1 class="text-[32px] font-bold text-[#050026] leading-tight">Internal Role Management</h1>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="flex items-center gap-3">
|
|
|
|
|
|
<button class="inline-flex h-11 items-center justify-center rounded-xl border border-[#d9dde6] bg-white px-6 text-[14px] font-semibold text-[#050026] transition-colors hover:bg-[#f8f9fc]">
|
|
|
|
|
|
Export Data
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</button>
|
|
|
|
|
|
<A
|
|
|
|
|
|
href="/admin/roles/create"
|
2026-03-26 00:06:47 +01:00
|
|
|
|
class="inline-flex h-11 items-center justify-center rounded-xl bg-[#050026] px-6 text-[14px] font-semibold text-white transition-colors hover:bg-[#0a0044]"
|
2026-03-25 22:15:06 +01:00
|
|
|
|
>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
<span class="mr-2 text-lg leading-none">+</span> Add Role
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</A>
|
|
|
|
|
|
</div>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
</div>
|
2026-03-25 22:15:06 +01:00
|
|
|
|
|
2026-03-26 00:06:47 +01:00
|
|
|
|
<section class="rounded-[24px] border border-[#e2e6ee] bg-[#f7f7f8] p-1.5 h-full">
|
|
|
|
|
|
<div class="rounded-[20px] bg-white p-5">
|
|
|
|
|
|
|
|
|
|
|
|
{/* Tabs */}
|
|
|
|
|
|
<div class="flex gap-6 mb-6 border-b border-[#e2e6ee]">
|
|
|
|
|
|
<For each={['Active Roles', 'Archived Roles']}>
|
|
|
|
|
|
{(t) => (
|
|
|
|
|
|
<button
|
|
|
|
|
|
class={`pb-3 text-[14px] font-bold transition-colors border-b-2 ${
|
|
|
|
|
|
t === 'Active Roles'
|
|
|
|
|
|
? 'border-[#050026] text-[#050026]'
|
|
|
|
|
|
: 'border-transparent text-[#8087a0] hover:text-[#050026]'
|
|
|
|
|
|
}`}
|
|
|
|
|
|
>
|
|
|
|
|
|
{t}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</For>
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-03-26 00:06:47 +01:00
|
|
|
|
{/* Filters Row */}
|
|
|
|
|
|
<div class="flex flex-col gap-4 md:flex-row items-center mb-6">
|
|
|
|
|
|
<div class="relative w-full md:w-[320px]">
|
|
|
|
|
|
<div class="absolute inset-y-0 left-4 flex items-center pointer-events-none">
|
|
|
|
|
|
<svg class="h-5 w-5 text-[#a0aabf]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
placeholder="Search roles..."
|
|
|
|
|
|
value={search()}
|
|
|
|
|
|
onInput={(e) => handleSearch(e.currentTarget.value)}
|
|
|
|
|
|
class="h-11 w-full rounded-xl border border-[#d9dde6] bg-[#f9fafb] pl-11 pr-4 text-[14px] text-[#050026] outline-none transition-colors focus:border-[#050026] focus:bg-white"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="h-11 w-full md:w-[200px] rounded-xl border border-[#d9dde6] bg-[#f9fafb]"></div>
|
|
|
|
|
|
<div class="flex-1"></div>
|
|
|
|
|
|
<Show when={!data.loading}>
|
|
|
|
|
|
<span class="text-[13px] text-[#8087a0] font-medium">
|
|
|
|
|
|
Showing {((page() - 1) * (data()?.per_page ?? 8)) + 1}–{Math.min(page() * (data()?.per_page ?? 8), data()?.total ?? 0)} of {data()?.total ?? 0} roles
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</Show>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* Table */}
|
|
|
|
|
|
<div class="overflow-x-auto">
|
|
|
|
|
|
<table class="w-full min-w-[1000px] border-collapse">
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr class="bg-[#050026] text-left text-white">
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider rounded-tl-xl whitespace-nowrap">ROLE ID</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider whitespace-nowrap">ROLE NAME</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider whitespace-nowrap">CATEGORY</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider whitespace-nowrap">ASSOCIATED USERS</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider whitespace-nowrap">ACTIVE PERMISSIONS</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider whitespace-nowrap">LAST UPDATED</th>
|
|
|
|
|
|
<th class="px-6 py-4 text-[11px] font-bold uppercase tracking-wider text-right rounded-tr-xl whitespace-nowrap">ACTION</th>
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</tr>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
<Show when={data.loading}>
|
|
|
|
|
|
<tr><td colspan="7" class="text-center py-12 text-[#8087a0] text-[14px]">Loading roles...</td></tr>
|
|
|
|
|
|
</Show>
|
|
|
|
|
|
<Show when={!data.loading && (data()?.roles?.length ?? 0) === 0}>
|
|
|
|
|
|
<tr><td colspan="7" class="text-center py-12 text-[#8087a0] text-[14px]">No internal roles found.</td></tr>
|
|
|
|
|
|
</Show>
|
|
|
|
|
|
<For each={data()?.roles ?? []}>
|
|
|
|
|
|
{(role) => (
|
|
|
|
|
|
<tr class="border-b border-[#e2e6ee] bg-white transition-colors hover:bg-[#f8f9fc]">
|
|
|
|
|
|
<td class="px-6 py-4 text-[14px] font-semibold text-[#64748b]">{role.key.toUpperCase()}</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-[14px] font-bold text-[#050026]">{role.name}</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-[14px] text-[#475569]">{role.department_name || '—'}</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-[14px] font-semibold text-[#050026]">
|
|
|
|
|
|
<div class="flex -space-x-2 mr-2 inline-flex items-center">
|
|
|
|
|
|
{/* Placeholder for avatar group if users > 0 */}
|
|
|
|
|
|
<Show when={role.users_assigned > 0} fallback={<span class="text-[#c1c7d0] font-normal">0 users</span>}>
|
|
|
|
|
|
<div class="h-6 w-6 rounded-full bg-[#e2e8f0] border-2 border-white flex items-center justify-center text-[10px] font-bold text-[#475569]">U</div>
|
|
|
|
|
|
<div class="h-6 w-6 rounded-full bg-[#f1f5f9] border-2 border-white flex items-center justify-center text-[10px] font-bold text-[#64748b]">+{role.users_assigned - 1}</div>
|
|
|
|
|
|
</Show>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
<td class="px-6 py-4">
|
|
|
|
|
|
<span class="inline-flex items-center px-3 py-1 rounded-lg bg-[#f8f9fc] text-[#050026] text-[12px] font-bold border border-[#e2e6ee]">
|
|
|
|
|
|
{role.permissions_count} Permissions
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</span>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
</td>
|
|
|
|
|
|
<td class="px-6 py-4 text-[14px] text-[#475569]">{formatDate(role.created_at)}</td>
|
|
|
|
|
|
<td class="px-6 py-4">
|
|
|
|
|
|
<div class="flex items-center justify-end gap-2">
|
|
|
|
|
|
<A
|
|
|
|
|
|
title="View Details"
|
|
|
|
|
|
href={`/admin/roles/${role.id}`}
|
|
|
|
|
|
class="flex h-8 w-8 items-center justify-center rounded-lg border border-[#e2e6ee] bg-white text-[#64748b] hover:bg-[#f8f9fc] hover:text-[#050026] transition-colors"
|
|
|
|
|
|
>
|
|
|
|
|
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</A>
|
|
|
|
|
|
<A
|
|
|
|
|
|
title="Edit"
|
|
|
|
|
|
href={`/admin/roles/${role.id}/edit`}
|
|
|
|
|
|
class="flex h-8 w-8 items-center justify-center rounded-lg border border-[#e2e6ee] bg-white text-[#64748b] hover:bg-[#f8f9fc] hover:text-[#050026] transition-colors"
|
|
|
|
|
|
>
|
|
|
|
|
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</A>
|
|
|
|
|
|
<button
|
|
|
|
|
|
title="Archive"
|
|
|
|
|
|
disabled={deleting() === role.id}
|
|
|
|
|
|
onClick={() => handleDelete(role.id, role.name)}
|
|
|
|
|
|
class="flex h-8 w-8 items-center justify-center rounded-lg border border-[#e2e6ee] bg-white text-[#64748b] hover:bg-[#f8f9fc] hover:text-[#050026] transition-colors"
|
|
|
|
|
|
>
|
|
|
|
|
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" />
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
)}
|
|
|
|
|
|
</For>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
2026-03-25 22:15:06 +01:00
|
|
|
|
|
2026-03-26 00:06:47 +01:00
|
|
|
|
{/* Pagination */}
|
|
|
|
|
|
<Show when={totalPages() > 1}>
|
|
|
|
|
|
<div class="mt-6 flex items-center justify-between border-t border-[#e2e6ee] pt-4">
|
|
|
|
|
|
<span class="text-[13px] font-medium text-[#8087a0]">Page {page()} of {totalPages()}</span>
|
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
|
<button
|
|
|
|
|
|
disabled={page() === 1}
|
|
|
|
|
|
onClick={() => setPage((p) => Math.max(1, p - 1))}
|
|
|
|
|
|
class="flex h-9 w-9 items-center justify-center rounded-lg border border-[#e2e6ee] bg-white text-[#64748b] hover:bg-[#f8f9fc] hover:text-[#050026] disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
|
>
|
|
|
|
|
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" /></svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
|
|
|
disabled={page() >= totalPages()}
|
|
|
|
|
|
onClick={() => setPage((p) => Math.min(totalPages(), p + 1))}
|
|
|
|
|
|
class="flex h-9 w-9 items-center justify-center rounded-lg border border-[#e2e6ee] bg-white text-[#64748b] hover:bg-[#f8f9fc] hover:text-[#050026] disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
|
|
|
|
|
|
>
|
|
|
|
|
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" /></svg>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
2026-03-25 22:15:06 +01:00
|
|
|
|
</div>
|
2026-03-26 00:06:47 +01:00
|
|
|
|
</Show>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</section>
|
2026-03-24 02:36:40 +01:00
|
|
|
|
</div>
|
ui(step-1): match reference layout for dept/designation/employees/roles pages
- All pages: white sticky page header + tab bar with orange underline,
-mx-6 -mt-6 negative margin to stretch headers edge-to-edge
- department: full columns (ID, Name, Description, Created By, etc.),
icon-only action buttons, navy Add Department button
- designation: Designations List / Add Designation tabs, status filter
dropdown, inline create/edit form, full columns with status badge
- employees: View/Add tabs, icon-only action buttons, status badges
- roles/index: clean table with Name+code subtext, Description, actions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 04:47:05 +01:00
|
|
|
|
</div>
|
feat(admin): build complete admin panel with UI parity and search/filter
- Implement all admin management pages (employees, users, jobs, leads, orders, companies, customers, candidates, approval, invoices, reviews, support, KB, pricing, coupons, credits, discounts, tax, reports, ledger)
- Implement 9 professional vertical pages (developers, designers, tutors, video editors, photographers, makeup artists, graphic designers, social media managers, fitness trainers)
- Implement internal/external dashboard and role management with builder UI
- Fix tab styling: replace inline border-bottom styles with admin-tab CSS class across 8+ pages
- Add search/filter functionality to invoice and review pages
- Add toggle status (activate/deactivate) to employees page with PATCH /api/admin/employees/{id}
- Align UI styling with NextJS admin panel for visual parity
- Add stat cards to approval page showing counts by status
- Implement graceful empty states for all list views
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-19 13:04:10 +01:00
|
|
|
|
</AdminShell>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|