This commit is contained in:
2025-11-17 14:37:50 -03:00
parent d2abaec021
commit 7f41704d90
51 changed files with 733 additions and 495 deletions

View File

@@ -64,7 +64,7 @@ function SidebarMenuItemLink({ title, url, icon: Icon }: NavItem) {
return (
<SidebarMenuItem key={title} onClick={onToggle}>
<NavLink to={`/${orgid}${url}`}>
{({ isActive }) => (
{({ isActive, isPending }) => (
<SidebarMenuButton
asChild
className="data-[active=true]:text-lime-500"
@@ -72,7 +72,7 @@ function SidebarMenuItemLink({ title, url, icon: Icon }: NavItem) {
tooltip={title}
>
<span>
{Icon && <Icon />}
{Icon ? <Icon /> : null}
<span>{title}</span>
</span>
</SidebarMenuButton>

View File

@@ -1,34 +0,0 @@
import { Meilisearch, type SearchResponse } from 'meilisearch'
const MAX_HITS_PER_PAGE = 100
export async function createSearch({
query,
filter = undefined,
index,
page,
hitsPerPage,
sort,
env
}: {
query?: string
filter?: string
index: string
page?: number
hitsPerPage: number
sort: string[]
env: Env
}): Promise<SearchResponse> {
const host = env.MEILI_HOST
const apiKey = env.MEILI_API_KEY
const client = new Meilisearch({ host, apiKey })
const index_ = client.index(index)
return index_.search(query, {
sort,
filter,
page,
hitsPerPage:
hitsPerPage > MAX_HITS_PER_PAGE ? MAX_HITS_PER_PAGE : hitsPerPage
})
}

View File

@@ -1,49 +0,0 @@
import type { User } from '@repo/auth/auth'
import { requestIdContext, userContext } from '@repo/auth/context'
import type { LoaderFunctionArgs } from 'react-router'
export enum HttpMethod {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
PATCH = 'PATCH',
DELETE = 'DELETE'
}
type RequestArgs = {
url: string
method?: HttpMethod
headers?: HeadersInit
body?: BodyInit | null
request: LoaderFunctionArgs['request']
context: LoaderFunctionArgs['context']
}
export function request({
url,
method = HttpMethod.GET,
body = null,
headers: _headers = {},
request: { signal },
context
}: RequestArgs): Promise<Response> {
const requestId = context.get(requestIdContext) as string
const user = context.get(userContext) as User
const url_ = new URL(url, context.cloudflare.env.API_URL)
const headers = new Headers({
Authorization: `Bearer ${user.accessToken}`
})
if (_headers instanceof Headers) {
_headers.forEach((value, key) => headers.set(key, value))
} else {
Object.entries(_headers).forEach(([key, value]) => headers.set(key, value))
}
console.log(
`[${new Date().toISOString()}] [${requestId}] ${method} ${url_.toString()}`
)
return fetch(url_.toString(), { method, headers, body, signal })
}

View File

@@ -11,7 +11,7 @@ import { Await, NavLink, useParams, useRevalidator } from 'react-router'
import { toast } from 'sonner'
import { Abbr } from '@/components/abbr'
import { request as req } from '@/lib/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
AlertDialog,
@@ -34,6 +34,7 @@ import {
} from '@repo/ui/components/ui/dropdown-menu'
import { Spinner } from '@repo/ui/components/ui/spinner'
import { initials } from '@repo/ui/lib/utils'
import { request as req } from '@repo/util/request'
type Admin = {
sk: string

View File

@@ -6,8 +6,6 @@ import { Suspense, useMemo } from 'react'
import { Await, useSearchParams } from 'react-router'
import placeholder from '@/assets/placeholder.webp'
import { createSearch } from '@/lib/meili'
import { request as req } from '@/lib/request'
import { SearchForm } from '@repo/ui/components/search-form'
import { Skeleton } from '@repo/ui/components/skeleton'
@@ -26,6 +24,8 @@ import {
} from '@repo/ui/components/ui/empty'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { cn } from '@repo/ui/lib/utils'
import { createSearch } from '@repo/util/meili'
import { request as req } from '@repo/util/request'
type Cert = {
exp_interval: number

View File

@@ -18,7 +18,6 @@ import * as XLSX from 'xlsx'
import { DataTable, DataTableViewOptions } from '@/components/data-table'
import { RangeCalendarFilter } from '@/components/range-calendar-filter'
import { createSearch } from '@/lib/meili'
import { FacetedFilter } from '@repo/ui/components/faceted-filter'
import { SearchForm } from '@repo/ui/components/search-form'
@@ -32,6 +31,7 @@ import {
DropdownMenuTrigger
} from '@repo/ui/components/ui/dropdown-menu'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { createSearch } from '@repo/util/meili'
import { columns, type Enrollment } from './columns'
import { headers, sortings, statuses } from './data'

View File

@@ -4,8 +4,9 @@ import { Suspense } from 'react'
import { Await } from 'react-router'
import { DataTable } from '@/components/data-table'
import { createSearch } from '@/lib/meili'
import { Skeleton } from '@repo/ui/components/skeleton'
import { createSearch } from '@repo/util/meili'
import { columns, type Order } from './columns'
export function meta({}: Route.MetaArgs) {

View File

@@ -1,11 +1,11 @@
import type { Route } from './+types'
import { Suspense } from 'react'
import { request as req } from '@/lib/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Await } from 'react-router'
import { Skeleton } from '@repo/ui/components/skeleton'
import { request as req } from '@repo/util/request'
export function meta({}: Route.MetaArgs) {
return [{ title: 'Matrículas agendadas' }]
}

View File

@@ -3,8 +3,6 @@ import type { Route } from './+types'
import { Suspense } from 'react'
import { Await, useOutletContext } from 'react-router'
import { request as req } from '@/lib/request'
import { Skeleton } from '@repo/ui/components/skeleton'
import {
Card,
@@ -18,6 +16,7 @@ import {
NativeSelect,
NativeSelectOption
} from '@repo/ui/components/ui/native-select'
import { request as req } from '@repo/util/request'
import { Button } from '@repo/ui/components/ui/button'
import type { User } from '../_.$orgid.users.$id/route'
@@ -64,9 +63,13 @@ export default function Route({ loaderData: { data } }) {
<CardHeader>
<CardTitle className="text-lg">Email principal</CardTitle>
<CardDescription>
<Kbd className="font-mono border">{user.email}</Kbd> será
usado para mensagens e pode ser usado para redefinições de
senha.
<Kbd className="font-mono border">
<span className="truncate max-lg:max-w-62">
{user.email}
</span>
</Kbd>{' '}
será usado para mensagens e pode ser usado para redefinições
de senha.
</CardDescription>
</CardHeader>
<CardContent>

View File

@@ -7,8 +7,6 @@ import {
type ShouldRevalidateFunctionArgs
} from 'react-router'
import { request as req } from '@/lib/request'
import { Avatar, AvatarFallback } from '@repo/ui/components/ui/avatar'
import {
Breadcrumb,
@@ -20,6 +18,7 @@ import {
} from '@repo/ui/components/ui/breadcrumb'
import { Tabs, TabsList, TabsTrigger } from '@repo/ui/components/ui/tabs'
import { initials } from '@repo/ui/lib/utils'
import { request as req } from '@repo/util/request'
export function meta() {
return [
@@ -92,7 +91,9 @@ export default function Route({
<ul>
<li className="font-bold text-lg">{user.name}</li>
<li className="text-muted-foreground text-sm">{user.email}</li>
<li className="text-muted-foreground text-sm truncate max-lg:max-w-62">
{user.email}
</li>
</ul>
</div>

View File

@@ -5,13 +5,13 @@ import { Suspense } from 'react'
import { Await, Link, useSearchParams } from 'react-router'
import { DataTable } from '@/components/data-table'
import { createSearch } from '@/lib/meili'
import { columns, type User } from './columns'
import { SearchForm } from '@repo/ui/components/search-form'
import { Skeleton } from '@repo/ui/components/skeleton'
import { Button } from '@repo/ui/components/ui/button'
import { Kbd } from '@repo/ui/components/ui/kbd'
import { createSearch } from '@repo/util/meili'
export function meta({}: Route.MetaArgs) {
return [

View File

@@ -43,7 +43,7 @@ import { Input } from '@repo/ui/components/ui/input'
import { Spinner } from '@repo/ui/components/ui/spinner'
import { useWorksapce } from '@/components/workspace-switcher'
import { HttpMethod, request as req } from '@/lib/request'
import { HttpMethod, request as req } from '@repo/util/request'
import { useEffect } from 'react'
const isName = (name: string) => name && name.includes(' ')

View File

@@ -4,7 +4,6 @@ import * as cookie from 'cookie'
import { Outlet, type ShouldRevalidateFunctionArgs } from 'react-router'
import { AppSidebar } from '@/components/app-sidebar'
import { request as req } from '@/lib/request'
import { WorkspaceProvider } from '@/components/workspace-switcher'
import { userContext } from '@repo/auth/context'
@@ -17,6 +16,7 @@ import {
SidebarTrigger
} from '@repo/ui/components/ui/sidebar'
import { Toaster } from '@repo/ui/components/ui/sonner'
import { request as req } from '@repo/util/request'
export const middleware: Route.MiddlewareFunction[] = [authMiddleware]

View File

@@ -2,9 +2,9 @@ import type { Route } from './+types'
import { redirect } from 'react-router'
import { request as req } from '@/lib/request'
import { userContext } from '@repo/auth/context'
import { authMiddleware } from '@repo/auth/middleware/auth'
import { request as req } from '@repo/util/request'
export const middleware: Route.MiddlewareFunction[] = [authMiddleware]

View File

@@ -15,6 +15,7 @@
"@react-router/fs-routes": "^7.9.5",
"@repo/auth": "*",
"@repo/ui": "*",
"@repo/util": "^0.0.0",
"@tanstack/react-table": "^8.21.3",
"cookie": "^1.0.2",
"date-fns": "^4.1.0",