This commit is contained in:
phaichayon
2026-06-11 12:46:57 +07:00
parent 1993d88306
commit 7a390cf0df
720 changed files with 100919 additions and 0 deletions

82
src/config/data-table.ts Normal file
View File

@@ -0,0 +1,82 @@
export type DataTableConfig = typeof dataTableConfig;
export const dataTableConfig = {
textOperators: [
{ label: 'Contains', value: 'iLike' as const },
{ label: 'Does not contain', value: 'notILike' as const },
{ label: 'Is', value: 'eq' as const },
{ label: 'Is not', value: 'ne' as const },
{ label: 'Is empty', value: 'isEmpty' as const },
{ label: 'Is not empty', value: 'isNotEmpty' as const }
],
numericOperators: [
{ label: 'Is', value: 'eq' as const },
{ label: 'Is not', value: 'ne' as const },
{ label: 'Is less than', value: 'lt' as const },
{ label: 'Is less than or equal to', value: 'lte' as const },
{ label: 'Is greater than', value: 'gt' as const },
{ label: 'Is greater than or equal to', value: 'gte' as const },
{ label: 'Is between', value: 'isBetween' as const },
{ label: 'Is empty', value: 'isEmpty' as const },
{ label: 'Is not empty', value: 'isNotEmpty' as const }
],
dateOperators: [
{ label: 'Is', value: 'eq' as const },
{ label: 'Is not', value: 'ne' as const },
{ label: 'Is before', value: 'lt' as const },
{ label: 'Is after', value: 'gt' as const },
{ label: 'Is on or before', value: 'lte' as const },
{ label: 'Is on or after', value: 'gte' as const },
{ label: 'Is between', value: 'isBetween' as const },
{ label: 'Is relative to today', value: 'isRelativeToToday' as const },
{ label: 'Is empty', value: 'isEmpty' as const },
{ label: 'Is not empty', value: 'isNotEmpty' as const }
],
selectOperators: [
{ label: 'Is', value: 'eq' as const },
{ label: 'Is not', value: 'ne' as const },
{ label: 'Is empty', value: 'isEmpty' as const },
{ label: 'Is not empty', value: 'isNotEmpty' as const }
],
multiSelectOperators: [
{ label: 'Has any of', value: 'inArray' as const },
{ label: 'Has none of', value: 'notInArray' as const },
{ label: 'Is empty', value: 'isEmpty' as const },
{ label: 'Is not empty', value: 'isNotEmpty' as const }
],
booleanOperators: [
{ label: 'Is', value: 'eq' as const },
{ label: 'Is not', value: 'ne' as const }
],
sortOrders: [
{ label: 'Asc', value: 'asc' as const },
{ label: 'Desc', value: 'desc' as const }
],
filterVariants: [
'text',
'number',
'range',
'date',
'dateRange',
'boolean',
'select',
'multiSelect'
] as const,
operators: [
'iLike',
'notILike',
'eq',
'ne',
'inArray',
'notInArray',
'isEmpty',
'isNotEmpty',
'lt',
'lte',
'gt',
'gte',
'isBetween',
'isRelativeToToday'
] as const,
joinOperators: ['and', 'or'] as const
};

191
src/config/infoconfig.ts Normal file
View File

