Merge pull request 'super amdin loign role creation in the saas' (#5) from ribai-patch-1 into dev
Reviewed-on: https://gitea.maskantech.in/gitea_admin/docqube_frontend/pulls/5
This commit is contained in:
+20
-1
@@ -36,12 +36,31 @@ import ConversionWorkflow from '@/features/conversion/ConversionWorkflow';
|
||||
import UpgradePlan from '@/features/subscription/SubscriptionPage';
|
||||
|
||||
|
||||
import { useAuth } from '@/features/auth/context';
|
||||
|
||||
const RouteFallback = () => (
|
||||
<div className="flex min-h-[60vh] items-center justify-center" role="status" aria-live="polite">
|
||||
<div className="h-8 w-8 animate-spin rounded-full border-2 border-gray-300 border-t-transparent" />
|
||||
<span className="sr-only">Loading</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
const TenantDashboardRoute = ({ children }: { children: React.ReactElement }) => {
|
||||
const { user, isLoading } = useAuth();
|
||||
if (isLoading) {
|
||||
return <RouteFallback />;
|
||||
}
|
||||
const isSuperadmin = Boolean(
|
||||
user?.is_superadmin ||
|
||||
user?.role === 'superadmin' ||
|
||||
user?.accesses?.includes('superadmin.main.view')
|
||||
);
|
||||
if (isSuperadmin) {
|
||||
return <Navigate to="/admin/dashboard" replace />;
|
||||
}
|
||||
return children;
|
||||
};
|
||||
|
||||
// Scroll to top component
|
||||
const ScrollToTop = () => {
|
||||
const { pathname } = useLocation();
|
||||
@@ -157,7 +176,7 @@ function AppContent() {
|
||||
</RequireAuth>
|
||||
}
|
||||
>
|
||||
<Route path="/dashboard" element={<DashboardMainView />} />
|
||||
<Route path="/dashboard" element={<TenantDashboardRoute><DashboardMainView /></TenantDashboardRoute>} />
|
||||
<Route path="/documents" element={<RequireAccess accessCode="document.read"><MyDocumentsView /></RequireAccess>} />
|
||||
<Route
|
||||
path="/new-conversion"
|
||||
|
||||
@@ -76,6 +76,7 @@ export const authAPI = {
|
||||
saasSignInRes = await fetch(`${saasApiUrl}/api/auth/signin`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ email: credentials.email.trim(), password: credentials.password }),
|
||||
});
|
||||
} catch (e: any) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import ConfirmationModal from '@/components/custom/CustomConfirmationModal';
|
||||
import { tenantApi, Tenant } from '@/services/tenant';
|
||||
import { useAuth } from '@/features/auth/context';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getSaasFrontendUrl } from '@/lib/saasConfig';
|
||||
|
||||
const RoleManagement = () => {
|
||||
const [roles, setRoles] = useState<Role[]>([]);
|
||||
@@ -77,12 +78,17 @@ const RoleManagement = () => {
|
||||
}, []);
|
||||
|
||||
const handleOpenCreate = () => {
|
||||
if (isTenantAdmin) {
|
||||
const saasUrl = getSaasFrontendUrl();
|
||||
window.open(`${saasUrl}/roles/add`, '_blank');
|
||||
return;
|
||||
}
|
||||
setIsEditing(false);
|
||||
setIsViewModalOpen(false);
|
||||
setRoleName('');
|
||||
setRoleDescription('');
|
||||
setSelectedAccessIds([]);
|
||||
setSelectedTenantId(isTenantAdmin ? user!.tenant_id! : '');
|
||||
setSelectedTenantId('');
|
||||
setIsSuperadminRole(false);
|
||||
setIsDefaultRole(false);
|
||||
setIsModalOpen(true);
|
||||
@@ -321,6 +327,22 @@ const RoleManagement = () => {
|
||||
</CustomButton>
|
||||
</div>
|
||||
|
||||
{isTenantAdmin && (
|
||||
<div className="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-lg flex flex-wrap items-center justify-between gap-2 text-sm text-blue-800">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>Roles and user permissions are centrally managed in Maskan SaaS Hub.</span>
|
||||
</div>
|
||||
<a
|
||||
href={`${getSaasFrontendUrl()}/roles`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="font-semibold underline hover:text-blue-900 flex items-center gap-1"
|
||||
>
|
||||
Manage in SaaS Hub →
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<CustomTable
|
||||
data={roles}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { tenantApi, Tenant } from '@/services/tenant';
|
||||
import { ConfigurationApi, LimitsSnapshot } from '@/features/superAdmin/settings/ConfigurationApi';
|
||||
import { useAuth } from '@/features/auth/context';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { getSaasFrontendUrl } from '@/lib/saasConfig';
|
||||
|
||||
export default function UserManagement() {
|
||||
const [users, setUsers] = useState<UserListItem[]>([]);
|
||||
@@ -166,6 +167,12 @@ export default function UserManagement() {
|
||||
|
||||
|
||||
const openCreateModal = async () => {
|
||||
if (isTenantAdmin) {
|
||||
const saasUrl = getSaasFrontendUrl();
|
||||
window.open(`${saasUrl}/users/add`, '_blank');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsCreating(true);
|
||||
setSelectedUser(null);
|
||||
setFormName('');
|
||||
@@ -180,14 +187,10 @@ export default function UserManagement() {
|
||||
|
||||
refreshLimits();
|
||||
|
||||
if (isTenantAdmin) {
|
||||
await onTenantChanged(user!.tenant_id!);
|
||||
} else {
|
||||
setFormTenantId('');
|
||||
setSelectedTenantActiveUsers(null);
|
||||
setSelectedTenantUserLimit(null);
|
||||
setAvailableRoles([]);
|
||||
}
|
||||
setFormTenantId('');
|
||||
setSelectedTenantActiveUsers(null);
|
||||
setSelectedTenantUserLimit(null);
|
||||
setAvailableRoles([]);
|
||||
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
@@ -702,6 +705,22 @@ export default function UserManagement() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isTenantAdmin && (
|
||||
<div className="mb-6 p-3 bg-blue-50 border border-blue-200 rounded-lg flex flex-wrap items-center justify-between gap-2 text-sm text-blue-800">
|
||||
<div className="flex items-center gap-2">
|
||||
<span>User onboarding, invitations, and team assignments are centrally managed in Maskan SaaS Hub.</span>
|
||||
</div>
|
||||
<a
|
||||
href={`${getSaasFrontendUrl()}/users`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="font-semibold underline hover:text-blue-900 flex items-center gap-1"
|
||||
>
|
||||
Manage in SaaS Hub →
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(orgCreditStats || isLoading) && (
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
||||
{isLoading && !orgCreditStats ? (
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Helper to dynamically resolve the Central SaaS Management Frontend URL
|
||||
* Supports local development, test environments, and production dynamically.
|
||||
*/
|
||||
export function getSaasFrontendUrl(): string {
|
||||
const envSaasFrontend = (import.meta.env.VITE_SAAS_FRONTEND_URL as string | undefined);
|
||||
if (envSaasFrontend && envSaasFrontend.trim()) {
|
||||
return envSaasFrontend.trim().replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
const hostname = window.location.hostname;
|
||||
if (hostname.includes('maskantech.in')) {
|
||||
if (hostname.includes('test')) {
|
||||
return 'https://saas-test.maskantech.in';
|
||||
}
|
||||
return 'https://saas.maskantech.in';
|
||||
}
|
||||
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
||||
return 'http://localhost:5174';
|
||||
}
|
||||
}
|
||||
|
||||
const saasApi = (import.meta.env.VITE_SAAS_API_URL as string | undefined) || '';
|
||||
if (saasApi.includes('8000') || saasApi.includes('localhost')) {
|
||||
return 'http://localhost:5174';
|
||||
}
|
||||
if (saasApi.trim()) {
|
||||
return saasApi.trim().replace(/\/+$/, '');
|
||||
}
|
||||
|
||||
return 'http://localhost:5173';
|
||||
}
|
||||
Reference in New Issue
Block a user