diff --git a/src/app/admin/companies/page.tsx b/src/app/admin/companies/page.tsx index d8cca43..2debf1c 100644 --- a/src/app/admin/companies/page.tsx +++ b/src/app/admin/companies/page.tsx @@ -8,9 +8,13 @@ import { fetchCompaniesByTenant, normalizeCompany } from "@/server/company-servi export const runtime = "nodejs" export const dynamic = "force-dynamic" -export default async function AdminCompaniesPage() { +export default async function AdminCompaniesPage({ + searchParams, +}: { searchParams: Promise> }) { const session = await requireStaffSession() const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID + const params = await searchParams + const autoOpenCreateCompany = params.quick === "new-company" const companies = (await fetchCompaniesByTenant(tenantId)).map(normalizeCompany) return (
- +
) diff --git a/src/app/admin/devices/page.tsx b/src/app/admin/devices/page.tsx index 403e6fc..2ada0f7 100644 --- a/src/app/admin/devices/page.tsx +++ b/src/app/admin/devices/page.tsx @@ -12,6 +12,7 @@ export default async function AdminDevicesPage({ const params = await searchParams const companyParam = params.company const company = typeof companyParam === "string" ? companyParam : undefined + const autoOpenCreateDevice = params.quick === "new-device" return (
- +
) diff --git a/src/app/admin/users/page.tsx b/src/app/admin/users/page.tsx index 5065ca4..ef46043 100644 --- a/src/app/admin/users/page.tsx +++ b/src/app/admin/users/page.tsx @@ -9,9 +9,13 @@ import { fetchCompaniesByTenant, normalizeCompany } from "@/server/company-servi export const runtime = "nodejs" export const dynamic = "force-dynamic" -export default async function AdminUsersPage() { +export default async function AdminUsersPage({ + searchParams, +}: { searchParams: Promise> }) { const session = await requireStaffSession() const tenantId = session.user.tenantId ?? DEFAULT_TENANT_ID + const params = await searchParams + const autoOpenCreateUser = params.quick === "new-user" const users = await prisma.user.findMany({ where: { @@ -103,7 +107,12 @@ export default async function AdminUsersPage() { } >
- +
) diff --git a/src/components/admin/companies/admin-companies-manager.tsx b/src/components/admin/companies/admin-companies-manager.tsx index 9a8fff0..a78fb4f 100644 --- a/src/components/admin/companies/admin-companies-manager.tsx +++ b/src/components/admin/companies/admin-companies-manager.tsx @@ -95,6 +95,7 @@ type LastAlertInfo = { createdAt: number; usagePct: number; threshold: number } type Props = { initialCompanies: NormalizedCompany[] tenantId?: string | null + autoOpenCreate?: boolean } type ViewMode = "table" | "board" @@ -291,7 +292,7 @@ function FieldError({ error }: { error?: string }) { return

{error}

} -export function AdminCompaniesManager({ initialCompanies, tenantId }: Props) { +export function AdminCompaniesManager({ initialCompanies, tenantId, autoOpenCreate = false }: Props) { const [companies, setCompanies] = useState(() => initialCompanies) const [view, setView] = useState("table") const [search, setSearch] = useState("") @@ -429,6 +430,12 @@ export function AdminCompaniesManager({ initialCompanies, tenantId }: Props) { const cancelDelete = useCallback(() => setIsDeleting(null), []) + useEffect(() => { + if (autoOpenCreate) { + openCreate() + } + }, [autoOpenCreate, openCreate]) + const handleDelete = useCallback(async () => { if (!isDeleting) return try { diff --git a/src/components/admin/devices/admin-devices-overview.tsx b/src/components/admin/devices/admin-devices-overview.tsx index 7dae465..3630598 100644 --- a/src/components/admin/devices/admin-devices-overview.tsx +++ b/src/components/admin/devices/admin-devices-overview.tsx @@ -1268,7 +1268,15 @@ function OsIcon({ osName }: { osName?: string | null }) { return } -export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all" }: { tenantId: string; initialCompanyFilterSlug?: string }) { +export function AdminDevicesOverview({ + tenantId, + initialCompanyFilterSlug = "all", + autoOpenCreateDevice = false, +}: { + tenantId: string + initialCompanyFilterSlug?: string + autoOpenCreateDevice?: boolean +}) { const { devices, isLoading } = useDevicesQuery(tenantId) const [q, setQ] = useState("") const [statusFilter, setStatusFilter] = useState("all") @@ -1555,6 +1563,12 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all setIsCreateDeviceOpen(true) }, [selectedCompany, companyFilterSlug]) + useEffect(() => { + if (autoOpenCreateDevice) { + handleOpenCreateDevice() + } + }, [autoOpenCreateDevice, handleOpenCreateDevice]) + const handleCreateDevice = useCallback(async () => { if (!convexUserId) { toast.error("Sincronize a sessão antes de criar dispositivos.") diff --git a/src/components/admin/users/admin-users-workspace.tsx b/src/components/admin/users/admin-users-workspace.tsx index 0648107..b5b24a8 100644 --- a/src/components/admin/users/admin-users-workspace.tsx +++ b/src/components/admin/users/admin-users-workspace.tsx @@ -95,6 +95,7 @@ type Props = { initialAccounts: AdminAccount[] companies: NormalizedCompany[] tenantId: string + autoOpenCreate?: boolean } type SectionEditorState = @@ -164,7 +165,7 @@ function FieldError({ message }: { message?: string }) { return

{message}

} -export function AdminUsersWorkspace({ initialAccounts, companies, tenantId }: Props) { +export function AdminUsersWorkspace({ initialAccounts, companies, tenantId, autoOpenCreate = false }: Props) { const [tab, setTab] = useState<"accounts" | "structure">("accounts") return ( setTab(value as typeof tab)}> @@ -173,7 +174,12 @@ export function AdminUsersWorkspace({ initialAccounts, companies, tenantId }: Pr Estrutura das empresas - + @@ -186,10 +192,12 @@ function AccountsTable({ initialAccounts, companies, tenantId, + autoOpenCreate, }: { initialAccounts: AdminAccount[] companies: NormalizedCompany[] tenantId: string + autoOpenCreate?: boolean }) { const [accounts, setAccounts] = useState(initialAccounts) const [search, setSearch] = useState("") @@ -212,6 +220,7 @@ function AccountsTable({ const [isResettingPassword, setIsResettingPassword] = useState(false) const [passwordPreview, setPasswordPreview] = useState(null) const [createDialogOpen, setCreateDialogOpen] = useState(false) + const autoOpenHandledRef = useRef(false) const [isCreatingAccount, setIsCreatingAccount] = useState(false) const [createForm, setCreateForm] = useState(() => createDefaultAccountForm()) @@ -400,6 +409,13 @@ function AccountsTable({ setCreateForm(createDefaultAccountForm()) }, []) + useEffect(() => { + if (!autoOpenCreate || autoOpenHandledRef.current) return + autoOpenHandledRef.current = true + setCreateForm(createDefaultAccountForm()) + setCreateDialogOpen(true) + }, [autoOpenCreate]) + useEffect(() => { if (editAccount) { setEditForm({ diff --git a/src/components/global-quick-actions.tsx b/src/components/global-quick-actions.tsx index a0329f7..5164ce5 100644 --- a/src/components/global-quick-actions.tsx +++ b/src/components/global-quick-actions.tsx @@ -39,7 +39,7 @@ export function GlobalQuickActions() { label: "Adicionar empresa", description: "Cadastrar novo cliente", icon: Building, - href: "/admin/companies", + href: "/admin/companies?quick=new-company", visible: Boolean(isAdmin), }, { @@ -47,7 +47,7 @@ export function GlobalQuickActions() { label: "Novo usuário", description: "Gestores / colaboradores", icon: UserPlus, - href: "/admin/users", + href: "/admin/users?quick=new-user", visible: Boolean(isAdmin), }, ]