@@ -0,0 +1,191 @@
import type { InfobarContent } from '@/components/ui/infobar';
export const workspacesInfoContent: InfobarContent = {
title: 'Workspaces Management',
sections: [
{
title: 'Overview',
description:
'The Workspaces page now reflects an app-owned organization model. You can review your current workspaces, create a new one, and control which workspace is active for organization-scoped product data.',
links: []
},
{
title: 'Creating Workspaces',
description:
'Creating a workspace inserts a new organization record, membership record, and makes it the active organization for the current user.',
links: []
},
{
title: 'Switching Workspaces',
description:
'You can switch between workspaces by clicking on a workspace in the list. The selected workspace becomes your active organization context, and all organization-specific features will use this workspace.',
links: []
},
{
title: 'Workspace Features',
description:
'Each workspace operates independently with its own team members, roles, permissions, and billing. This allows you to manage multiple projects or teams within a single account while keeping their data and settings separate.',
links: []
},
{
title: 'Server-Side Permission Checks',
description:
'Server-side permission checks now resolve the current Auth.js session, then load the active organization and membership from your own database before serving protected resources.',
links: []
}
]
};
export const teamInfoContent: InfobarContent = {
title: 'Team Management',
sections: [
{
title: 'Overview',
description:
'This route now serves as an app-owned placeholder for workspace membership management while the full post-Clerk team flow is still being built.',
links: []
},
{
title: 'Managing Team Members',
description:
'You can add, remove, and manage team members from this page. Invite new members by email, assign roles, and control their access levels. Each member can have different permissions based on their role.',
links: []
},
{
title: 'Roles and Permissions',
description:
'Roles and permissions are now app-owned data. The migration introduced a `memberships` table that can later back invites, role changes, and fine-grained permission management.',
links: []
},
{
title: 'Security Settings',
description:
"Manage security settings for your workspace, including authentication requirements, session management, and access controls. These settings help protect your organization's data and resources.",
links: []
},
{
title: 'Organization Settings',
description:
'Configure general organization settings such as name, logo, and other workspace preferences. These settings apply to the entire workspace and affect all team members.',
links: []
},
{
title: 'Navigation RBAC System',
description:
'The application includes a fully client-side navigation filtering system using the `useNav` hook. It supports `requireOrg`, `permission`, and `role` checks for instant access control. Navigation items are configured in `src/config/nav-config.ts` with `access` properties.',
links: []
}
]
};
export const billingInfoContent: InfobarContent = {
title: 'Billing & Plans',
sections: [
{
title: 'Overview',
description:
'This page now reads plan state from your own organization records instead of relying on Clerk Billing components.',
links: []
},
{
title: 'Available Plans',
description:
'For now, plan tiers are placeholders stored on each workspace. A billing provider and checkout flow can be layered on later without changing the route structure.',
links: []
},
{
title: 'Plan Features',
description:
'Each plan can still map to feature entitlements, but those checks should now come from app-owned workspace data rather than vendor-specific helpers.',
links: []
},
{
title: 'Access Control',
description:
'Plan and feature gates should now be enforced using app-owned server checks against the active workspace record.',
links: []
},
{
title: 'Setup Requirements',
description:
'When you are ready to implement real billing, introduce a dedicated subscription model and provider integration on top of the `organizations.plan` field.',
links: []
}
]
};
export const productInfoContent: InfobarContent = {
title: 'Product Management',
sections: [
{
title: 'Overview',
description:
'The Products page allows you to manage your product catalog. You can view all products in a table format with server-side functionality including sorting, filtering, pagination, and search capabilities. Use the "Add New" button to create new products.',
links: [
{
title: 'Product Management Guide',
url: '#'
}
]
},
{
title: 'Adding Products',
description:
'To add a new product, click the "Add New" button in the page header. You will be taken to a form where you can enter product details including name, description, price, category, and upload product images.',
links: [
{
title: 'Adding Products Documentation',
url: '#'
}
]
},
{
title: 'Editing Products',
description:
'You can edit existing products by clicking on a product row in the table. This will open the product edit form where you can modify any product information. Changes are saved automatically when you submit the form.',
links: [
{
title: 'Editing Products Guide',
url: '#'
}
]
},
{
title: 'Deleting Products',
description:
'Products can be deleted from the product listing table. Click the delete action for the product you want to remove. You will be asked to confirm the deletion before the product is permanently removed from your catalog.',
links: [
{
title: 'Product Deletion Policy',
url: '#'
}
]
},
{
title: 'Table Features',
description:
'The product table includes several powerful features to help you manage large product catalogs efficiently. You can sort columns by clicking on column headers, filter products using the filter controls, navigate through pages using pagination, and quickly find products using the search functionality.',
links: [
{
title: 'Table Features Documentation',
url: '#'
},
{
title: 'Sorting and Filtering Guide',
url: '#'
}
]
},
{
title: 'Product Fields',
description:
'Each product can have the following fields: Name (required), Description (optional text), Price (numeric value), Category (for organizing products), and Image Upload (for product photos). All fields can be edited when creating or updating a product.',
links: [
{
title: 'Product Fields Specification',
url: '#'
}
]
}
]
};

