Ajusta portal e desktop para máquina vinculada
This commit is contained in:
parent
0cac7aa23a
commit
ba0dcddefb
4 changed files with 62 additions and 9 deletions
|
|
@ -21,7 +21,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
@apply inline-flex items-center justify-center rounded-lg border px-3 py-2 text-sm font-semibold transition;
|
@apply inline-flex items-center justify-center rounded-md border px-3 py-2 text-sm font-semibold transition;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
|
|
@ -49,7 +49,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-btn {
|
.tab-btn {
|
||||||
@apply rounded-lg border border-transparent bg-transparent px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-100;
|
@apply rounded-md border border-transparent bg-transparent px-3 py-1.5 text-sm font-medium text-slate-700 hover:bg-slate-100;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-btn.active {
|
.tab-btn.active {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { api } from "@/convex/_generated/api"
|
||||||
import type { Id } from "@/convex/_generated/dataModel"
|
import type { Id } from "@/convex/_generated/dataModel"
|
||||||
import { env } from "@/lib/env"
|
import { env } from "@/lib/env"
|
||||||
import { assertAuthenticatedSession } from "@/lib/auth-server"
|
import { assertAuthenticatedSession } from "@/lib/auth-server"
|
||||||
|
import { DEFAULT_TENANT_ID } from "@/lib/constants"
|
||||||
|
|
||||||
const MACHINE_CTX_COOKIE = "machine_ctx"
|
const MACHINE_CTX_COOKIE = "machine_ctx"
|
||||||
|
|
||||||
|
|
@ -88,17 +89,56 @@ export async function GET(request: NextRequest) {
|
||||||
authEmail: string | null
|
authEmail: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let ensuredAssignedUserId = context.assignedUserId
|
||||||
|
let ensuredAssignedUserName = context.assignedUserName
|
||||||
|
let ensuredAssignedUserRole = context.assignedUserRole
|
||||||
|
|
||||||
|
if (!ensuredAssignedUserId && context.persona && context.assignedUserEmail) {
|
||||||
|
try {
|
||||||
|
const ensuredUser = (await client.mutation(api.users.ensureUser, {
|
||||||
|
tenantId: context.tenantId ?? DEFAULT_TENANT_ID,
|
||||||
|
email: context.assignedUserEmail,
|
||||||
|
name: context.assignedUserName ?? context.assignedUserEmail,
|
||||||
|
avatarUrl: undefined,
|
||||||
|
role: (context.assignedUserRole ?? context.persona ?? "collaborator").toUpperCase(),
|
||||||
|
companyId: context.companyId ?? undefined,
|
||||||
|
})) as { _id?: Id<"users">; name?: string | null; role?: string | null } | null
|
||||||
|
|
||||||
|
if (ensuredUser?._id) {
|
||||||
|
ensuredAssignedUserId = ensuredUser._id as string
|
||||||
|
ensuredAssignedUserName = ensuredUser.name ?? context.assignedUserName
|
||||||
|
ensuredAssignedUserRole = ensuredUser.role ?? context.assignedUserRole
|
||||||
|
|
||||||
|
await client.mutation(api.machines.updatePersona, {
|
||||||
|
machineId: machineId as Id<"machines">,
|
||||||
|
persona: context.persona ?? undefined,
|
||||||
|
assignedUserId: ensuredUser._id as Id<"users">,
|
||||||
|
assignedUserEmail: context.assignedUserEmail,
|
||||||
|
assignedUserName: ensuredAssignedUserName ?? undefined,
|
||||||
|
assignedUserRole: (ensuredAssignedUserRole ?? context.persona ?? "collaborator").toUpperCase(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[machines.session] Falha ao garantir usuário vinculado", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const responsePayload = {
|
const responsePayload = {
|
||||||
machineId: context.id,
|
machineId: context.id,
|
||||||
persona: context.persona,
|
persona: context.persona,
|
||||||
assignedUserId: context.assignedUserId,
|
assignedUserId: ensuredAssignedUserId,
|
||||||
assignedUserEmail: context.assignedUserEmail,
|
assignedUserEmail: context.assignedUserEmail,
|
||||||
assignedUserName: context.assignedUserName,
|
assignedUserName: ensuredAssignedUserName,
|
||||||
assignedUserRole: context.assignedUserRole,
|
assignedUserRole: ensuredAssignedUserRole,
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = NextResponse.json({
|
const response = NextResponse.json({
|
||||||
machine: context,
|
machine: {
|
||||||
|
...context,
|
||||||
|
assignedUserId: ensuredAssignedUserId ?? null,
|
||||||
|
assignedUserName: ensuredAssignedUserName ?? null,
|
||||||
|
assignedUserRole: ensuredAssignedUserRole ?? null,
|
||||||
|
},
|
||||||
cookie: responsePayload,
|
cookie: responsePayload,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export function PortalShell({ children }: PortalShellProps) {
|
||||||
<GalleryVerticalEnd className="size-4" />
|
<GalleryVerticalEnd className="size-4" />
|
||||||
</span>
|
</span>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-xs font-semibold tracking-[0.04em] text-neutral-500 sm:tracking-[0.06em]">
|
<span className="text-sm text-neutral-500">
|
||||||
Portal do Cliente
|
Portal do Cliente
|
||||||
</span>
|
</span>
|
||||||
<span className="text-lg font-semibold text-neutral-900">Raven</span>
|
<span className="text-lg font-semibold text-neutral-900">Raven</span>
|
||||||
|
|
|
||||||
|
|
@ -48,10 +48,18 @@ export function PortalTicketForm() {
|
||||||
const isFormValid = useMemo(() => {
|
const isFormValid = useMemo(() => {
|
||||||
return Boolean(subject.trim() && description.trim() && categoryId && subcategoryId)
|
return Boolean(subject.trim() && description.trim() && categoryId && subcategoryId)
|
||||||
}, [subject, description, categoryId, subcategoryId])
|
}, [subject, description, categoryId, subcategoryId])
|
||||||
|
const isViewerReady = Boolean(viewerId)
|
||||||
|
|
||||||
async function handleSubmit(event: React.FormEvent) {
|
async function handleSubmit(event: React.FormEvent) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (!viewerId || !isFormValid || isSubmitting) return
|
if (isSubmitting || !isFormValid) return
|
||||||
|
if (!viewerId) {
|
||||||
|
toast.error(
|
||||||
|
"Não foi possível identificar o colaborador vinculado a esta máquina. Tente abrir novamente o portal ou contate o suporte.",
|
||||||
|
{ id: "portal-new-ticket" }
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const trimmedSubject = subject.trim()
|
const trimmedSubject = subject.trim()
|
||||||
const trimmedSummary = summary.trim()
|
const trimmedSummary = summary.trim()
|
||||||
|
|
@ -113,6 +121,11 @@ export function PortalTicketForm() {
|
||||||
<CardTitle className="text-xl font-semibold text-neutral-900">Abrir novo chamado</CardTitle>
|
<CardTitle className="text-xl font-semibold text-neutral-900">Abrir novo chamado</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-6 px-5 pb-6">
|
<CardContent className="space-y-6 px-5 pb-6">
|
||||||
|
{!isViewerReady ? (
|
||||||
|
<div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700">
|
||||||
|
Vincule esta máquina a um colaborador na aplicação desktop para enviar chamados em nome dele.
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
<form onSubmit={handleSubmit} className="space-y-6">
|
<form onSubmit={handleSubmit} className="space-y-6">
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -186,7 +199,7 @@ export function PortalTicketForm() {
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!isFormValid || isSubmitting || !viewerId}
|
disabled={!isFormValid || isSubmitting}
|
||||||
className="rounded-full bg-neutral-900 px-6 text-sm font-semibold text-white hover:bg-neutral-900/90"
|
className="rounded-full bg-neutral-900 px-6 text-sm font-semibold text-white hover:bg-neutral-900/90"
|
||||||
>
|
>
|
||||||
Registrar chamado
|
Registrar chamado
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue