diff --git a/convex/reports.ts b/convex/reports.ts index 57b5454..f718ec1 100644 --- a/convex/reports.ts +++ b/convex/reports.ts @@ -81,6 +81,44 @@ async function fetchScopedTickets( return fetchTickets(ctx, tenantId); } +async function fetchScopedTicketsByCreatedRange( + ctx: QueryCtx, + tenantId: string, + viewer: Awaited>, + startMs: number, + endMs: number, + companyId?: Id<"companies">, +) { + if (viewer.role === "MANAGER") { + if (!viewer.user.companyId) { + throw new ConvexError("Gestor não possui empresa vinculada"); + } + return ctx.db + .query("tickets") + .withIndex("by_tenant_company_created", (q) => + q.eq("tenantId", tenantId).eq("companyId", viewer.user.companyId!).gte("createdAt", startMs), + ) + .filter((q) => q.lt(q.field("createdAt"), endMs)) + .collect(); + } + + if (companyId) { + return ctx.db + .query("tickets") + .withIndex("by_tenant_company_created", (q) => + q.eq("tenantId", tenantId).eq("companyId", companyId).gte("createdAt", startMs), + ) + .filter((q) => q.lt(q.field("createdAt"), endMs)) + .collect(); + } + + return ctx.db + .query("tickets") + .withIndex("by_tenant_created", (q) => q.eq("tenantId", tenantId).gte("createdAt", startMs)) + .filter((q) => q.lt(q.field("createdAt"), endMs)) + .collect(); +} + async function fetchQueues(ctx: QueryCtx, tenantId: string) { return ctx.db .query("queues") @@ -306,16 +344,13 @@ export const backlogOverview = query({ args: { tenantId: v.string(), viewerId: v.id("users"), range: v.optional(v.string()), companyId: v.optional(v.id("companies")) }, handler: async (ctx, { tenantId, viewerId, range, companyId }) => { const viewer = await requireStaff(ctx, viewerId, tenantId); - let tickets = await fetchScopedTickets(ctx, tenantId, viewer); - if (companyId) tickets = tickets.filter((t) => t.companyId === companyId) - // Optional range filter (createdAt) for reporting purposes const days = range === "7d" ? 7 : range === "30d" ? 30 : 90; const end = new Date(); end.setUTCHours(0, 0, 0, 0); const endMs = end.getTime() + ONE_DAY_MS; const startMs = endMs - days * ONE_DAY_MS; - const inRange = tickets.filter((t) => t.createdAt >= startMs && t.createdAt < endMs); + const inRange = await fetchScopedTicketsByCreatedRange(ctx, tenantId, viewer, startMs, endMs, companyId); const statusCounts = inRange.reduce>((acc, ticket) => { const status = normalizeStatus(ticket.status); diff --git a/convex/schema.ts b/convex/schema.ts index 353fdfc..7488363 100644 --- a/convex/schema.ts +++ b/convex/schema.ts @@ -181,7 +181,9 @@ export default defineSchema({ .index("by_tenant_requester", ["tenantId", "requesterId"]) .index("by_tenant_company", ["tenantId", "companyId"]) .index("by_tenant_machine", ["tenantId", "machineId"]) - .index("by_tenant", ["tenantId"]), + .index("by_tenant", ["tenantId"]) + .index("by_tenant_created", ["tenantId", "createdAt"]) + .index("by_tenant_company_created", ["tenantId", "companyId", "createdAt"]), ticketComments: defineTable({ ticketId: v.id("tickets"), diff --git a/public/fonts/JetBrainsMono-VariableFont_wght.ttf b/public/fonts/JetBrainsMono-VariableFont_wght.ttf deleted file mode 100644 index 4993802..0000000 --- a/public/fonts/JetBrainsMono-VariableFont_wght.ttf +++ /dev/null @@ -1,2151 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Page not found · GitHub · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- Skip to content - - - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - -
- -
- - - - - - - - -
- - - - - -
- - - - - - - - - -
-
- - - -
-
- -
-
- 404 “This is not the web page you are looking for” - - - - - - - - - - - - -
-
- -
-
- -
- - -
-
- -
- -
- -
- - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - diff --git a/src/app/globals.css b/src/app/globals.css index 444fd80..925a671 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -19,13 +19,7 @@ font-display: swap; } -@font-face { - font-family: "JetBrainsMonoVariable"; - src: url("/fonts/JetBrainsMono-VariableFont_wght.ttf") format("truetype"); - font-weight: 100 800; - font-style: normal; - font-display: swap; -} +/* JetBrains Mono agora depende das fontes do sistema para evitar carregar um arquivo corrompido */ @theme inline { --color-background: var(--background); @@ -106,7 +100,7 @@ --sidebar-ring: #00d6eb; --destructive-foreground: oklch(1 0 0); --font-geist-sans: "InterVariable", "Inter", sans-serif; - --font-geist-mono: "JetBrainsMonoVariable", "JetBrains Mono", monospace; + --font-geist-mono: "JetBrains Mono", "Fira Code", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; } .dark {