152
src/config/nav-config.ts Normal file
View File

@@ -0,0 +1,152 @@
import { NavGroup } from "@/types";
/**
* Navigation configuration with RBAC support
*
* This configuration is used for both the sidebar navigation and Cmd+K bar.
* Items are organized into groups, each rendered with a SidebarGroupLabel.
*
* RBAC Access Control:
* Each navigation item can have an `access` property that controls visibility
* based on permissions, plans, features, roles, and organization context.
*
* Examples:
*
* 1. Require organization:
* access: { requireOrg: true }
*
* 2. Require specific permission:
* access: { requireOrg: true, permission: 'org:teams:manage' }
*
* 3. Require specific plan:
* access: { plan: 'pro' }
*
* 4. Require specific feature:
* access: { feature: 'premium_access' }
*
* 5. Require specific role:
* access: { role: 'admin' }
*
* 6. Multiple conditions (all must be true):
* access: { requireOrg: true, permission: 'org:teams:manage', plan: 'pro' }
*
* Note: The `visible` function is deprecated but still supported for backward compatibility.
* Use the `access` property for new items.
*/
export const navGroups: NavGroup[] = [
{
label: "Overview",
items: [
{
title: "Dashboard",
url: "/dashboard",
icon: "dashboard",
isActive: false,
shortcut: ["d", "d"],
items: [],
},
{
title: "Workspaces",
url: "/dashboard/workspaces",
icon: "workspace",
isActive: false,
items: [],
access: { systemRole: "super_admin" },
},
{
title: "Teams",
url: "/dashboard/workspaces/team",
icon: "teams",
isActive: false,
items: [],
access: { requireOrg: true, role: "admin" },
},
{
title: "Users",
url: "/dashboard/users",
icon: "teams",
shortcut: ["u", "u"],
isActive: false,
items: [],
access: { requireOrg: true, permission: "users:manage" },
},
{
title: "Kanban",
url: "/dashboard/kanban",
icon: "kanban",
shortcut: ["k", "k"],
isActive: false,
items: [],
},
],
},
{
label: "CRM",
items: [
{
title: "CRM Dashboard",
url: "/dashboard/crm",
icon: "dashboard",
isActive: false,
items: [],
access: { requireOrg: true },
},
{
title: "Enquiries",
url: "/dashboard/crm/enquiries",
icon: "forms",
isActive: false,
items: [],
access: { requireOrg: true },
},
{
title: "Customers",
url: "/dashboard/crm/customers",
icon: "teams",
isActive: false,
items: [],
access: { requireOrg: true },
},
{
title: "Quotations",
url: "/dashboard/crm/quotations",
icon: "fileTypePdf",
isActive: false,
items: [],
access: { requireOrg: true },
},
{
title: "Approvals",
url: "/dashboard/crm/approvals",
icon: "checks",
isActive: false,
items: [],
access: { requireOrg: true },
},
{
title: "CRM Settings",
url: "#",
icon: "settings",
isActive: true,
access: { requireOrg: true },
items: [
{
title: "Master Options",
url: "/dashboard/crm/settings/master-options",
icon: "settings",
},
{
title: "Document Sequences",
url: "/dashboard/crm/settings/document-sequences",
icon: "post",
},
{
title: "Templates",
url: "/dashboard/crm/settings/templates",
icon: "page",
},
],
},
],
},
];