refactor: refactor webui

This commit is contained in:
master 2025-04-26 01:43:23 +08:00
parent b20f7cd1ad
commit ee1b1ae5e6
104 changed files with 934 additions and 827 deletions

View File

@ -10,11 +10,11 @@
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/infra/styles/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/infra/hooks"
"components": "@/views/components",
"utils": "@/views/utils",
"ui": "@/views/components/ui",
"lib": "@/views/lib",
"hooks": "@/views/hooks"
},
"iconLibrary": "lucide"
}

View File

@ -18,32 +18,32 @@
"@graphiql/toolkit": "^0.11.1",
"@hookform/resolvers": "^5.0.1",
"@outposts/injection-js": "^2.5.1",
"@radix-ui/react-accordion": "^1.2.7",
"@radix-ui/react-alert-dialog": "^1.1.10",
"@radix-ui/react-aspect-ratio": "^1.1.4",
"@radix-ui/react-avatar": "^1.1.6",
"@radix-ui/react-checkbox": "^1.2.2",
"@radix-ui/react-collapsible": "^1.1.7",
"@radix-ui/react-context-menu": "^2.2.11",
"@radix-ui/react-dialog": "^1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.11",
"@radix-ui/react-hover-card": "^1.1.10",
"@radix-ui/react-label": "^2.1.4",
"@radix-ui/react-menubar": "^1.1.11",
"@radix-ui/react-navigation-menu": "^1.2.9",
"@radix-ui/react-popover": "^1.1.10",
"@radix-ui/react-progress": "^1.1.4",
"@radix-ui/react-radio-group": "^1.3.3",
"@radix-ui/react-scroll-area": "^1.2.5",
"@radix-ui/react-select": "^2.2.2",
"@radix-ui/react-separator": "^1.1.4",
"@radix-ui/react-slider": "^1.3.2",
"@radix-ui/react-slot": "^1.2.0",
"@radix-ui/react-switch": "^1.2.2",
"@radix-ui/react-tabs": "^1.1.8",
"@radix-ui/react-toggle": "^1.1.6",
"@radix-ui/react-toggle-group": "^1.1.7",
"@radix-ui/react-tooltip": "^1.2.3",
"@radix-ui/react-accordion": "^1.2.10",
"@radix-ui/react-alert-dialog": "^1.1.13",
"@radix-ui/react-aspect-ratio": "^1.1.6",
"@radix-ui/react-avatar": "^1.1.9",
"@radix-ui/react-checkbox": "^1.3.1",
"@radix-ui/react-collapsible": "^1.1.10",
"@radix-ui/react-context-menu": "^2.2.14",
"@radix-ui/react-dialog": "^1.1.13",
"@radix-ui/react-dropdown-menu": "^2.1.14",
"@radix-ui/react-hover-card": "^1.1.13",
"@radix-ui/react-label": "^2.1.6",
"@radix-ui/react-menubar": "^1.1.14",
"@radix-ui/react-navigation-menu": "^1.2.12",
"@radix-ui/react-popover": "^1.1.13",
"@radix-ui/react-progress": "^1.1.6",
"@radix-ui/react-radio-group": "^1.3.6",
"@radix-ui/react-scroll-area": "^1.2.8",
"@radix-ui/react-select": "^2.2.4",
"@radix-ui/react-separator": "^1.1.6",
"@radix-ui/react-slider": "^1.3.4",
"@radix-ui/react-slot": "^1.2.2",
"@radix-ui/react-switch": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.11",
"@radix-ui/react-toggle": "^1.1.8",
"@radix-ui/react-toggle-group": "^1.1.9",
"@radix-ui/react-tooltip": "^1.2.6",
"@rsbuild/plugin-react": "^1.2.0",
"@tanstack/react-router": "^1.112.13",
"@tanstack/router-devtools": "^1.112.13",
@ -63,10 +63,10 @@
"next-themes": "^0.4.6",
"oidc-client-rx": "0.1.0-alpha.9",
"react": "^19.1.0",
"react-day-picker": "9.6.7",
"react-day-picker": "8.10.1",
"react-dom": "^19.1.0",
"react-hook-form": "^7.56.0",
"react-resizable-panels": "^3.0.0",
"react-hook-form": "^7.56.3",
"react-resizable-panels": "^3.0.1",
"recharts": "^2.15.3",
"rxjs": "^7.8.2",
"sonner": "^2.0.3",
@ -74,7 +74,8 @@
"tailwindcss": "^4.0.6",
"tw-animate-css": "^1.2.7",
"type-fest": "^4.40.0",
"vaul": "^1.1.2"
"vaul": "^1.1.2",
"zod": "^3.24.4"
},
"devDependencies": {
"@rsbuild/core": "^1.2.15",

View File

@ -1,4 +1,13 @@
import { AuthService } from '@/domains/auth/auth.service';
import { AUTH_PROVIDER, type AuthProvider } from '@/infra/auth/auth.provider';
import { BasicAuthProvider } from '@/infra/auth/basic';
import {
AUTH_METHOD,
type AuthMethodType,
getAppAuthMethod,
} from '@/infra/auth/defs';
import { OidcAuthProvider, buildOidcConfig } from '@/infra/auth/oidc';
import { UnreachableError } from '@/infra/errors/common';
import type { Injector, Provider } from '@outposts/injection-js';
import type { AnyRouter } from '@tanstack/react-router';
import {
@ -9,16 +18,11 @@ import {
} from 'oidc-client-rx';
import { withTanstackRouter } from 'oidc-client-rx/adapters/@tanstack/react-router';
import type { Observable } from 'rxjs';
import {
AppAuthMethod,
AuthMethodEnum,
type AuthMethodType,
buildOidcConfig,
} from './config';
export function provideAuth(router: AnyRouter): Provider[] {
const providers: Provider[] = [AuthService];
if (AppAuthMethod === AuthMethodEnum.OIDC) {
const appAuthMethod = getAppAuthMethod();
if (appAuthMethod === AUTH_METHOD.OIDC) {
providers.push(
...provideOidcAuth(
{
@ -32,18 +36,25 @@ export function provideAuth(router: AnyRouter): Provider[] {
withCheckAuthResultEvent()
)
);
providers.push({
provide: AUTH_PROVIDER,
useClass: OidcAuthProvider,
});
} else if (appAuthMethod === AUTH_METHOD.BASIC) {
providers.push({
provide: AUTH_PROVIDER,
useClass: BasicAuthProvider,
});
} else {
throw new UnreachableError(`Unsupported auth method: ${appAuthMethod}`);
}
return providers;
}
export function setupAuthContext(injector: Injector) {
const { authService } = authContextFromInjector(injector);
authService.setup();
}
export interface AuthContext {
type: AuthMethodType;
authService: AuthService;
authProvider: AuthProvider;
isAuthenticated$: Observable<boolean>;
userData$: Observable<{}>;
checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
@ -51,11 +62,18 @@ export interface AuthContext {
export function authContextFromInjector(injector: Injector): AuthContext {
const authService = injector.get(AuthService);
const authProvider = injector.get(AUTH_PROVIDER);
return {
type: AppAuthMethod,
authService,
type: authProvider.authMethod,
isAuthenticated$: authService.isAuthenticated$,
userData$: authService.userData$,
checkAuthResultEvent$: authService.checkAuthResultEvent$,
authService,
authProvider,
};
}
export function setupAuthContext(injector: Injector) {
const { authService } = authContextFromInjector(injector);
authService.setup();
}

View File

@ -1,19 +1,17 @@
import type { RouterContext } from '@/infra/routes/traits';
import { runInInjectionContext } from '@outposts/injection-js';
import { autoLoginPartialRoutesGuard } from 'oidc-client-rx';
import { firstValueFrom } from 'rxjs';
import { authContextFromInjector } from './context';
export const beforeLoadGuard = async ({
context,
}: { context: RouterContext }) => {
const { isAuthenticated$ } = authContextFromInjector(context.injector);
const { isAuthenticated$, authProvider } = authContextFromInjector(
context.injector
);
if (!(await firstValueFrom(isAuthenticated$))) {
const guard$ = runInInjectionContext(context.injector, () =>
autoLoginPartialRoutesGuard()
const isAuthenticated = await firstValueFrom(
authProvider.autoLoginPartialRoutesGuard()
);
const isAuthenticated = await firstValueFrom(guard$);
if (!isAuthenticated) {
throw !isAuthenticated;
}

View File

@ -26,9 +26,9 @@ export function useAuth() {
);
return {
...authContext,
userData,
injector,
isAuthenticated,
authContext,
};
}

View File

@ -1,53 +1,15 @@
import { AppAuthMethod, AuthMethodEnum } from '@/app/auth/config';
import { injectInjector } from '@/infra/di/inject';
import { Injectable, type Injector } from '@outposts/injection-js';
import {
CHECK_AUTH_RESULT_EVENT,
type CheckAuthResultEventType,
OidcSecurityService,
} from 'oidc-client-rx';
import { NEVER, type Observable, map, of } from 'rxjs';
const BASIC_AUTH_IS_AUTHENTICATED$ = of(true) as Observable<true>;
const BASIC_AUTH_USER_DATA$ = of({});
import { AUTH_PROVIDER } from '@/infra/auth/auth.provider';
import { Injectable, inject } from '@outposts/injection-js';
@Injectable()
export class AuthService {
private injector: Injector = injectInjector();
oidcSecurityService: OidcSecurityService | undefined;
checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
constructor() {
if (AppAuthMethod === 'oidc') {
this.oidcSecurityService = this.injector.get(OidcSecurityService);
this.checkAuthResultEvent$ = this.injector.get(CHECK_AUTH_RESULT_EVENT);
} else {
this.checkAuthResultEvent$ = NEVER;
}
}
private authProvider = inject(AUTH_PROVIDER);
isAuthenticated$ = this.authProvider.isAuthenticated$;
userData$ = this.authProvider.userData$;
checkAuthResultEvent$ = this.authProvider.checkAuthResultEvent$;
setup() {
if (AppAuthMethod === AuthMethodEnum.OIDC) {
this.oidcSecurityService!.checkAuth().subscribe();
}
}
get isAuthenticated$() {
return (
this.oidcSecurityService?.isAuthenticated$.pipe(
map((s) => s.isAuthenticated)
) ?? BASIC_AUTH_IS_AUTHENTICATED$
);
}
get userData$() {
return (
this.oidcSecurityService?.userData$?.pipe(map((s) => s.userData)) ??
BASIC_AUTH_USER_DATA$
);
}
getAccessToken(): Observable<string | undefined> {
return this.oidcSecurityService?.getAccessToken() ?? of(undefined);
this.authProvider.setup();
}
}

View File

@ -0,0 +1,27 @@
import { InjectionToken } from '@outposts/injection-js';
import type { CheckAuthResultEventType } from 'oidc-client-rx';
import { type Observable, map } from 'rxjs';
import type { AuthMethodType } from './defs';
export abstract class AuthProvider {
abstract authMethod: AuthMethodType;
abstract checkAuthResultEvent$: Observable<CheckAuthResultEventType>;
abstract isAuthenticated$: Observable<boolean>;
abstract userData$: Observable<any>;
abstract getAccessToken(): Observable<string | undefined>;
abstract setup(): void;
abstract autoLoginPartialRoutesGuard(): Observable<boolean>;
getAuthHeaders(): Observable<Record<string, string>> {
return this.getAccessToken().pipe(
map((accessToken) =>
accessToken
? {
Authorization: `Bearer ${accessToken}`,
}
: ({} as Record<string, string>)
)
);
}
}
export const AUTH_PROVIDER = new InjectionToken<AuthProvider>('AUTH_PROVIDER');

View File

@ -0,0 +1,22 @@
import { UnreachableError } from '@/infra/errors/common';
import type { CheckAuthResultEventType } from 'oidc-client-rx';
import { NEVER, type Observable, of } from 'rxjs';
import { AuthProvider } from '../auth.provider';
import { AUTH_METHOD } from '../defs';
export class BasicAuthProvider extends AuthProvider {
authMethod = AUTH_METHOD.BASIC;
isAuthenticated$ = of(true);
userData$ = of({});
checkAuthResultEvent$: Observable<CheckAuthResultEventType> = NEVER;
getAccessToken(): Observable<string | undefined> {
return of(undefined);
}
setup(): void {}
autoLoginPartialRoutesGuard(): Observable<boolean> {
throw new UnreachableError('Basic auth should always be authenticated');
}
}

View File

@ -0,0 +1 @@
export { BasicAuthProvider } from './basic-auth.provider';

View File

@ -0,0 +1,12 @@
import type { ValueOf } from 'type-fest';
export const AUTH_METHOD = {
BASIC: 'basic',
OIDC: 'oidc',
} as const;
export type AuthMethodType = ValueOf<typeof AUTH_METHOD>;
export function getAppAuthMethod(): AuthMethodType {
return process.env.AUTH_TYPE as AuthMethodType;
}

View File

@ -1,14 +1,4 @@
import { LogLevel, type OpenIdConfiguration } from 'oidc-client-rx';
import type { ValueOf } from 'type-fest';
export const AuthMethodEnum = {
BASIC: 'basic',
OIDC: 'oidc',
} as const;
export type AuthMethodType = ValueOf<typeof AuthMethodEnum>;
export const AppAuthMethod = process.env.AUTH_TYPE as AuthMethodType;
export function buildOidcConfig(): OpenIdConfiguration {
const origin = window.location.origin;

View File

@ -0,0 +1,2 @@
export { buildOidcConfig } from './config';
export { OidcAuthProvider } from './oidc-auth.provider';

View File

@ -0,0 +1,41 @@
import { injectInjector } from '@/infra/di/inject';
import { inject, runInInjectionContext } from '@outposts/injection-js';
import {
CHECK_AUTH_RESULT_EVENT,
OidcSecurityService,
autoLoginPartialRoutesGuard,
} from 'oidc-client-rx';
import { type Observable, map } from 'rxjs';
import { AuthProvider } from '../auth.provider';
import { AUTH_METHOD } from '../defs';
export class OidcAuthProvider extends AuthProvider {
authMethod = AUTH_METHOD.OIDC;
oidcSecurityService = inject(OidcSecurityService);
checkAuthResultEvent$ = inject(CHECK_AUTH_RESULT_EVENT);
injector = injectInjector();
setup() {
this.oidcSecurityService.checkAuth().subscribe();
}
get isAuthenticated$() {
return this.oidcSecurityService.isAuthenticated$.pipe(
map((s) => s.isAuthenticated)
);
}
get userData$() {
return this.oidcSecurityService.userData$.pipe(map((s) => s.userData));
}
getAccessToken(): Observable<string | undefined> {
return this.oidcSecurityService.getAccessToken();
}
autoLoginPartialRoutesGuard() {
return runInInjectionContext(this.injector, () =>
autoLoginPartialRoutesGuard()
);
}
}

View File

@ -0,0 +1,16 @@
import type { Injector, Provider } from '@outposts/injection-js';
import { GraphQLService } from './graphql.service';
export function provideGraphql(): Provider[] {
return [GraphQLService];
}
export interface GraphQLContext {
graphqlService: GraphQLService;
}
export function graphqlContextFromInjector(injector: Injector): GraphQLContext {
return {
graphqlService: injector.get(GraphQLService),
};
}

View File

@ -0,0 +1,30 @@
import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client';
import { setContext } from '@apollo/client/link/context';
import { Injectable, inject } from '@outposts/injection-js';
import { firstValueFrom } from 'rxjs';
import { AUTH_PROVIDER } from '../auth/auth.provider.ts';
@Injectable()
export class GraphQLService {
private authProvider = inject(AUTH_PROVIDER);
private apiLink = createHttpLink({
uri: '/api/graphql',
});
private authLink = setContext(async (_, { headers }) => {
const authHeaders = await firstValueFrom(
this.authProvider.getAuthHeaders()
);
return { headers: { ...headers, ...authHeaders } };
});
_apollo = new ApolloClient({
link: this.authLink.concat(this.apiLink),
cache: new InMemoryCache(),
});
query = this._apollo.query;
mutate = this._apollo.mutate;
watchQuery = this._apollo.watchQuery;
}

View File

@ -0,0 +1,2 @@
export { GraphQLService } from './graphql.service';
export { provideGraphql } from './context';

View File

@ -1,21 +0,0 @@
import React from 'react';
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener('change', onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener('change', onChange);
}, []);
return !!isMobile;
}

View File

@ -1,7 +0,0 @@
import { Injectable, inject } from '@outposts/injection-js';
import { OidcSecurityService } from 'oidc-client-rx';
@Injectable()
export class HttpService {
authService = inject(OidcSecurityService);
}

View File

@ -1,4 +1,4 @@
import type { ProLinkProps } from '@/components/ui/pro-link';
import type { ProLinkProps } from '@/views/components/ui/pro-link';
import type { Injector } from '@outposts/injection-js';
import type { LucideIcon } from 'lucide-react';

View File

@ -1,5 +1,5 @@
import { guardRouteIndexAsNotFound } from '@/components/layout/app-not-found';
import type { RouteStateDataOption } from '@/infra/routes/traits';
import { guardRouteIndexAsNotFound } from '@/views/components/layout/app-not-found';
import { Outlet } from '@tanstack/react-router';
export interface BuildVirtualBranchRouteOptions {

View File

@ -3,6 +3,8 @@ import { provideAuth, setupAuthContext } from '@/app/auth/context';
import { providePlatform } from '@/infra/platform/context';
import { provideStorages } from '@/infra/storage/context';
import { provideStyles } from '@/infra/styles/context';
import { AppNotFoundComponent } from '@/views/components/layout/app-not-found';
import { routeTree } from '@/views/routeTree.gen';
import { type Injector, ReflectiveInjector } from '@outposts/injection-js';
import { RouterProvider, createRouter } from '@tanstack/react-router';
import {
@ -11,9 +13,10 @@ import {
} from 'oidc-client-rx/adapters/react';
import { Suspense } from 'react';
import { createRoot } from 'react-dom/client';
import { AppNotFoundComponent } from './components/layout/app-not-found';
import { routeTree } from './routeTree.gen';
import './app.css';
import { ApolloProvider } from '@apollo/client';
import { provideGraphql } from './infra/graphql';
import { graphqlContextFromInjector } from './infra/graphql/context';
// Create a new router instance
const router = createRouter({
@ -40,22 +43,27 @@ const injector: Injector = ReflectiveInjector.resolveAndCreate([
...provideStorages(),
...provideAuth(router),
...provideStyles(),
...provideGraphql(),
]);
setupAuthContext(injector);
const rootElement = document.getElementById('root');
const { graphqlService } = graphqlContextFromInjector(injector);
const App = () => {
return (
<InjectorProvider injector={injector}>
<Suspense>
<RouterProvider
router={router}
context={{
injector,
}}
/>
<ApolloProvider client={graphqlService._apollo}>
<RouterProvider
router={router}
context={{
injector,
}}
/>
</ApolloProvider>
</Suspense>
</InjectorProvider>
);

View File

@ -2,9 +2,9 @@ import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from '@/components/ui/sidebar';
} from '@/views/components/ui/sidebar';
import { Image } from '@/components/ui/image';
import { Image } from '@/views/components/ui/image';
export function AppIcon() {
return (

View File

@ -1,4 +1,6 @@
import { AppSidebar } from '@/components/layout/app-sidebar';
import type { RouteStateDataOption } from '@/infra/routes/traits';
import type { RouteBreadcrumbItem } from '@/infra/routes/traits';
import { AppSidebar } from '@/views/components/layout/app-sidebar';
import {
Breadcrumb,
BreadcrumbItem,
@ -6,16 +8,14 @@ import {
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/components/ui/breadcrumb';
import { Separator } from '@/components/ui/separator';
} from '@/views/components/ui/breadcrumb';
import { Separator } from '@/views/components/ui/separator';
import {
SidebarInset,
SidebarProvider,
SidebarTrigger,
} from '@/components/ui/sidebar';
import type { RouteStateDataOption } from '@/infra/routes/traits';
import type { RouteBreadcrumbItem } from '@/infra/routes/traits';
import { cn } from '@/infra/styles/utils';
} from '@/views/components/ui/sidebar';
import { cn } from '@/views/utils';
import { useMatches } from '@tanstack/react-router';
import {
type DetailedHTMLProps,

View File

@ -1,11 +1,11 @@
import { AppNavMainData } from '@/infra/routes/nav';
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarRail,
} from '@/components/ui/sidebar';
import { AppNavMainData } from '@/infra/routes/nav';
} from '@/views/components/ui/sidebar';
import type { ComponentPropsWithoutRef } from 'react';
import { AppIcon } from './app-icon';
import { NavMain } from './nav-main';

View File

@ -6,7 +6,7 @@ import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible';
} from '@/views/components/ui/collapsible';
import {
SidebarGroup,
SidebarGroupLabel,
@ -16,7 +16,7 @@ import {
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
} from '@/components/ui/sidebar';
} from '@/views/components/ui/sidebar';
import { useMatches } from '@tanstack/react-router';
import { ProLink, type ProLinkProps } from '../ui/pro-link';

View File

@ -16,7 +16,7 @@ import {
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
} from '@/views/components/ui/dropdown-menu';
import {
SidebarGroup,
SidebarGroupLabel,
@ -25,7 +25,7 @@ import {
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from '@/components/ui/sidebar';
} from '@/views/components/ui/sidebar';
import type { ComponentProps } from 'react';
export function NavProjects({

View File

@ -9,7 +9,11 @@ import {
Sparkles,
} from 'lucide-react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import {
Avatar,
AvatarFallback,
AvatarImage,
} from '@/views/components/ui/avatar';
import {
DropdownMenu,
DropdownMenuContent,
@ -18,13 +22,13 @@ import {
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
} from '@/views/components/ui/dropdown-menu';
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from '@/components/ui/sidebar';
} from '@/views/components/ui/sidebar';
export function NavUser({
user,

View File

@ -1,13 +1,13 @@
import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDownIcon } from "lucide-react"
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { ChevronDownIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Accordion({
...props
}: React.ComponentProps<typeof AccordionPrimitive.Root>) {
return <AccordionPrimitive.Root data-slot="accordion" {...props} />
return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
}
function AccordionItem({
@ -20,7 +20,7 @@ function AccordionItem({
className={cn("border-b last:border-b-0", className)}
{...props}
/>
)
);
}
function AccordionTrigger({
@ -42,7 +42,7 @@ function AccordionTrigger({
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" />
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
)
);
}
function AccordionContent({
@ -58,7 +58,7 @@ function AccordionContent({
>
<div className={cn("pt-0 pb-4", className)}>{children}</div>
</AccordionPrimitive.Content>
)
);
}
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };

View File

@ -1,15 +1,15 @@
"use client"
"use client";
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { buttonVariants } from "@/components/ui/button"
import { buttonVariants } from "@/views/components/ui/button";
import { cn } from "@/views/utils";
function AlertDialog({
...props
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
}
function AlertDialogTrigger({
@ -17,7 +17,7 @@ function AlertDialogTrigger({
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
return (
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
)
);
}
function AlertDialogPortal({
@ -25,7 +25,7 @@ function AlertDialogPortal({
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
return (
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
)
);
}
function AlertDialogOverlay({
@ -41,7 +41,7 @@ function AlertDialogOverlay({
)}
{...props}
/>
)
);
}
function AlertDialogContent({
@ -60,7 +60,7 @@ function AlertDialogContent({
{...props}
/>
</AlertDialogPortal>
)
);
}
function AlertDialogHeader({
@ -73,7 +73,7 @@ function AlertDialogHeader({
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
)
);
}
function AlertDialogFooter({
@ -89,7 +89,7 @@ function AlertDialogFooter({
)}
{...props}
/>
)
);
}
function AlertDialogTitle({
@ -102,7 +102,7 @@ function AlertDialogTitle({
className={cn("text-lg font-semibold", className)}
{...props}
/>
)
);
}
function AlertDialogDescription({
@ -115,7 +115,7 @@ function AlertDialogDescription({
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
function AlertDialogAction({
@ -127,7 +127,7 @@ function AlertDialogAction({
className={cn(buttonVariants(), className)}
{...props}
/>
)
);
}
function AlertDialogCancel({
@ -139,7 +139,7 @@ function AlertDialogCancel({
className={cn(buttonVariants({ variant: "outline" }), className)}
{...props}
/>
)
);
}
export {
@ -154,4 +154,4 @@ export {
AlertDialogDescription,
AlertDialogAction,
AlertDialogCancel,
}
};

View File

@ -1,7 +1,7 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
const alertVariants = cva(
"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
@ -17,7 +17,7 @@ const alertVariants = cva(
variant: "default",
},
}
)
);
function Alert({
className,
@ -31,7 +31,7 @@ function Alert({
className={cn(alertVariants({ variant }), className)}
{...props}
/>
)
);
}
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
@ -44,7 +44,7 @@ function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function AlertDescription({
@ -60,7 +60,7 @@ function AlertDescription({
)}
{...props}
/>
)
);
}
export { Alert, AlertTitle, AlertDescription }
export { Alert, AlertTitle, AlertDescription };

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"
import * as AvatarPrimitive from "@radix-ui/react-avatar";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Avatar({
className,
@ -18,7 +18,7 @@ function Avatar({
)}
{...props}
/>
)
);
}
function AvatarImage({
@ -31,7 +31,7 @@ function AvatarImage({
className={cn("aspect-square size-full", className)}
{...props}
/>
)
);
}
function AvatarFallback({
@ -47,7 +47,7 @@ function AvatarFallback({
)}
{...props}
/>
)
);
}
export { Avatar, AvatarImage, AvatarFallback }
export { Avatar, AvatarImage, AvatarFallback };

View File

@ -1,8 +1,8 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
const badgeVariants = cva(
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
@ -23,7 +23,7 @@ const badgeVariants = cva(
variant: "default",
},
}
)
);
function Badge({
className,
@ -32,7 +32,7 @@ function Badge({
...props
}: React.ComponentProps<"span"> &
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
const Comp = asChild ? Slot : "span"
const Comp = asChild ? Slot : "span";
return (
<Comp
@ -40,7 +40,7 @@ function Badge({
className={cn(badgeVariants({ variant }), className)}
{...props}
/>
)
);
}
export { Badge, badgeVariants }
export { Badge, badgeVariants };

View File

@ -1,11 +1,11 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { ChevronRight, MoreHorizontal } from "lucide-react"
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />;
}
function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
@ -18,7 +18,7 @@ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
)}
{...props}
/>
)
);
}
function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
@ -28,7 +28,7 @@ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
className={cn("inline-flex items-center gap-1.5", className)}
{...props}
/>
)
);
}
function BreadcrumbLink({
@ -36,9 +36,9 @@ function BreadcrumbLink({
className,
...props
}: React.ComponentProps<"a"> & {
asChild?: boolean
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "a"
const Comp = asChild ? Slot : "a";
return (
<Comp
@ -46,7 +46,7 @@ function BreadcrumbLink({
className={cn("hover:text-foreground transition-colors", className)}
{...props}
/>
)
);
}
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
@ -59,7 +59,7 @@ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
className={cn("text-foreground font-normal", className)}
{...props}
/>
)
);
}
function BreadcrumbSeparator({
@ -77,7 +77,7 @@ function BreadcrumbSeparator({
>
{children ?? <ChevronRight />}
</li>
)
);
}
function BreadcrumbEllipsis({
@ -95,7 +95,7 @@ function BreadcrumbEllipsis({
<MoreHorizontal className="size-4" />
<span className="sr-only">More</span>
</span>
)
);
}
export {
@ -106,4 +106,4 @@ export {
BreadcrumbPage,
BreadcrumbSeparator,
BreadcrumbEllipsis,
}
};

View File

@ -1,8 +1,8 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { Slot } from "@radix-ui/react-slot";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
@ -33,7 +33,7 @@ const buttonVariants = cva(
size: "default",
},
}
)
);
function Button({
className,
@ -43,9 +43,9 @@ function Button({
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
asChild?: boolean;
}) {
const Comp = asChild ? Slot : "button"
const Comp = asChild ? Slot : "button";
return (
<Comp
@ -53,7 +53,7 @@ function Button({
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
);
}
export { Button, buttonVariants }
export { Button, buttonVariants };

View File

@ -1,9 +1,9 @@
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import { ChevronLeft, ChevronRight } from "lucide-react";
import * as React from "react";
import { DayPicker } from "react-day-picker";
import { cn } from "@/infra/styles/utils"
import { buttonVariants } from "@/components/ui/button"
import { buttonVariants } from "@/views/components/ui/button";
import { cn } from "@/views/utils";
function Calendar({
className,
@ -67,7 +67,7 @@ function Calendar({
}}
{...props}
/>
)
);
}
export { Calendar }
export { Calendar };

View File

@ -1,6 +1,6 @@
import * as React from "react"
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
@ -12,7 +12,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
@ -25,7 +25,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
@ -35,7 +35,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
className={cn("leading-none font-semibold", className)}
{...props}
/>
)
);
}
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
@ -45,7 +45,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
@ -58,7 +58,7 @@ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
@ -68,7 +68,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
className={cn("px-6", className)}
{...props}
/>
)
);
}
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
@ -78,7 +78,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
{...props}
/>
)
);
}
export {
@ -89,4 +89,4 @@ export {
CardAction,
CardDescription,
CardContent,
}
};

View File

@ -1,45 +1,45 @@
"use client"
"use client";
import * as React from "react"
import useEmblaCarousel, {
type UseEmblaCarouselType,
} from "embla-carousel-react"
import { ArrowLeft, ArrowRight } from "lucide-react"
} from "embla-carousel-react";
import { ArrowLeft, ArrowRight } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { Button } from "@/components/ui/button"
import { Button } from "@/views/components/ui/button";
import { cn } from "@/views/utils";
type CarouselApi = UseEmblaCarouselType[1]
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin = UseCarouselParameters[1]
type CarouselApi = UseEmblaCarouselType[1];
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
type CarouselOptions = UseCarouselParameters[0];
type CarouselPlugin = UseCarouselParameters[1];
type CarouselProps = {
opts?: CarouselOptions
plugins?: CarouselPlugin
orientation?: "horizontal" | "vertical"
setApi?: (api: CarouselApi) => void
}
opts?: CarouselOptions;
plugins?: CarouselPlugin;
orientation?: "horizontal" | "vertical";
setApi?: (api: CarouselApi) => void;
};
type CarouselContextProps = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
api: ReturnType<typeof useEmblaCarousel>[1]
scrollPrev: () => void
scrollNext: () => void
canScrollPrev: boolean
canScrollNext: boolean
} & CarouselProps
carouselRef: ReturnType<typeof useEmblaCarousel>[0];
api: ReturnType<typeof useEmblaCarousel>[1];
scrollPrev: () => void;
scrollNext: () => void;
canScrollPrev: boolean;
canScrollNext: boolean;
} & CarouselProps;
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
const CarouselContext = React.createContext<CarouselContextProps | null>(null);
function useCarousel() {
const context = React.useContext(CarouselContext)
const context = React.useContext(CarouselContext);
if (!context) {
throw new Error("useCarousel must be used within a <Carousel />")
throw new Error("useCarousel must be used within a <Carousel />");
}
return context
return context;
}
function Carousel({
@ -57,52 +57,52 @@ function Carousel({
axis: orientation === "horizontal" ? "x" : "y",
},
plugins
)
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
const [canScrollNext, setCanScrollNext] = React.useState(false)
);
const [canScrollPrev, setCanScrollPrev] = React.useState(false);
const [canScrollNext, setCanScrollNext] = React.useState(false);
const onSelect = React.useCallback((api: CarouselApi) => {
if (!api) return
setCanScrollPrev(api.canScrollPrev())
setCanScrollNext(api.canScrollNext())
}, [])
if (!api) return;
setCanScrollPrev(api.canScrollPrev());
setCanScrollNext(api.canScrollNext());
}, []);
const scrollPrev = React.useCallback(() => {
api?.scrollPrev()
}, [api])
api?.scrollPrev();
}, [api]);
const scrollNext = React.useCallback(() => {
api?.scrollNext()
}, [api])
api?.scrollNext();
}, [api]);
const handleKeyDown = React.useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === "ArrowLeft") {
event.preventDefault()
scrollPrev()
event.preventDefault();
scrollPrev();
} else if (event.key === "ArrowRight") {
event.preventDefault()
scrollNext()
event.preventDefault();
scrollNext();
}
},
[scrollPrev, scrollNext]
)
);
React.useEffect(() => {
if (!api || !setApi) return
setApi(api)
}, [api, setApi])
if (!api || !setApi) return;
setApi(api);
}, [api, setApi]);
React.useEffect(() => {
if (!api) return
onSelect(api)
api.on("reInit", onSelect)
api.on("select", onSelect)
if (!api) return;
onSelect(api);
api.on("reInit", onSelect);
api.on("select", onSelect);
return () => {
api?.off("select", onSelect)
}
}, [api, onSelect])
api?.off("select", onSelect);
};
}, [api, onSelect]);
return (
<CarouselContext.Provider
@ -129,11 +129,11 @@ function Carousel({
{children}
</div>
</CarouselContext.Provider>
)
);
}
function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
const { carouselRef, orientation } = useCarousel()
const { carouselRef, orientation } = useCarousel();
return (
<div
@ -150,11 +150,11 @@ function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
{...props}
/>
</div>
)
);
}
function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
const { orientation } = useCarousel()
const { orientation } = useCarousel();
return (
<div
@ -168,7 +168,7 @@ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function CarouselPrevious({
@ -177,7 +177,7 @@ function CarouselPrevious({
size = "icon",
...props
}: React.ComponentProps<typeof Button>) {
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
return (
<Button
@ -198,7 +198,7 @@ function CarouselPrevious({
<ArrowLeft />
<span className="sr-only">Previous slide</span>
</Button>
)
);
}
function CarouselNext({
@ -207,7 +207,7 @@ function CarouselNext({
size = "icon",
...props
}: React.ComponentProps<typeof Button>) {
const { orientation, scrollNext, canScrollNext } = useCarousel()
const { orientation, scrollNext, canScrollNext } = useCarousel();
return (
<Button
@ -228,7 +228,7 @@ function CarouselNext({
<ArrowRight />
<span className="sr-only">Next slide</span>
</Button>
)
);
}
export {
@ -238,4 +238,4 @@ export {
CarouselItem,
CarouselPrevious,
CarouselNext,
}
};

View File

@ -1,7 +1,7 @@
import * as React from "react";
import * as RechartsPrimitive from "recharts";
import { cn } from "@/infra/styles/utils";
import { cn } from "@/views/utils";
// Format: { THEME_NAME: CSS_SELECTOR }
const THEMES = { light: "", dark: ".dark" } as const;

View File

@ -1,10 +1,10 @@
"use client"
"use client";
import * as React from "react"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
import { CheckIcon } from "lucide-react"
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { CheckIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Checkbox({
className,
@ -26,7 +26,7 @@ function Checkbox({
<CheckIcon className="size-3.5" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
)
);
}
export { Checkbox }
export { Checkbox };

View File

@ -1,17 +1,17 @@
"use client"
"use client";
import * as React from "react"
import { Command as CommandPrimitive } from "cmdk"
import { SearchIcon } from "lucide-react"
import { Command as CommandPrimitive } from "cmdk";
import { SearchIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
} from "@/views/components/ui/dialog";
import { cn } from "@/views/utils";
function Command({
className,
@ -26,7 +26,7 @@ function Command({
)}
{...props}
/>
)
);
}
function CommandDialog({
@ -35,8 +35,8 @@ function CommandDialog({
children,
...props
}: React.ComponentProps<typeof Dialog> & {
title?: string
description?: string
title?: string;
description?: string;
}) {
return (
<Dialog {...props}>
@ -50,7 +50,7 @@ function CommandDialog({
</Command>
</DialogContent>
</Dialog>
)
);
}
function CommandInput({
@ -72,7 +72,7 @@ function CommandInput({
{...props}
/>
</div>
)
);
}
function CommandList({
@ -88,7 +88,7 @@ function CommandList({
)}
{...props}
/>
)
);
}
function CommandEmpty({
@ -100,7 +100,7 @@ function CommandEmpty({
className="py-6 text-center text-sm"
{...props}
/>
)
);
}
function CommandGroup({
@ -116,7 +116,7 @@ function CommandGroup({
)}
{...props}
/>
)
);
}
function CommandSeparator({
@ -129,7 +129,7 @@ function CommandSeparator({
className={cn("bg-border -mx-1 h-px", className)}
{...props}
/>
)
);
}
function CommandItem({
@ -145,7 +145,7 @@ function CommandItem({
)}
{...props}
/>
)
);
}
function CommandShortcut({
@ -161,7 +161,7 @@ function CommandShortcut({
)}
{...props}
/>
)
);
}
export {
@ -174,4 +174,4 @@ export {
CommandItem,
CommandShortcut,
CommandSeparator,
}
};

View File

@ -1,15 +1,15 @@
"use client"
"use client";
import * as React from "react"
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function ContextMenu({
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />;
}
function ContextMenuTrigger({
@ -17,7 +17,7 @@ function ContextMenuTrigger({
}: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
return (
<ContextMenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />
)
);
}
function ContextMenuGroup({
@ -25,7 +25,7 @@ function ContextMenuGroup({
}: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
return (
<ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
)
);
}
function ContextMenuPortal({
@ -33,13 +33,13 @@ function ContextMenuPortal({
}: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
return (
<ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
)
);
}
function ContextMenuSub({
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />
return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />;
}
function ContextMenuRadioGroup({
@ -50,7 +50,7 @@ function ContextMenuRadioGroup({
data-slot="context-menu-radio-group"
{...props}
/>
)
);
}
function ContextMenuSubTrigger({
@ -59,7 +59,7 @@ function ContextMenuSubTrigger({
children,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
inset?: boolean
inset?: boolean;
}) {
return (
<ContextMenuPrimitive.SubTrigger
@ -74,7 +74,7 @@ function ContextMenuSubTrigger({
{children}
<ChevronRightIcon className="ml-auto" />
</ContextMenuPrimitive.SubTrigger>
)
);
}
function ContextMenuSubContent({
@ -90,7 +90,7 @@ function ContextMenuSubContent({
)}
{...props}
/>
)
);
}
function ContextMenuContent({
@ -108,7 +108,7 @@ function ContextMenuContent({
{...props}
/>
</ContextMenuPrimitive.Portal>
)
);
}
function ContextMenuItem({
@ -117,8 +117,8 @@ function ContextMenuItem({
variant = "default",
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
inset?: boolean
variant?: "default" | "destructive"
inset?: boolean;
variant?: "default" | "destructive";
}) {
return (
<ContextMenuPrimitive.Item
@ -131,7 +131,7 @@ function ContextMenuItem({
)}
{...props}
/>
)
);
}
function ContextMenuCheckboxItem({
@ -157,7 +157,7 @@ function ContextMenuCheckboxItem({
</span>
{children}
</ContextMenuPrimitive.CheckboxItem>
)
);
}
function ContextMenuRadioItem({
@ -181,7 +181,7 @@ function ContextMenuRadioItem({
</span>
{children}
</ContextMenuPrimitive.RadioItem>
)
);
}
function ContextMenuLabel({
@ -189,7 +189,7 @@ function ContextMenuLabel({
inset,
...props
}: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
inset?: boolean
inset?: boolean;
}) {
return (
<ContextMenuPrimitive.Label
@ -201,7 +201,7 @@ function ContextMenuLabel({
)}
{...props}
/>
)
);
}
function ContextMenuSeparator({
@ -214,7 +214,7 @@ function ContextMenuSeparator({
className={cn("bg-border -mx-1 my-1 h-px", className)}
{...props}
/>
)
);
}
function ContextMenuShortcut({
@ -230,7 +230,7 @@ function ContextMenuShortcut({
)}
{...props}
/>
)
);
}
export {
@ -249,4 +249,4 @@ export {
ContextMenuSubContent,
ContextMenuSubTrigger,
ContextMenuRadioGroup,
}
};

View File

@ -1,31 +1,31 @@
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Dialog({
...props
}: React.ComponentProps<typeof DialogPrimitive.Root>) {
return <DialogPrimitive.Root data-slot="dialog" {...props} />
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
}
function DialogTrigger({
...props
}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
}
function DialogPortal({
...props
}: React.ComponentProps<typeof DialogPrimitive.Portal>) {
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
}
function DialogClose({
...props
}: React.ComponentProps<typeof DialogPrimitive.Close>) {
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
}
function DialogOverlay({
@ -41,7 +41,7 @@ function DialogOverlay({
)}
{...props}
/>
)
);
}
function DialogContent({
@ -67,7 +67,7 @@ function DialogContent({
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</DialogPortal>
)
);
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
@ -77,7 +77,7 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
{...props}
/>
)
);
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
@ -90,7 +90,7 @@ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
)}
{...props}
/>
)
);
}
function DialogTitle({
@ -103,7 +103,7 @@ function DialogTitle({
className={cn("text-lg leading-none font-semibold", className)}
{...props}
/>
)
);
}
function DialogDescription({
@ -116,7 +116,7 @@ function DialogDescription({
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
export {
@ -130,4 +130,4 @@ export {
DialogPortal,
DialogTitle,
DialogTrigger,
}
};

View File

@ -1,30 +1,30 @@
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
import * as React from "react";
import { Drawer as DrawerPrimitive } from "vaul";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Drawer({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) {
return <DrawerPrimitive.Root data-slot="drawer" {...props} />
return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
}
function DrawerTrigger({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
}
function DrawerPortal({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
}
function DrawerClose({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Close>) {
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
}
function DrawerOverlay({
@ -40,7 +40,7 @@ function DrawerOverlay({
)}
{...props}
/>
)
);
}
function DrawerContent({
@ -67,7 +67,7 @@ function DrawerContent({
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
)
);
}
function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
@ -77,7 +77,7 @@ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex flex-col gap-1.5 p-4", className)}
{...props}
/>
)
);
}
function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
@ -87,7 +87,7 @@ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
);
}
function DrawerTitle({
@ -100,7 +100,7 @@ function DrawerTitle({
className={cn("text-foreground font-semibold", className)}
{...props}
/>
)
);
}
function DrawerDescription({
@ -113,7 +113,7 @@ function DrawerDescription({
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
export {
@ -127,4 +127,4 @@ export {
DrawerFooter,
DrawerTitle,
DrawerDescription,
}
};

View File

@ -1,15 +1,15 @@
"use client"
"use client";
import * as React from "react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function DropdownMenu({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
}
function DropdownMenuPortal({
@ -17,7 +17,7 @@ function DropdownMenuPortal({
}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {
return (
<DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
)
);
}
function DropdownMenuTrigger({
@ -28,7 +28,7 @@ function DropdownMenuTrigger({
data-slot="dropdown-menu-trigger"
{...props}
/>
)
);
}
function DropdownMenuContent({
@ -48,7 +48,7 @@ function DropdownMenuContent({
{...props}
/>
</DropdownMenuPrimitive.Portal>
)
);
}
function DropdownMenuGroup({
@ -56,7 +56,7 @@ function DropdownMenuGroup({
}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
return (
<DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
)
);
}
function DropdownMenuItem({
@ -65,8 +65,8 @@ function DropdownMenuItem({
variant = "default",
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
inset?: boolean
variant?: "default" | "destructive"
inset?: boolean;
variant?: "default" | "destructive";
}) {
return (
<DropdownMenuPrimitive.Item
@ -79,7 +79,7 @@ function DropdownMenuItem({
)}
{...props}
/>
)
);
}
function DropdownMenuCheckboxItem({
@ -105,7 +105,7 @@ function DropdownMenuCheckboxItem({
</span>
{children}
</DropdownMenuPrimitive.CheckboxItem>
)
);
}
function DropdownMenuRadioGroup({
@ -116,7 +116,7 @@ function DropdownMenuRadioGroup({
data-slot="dropdown-menu-radio-group"
{...props}
/>
)
);
}
function DropdownMenuRadioItem({
@ -140,7 +140,7 @@ function DropdownMenuRadioItem({
</span>
{children}
</DropdownMenuPrimitive.RadioItem>
)
);
}
function DropdownMenuLabel({
@ -148,7 +148,7 @@ function DropdownMenuLabel({
inset,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
inset?: boolean
inset?: boolean;
}) {
return (
<DropdownMenuPrimitive.Label
@ -160,7 +160,7 @@ function DropdownMenuLabel({
)}
{...props}
/>
)
);
}
function DropdownMenuSeparator({
@ -173,7 +173,7 @@ function DropdownMenuSeparator({
className={cn("bg-border -mx-1 my-1 h-px", className)}
{...props}
/>
)
);
}
function DropdownMenuShortcut({
@ -189,13 +189,13 @@ function DropdownMenuShortcut({
)}
{...props}
/>
)
);
}
function DropdownMenuSub({
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
}
function DropdownMenuSubTrigger({
@ -204,7 +204,7 @@ function DropdownMenuSubTrigger({
children,
...props
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
inset?: boolean
inset?: boolean;
}) {
return (
<DropdownMenuPrimitive.SubTrigger
@ -219,7 +219,7 @@ function DropdownMenuSubTrigger({
{children}
<ChevronRightIcon className="ml-auto size-4" />
</DropdownMenuPrimitive.SubTrigger>
)
);
}
function DropdownMenuSubContent({
@ -235,7 +235,7 @@ function DropdownMenuSubContent({
)}
{...props}
/>
)
);
}
export {
@ -254,4 +254,4 @@ export {
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
}
};

View File

@ -11,8 +11,8 @@ import {
useFormState,
} from "react-hook-form";
import { Label } from "@/components/ui/label";
import { cn } from "@/infra/styles/utils";
import { Label } from "@/views/components/ui/label";
import { cn } from "@/views/utils";
const Form = FormProvider;

View File

@ -1,12 +1,12 @@
import * as React from "react"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function HoverCard({
...props
}: React.ComponentProps<typeof HoverCardPrimitive.Root>) {
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />
return <HoverCardPrimitive.Root data-slot="hover-card" {...props} />;
}
function HoverCardTrigger({
@ -14,7 +14,7 @@ function HoverCardTrigger({
}: React.ComponentProps<typeof HoverCardPrimitive.Trigger>) {
return (
<HoverCardPrimitive.Trigger data-slot="hover-card-trigger" {...props} />
)
);
}
function HoverCardContent({
@ -36,7 +36,7 @@ function HoverCardContent({
{...props}
/>
</HoverCardPrimitive.Portal>
)
);
}
export { HoverCard, HoverCardTrigger, HoverCardContent }
export { HoverCard, HoverCardTrigger, HoverCardContent };

View File

@ -1,17 +1,17 @@
"use client"
"use client";
import * as React from "react"
import { OTPInput, OTPInputContext } from "input-otp"
import { MinusIcon } from "lucide-react"
import { OTPInput, OTPInputContext } from "input-otp";
import { MinusIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function InputOTP({
className,
containerClassName,
...props
}: React.ComponentProps<typeof OTPInput> & {
containerClassName?: string
containerClassName?: string;
}) {
return (
<OTPInput
@ -23,7 +23,7 @@ function InputOTP({
className={cn("disabled:cursor-not-allowed", className)}
{...props}
/>
)
);
}
function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
@ -33,7 +33,7 @@ function InputOTPGroup({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex items-center", className)}
{...props}
/>
)
);
}
function InputOTPSlot({
@ -41,10 +41,10 @@ function InputOTPSlot({
className,
...props
}: React.ComponentProps<"div"> & {
index: number
index: number;
}) {
const inputOTPContext = React.useContext(OTPInputContext)
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}
const inputOTPContext = React.useContext(OTPInputContext);
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
return (
<div
@ -63,7 +63,7 @@ function InputOTPSlot({
</div>
)}
</div>
)
);
}
function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
@ -71,7 +71,7 @@ function InputOTPSeparator({ ...props }: React.ComponentProps<"div">) {
<div data-slot="input-otp-separator" role="separator" {...props}>
<MinusIcon />
</div>
)
);
}
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };

View File

@ -1,6 +1,6 @@
import * as React from "react"
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
@ -15,7 +15,7 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
)}
{...props}
/>
)
);
}
export { Input }
export { Input };

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import * as LabelPrimitive from "@radix-ui/react-label";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Label({
className,
@ -18,7 +18,7 @@ function Label({
)}
{...props}
/>
)
);
}
export { Label }
export { Label };

View File

@ -1,8 +1,8 @@
import * as React from "react"
import * as MenubarPrimitive from "@radix-ui/react-menubar"
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Menubar({
className,
@ -17,25 +17,25 @@ function Menubar({
)}
{...props}
/>
)
);
}
function MenubarMenu({
...props
}: React.ComponentProps<typeof MenubarPrimitive.Menu>) {
return <MenubarPrimitive.Menu data-slot="menubar-menu" {...props} />
return <MenubarPrimitive.Menu data-slot="menubar-menu" {...props} />;
}
function MenubarGroup({
...props
}: React.ComponentProps<typeof MenubarPrimitive.Group>) {
return <MenubarPrimitive.Group data-slot="menubar-group" {...props} />
return <MenubarPrimitive.Group data-slot="menubar-group" {...props} />;
}
function MenubarPortal({
...props
}: React.ComponentProps<typeof MenubarPrimitive.Portal>) {
return <MenubarPrimitive.Portal data-slot="menubar-portal" {...props} />
return <MenubarPrimitive.Portal data-slot="menubar-portal" {...props} />;
}
function MenubarRadioGroup({
@ -43,7 +43,7 @@ function MenubarRadioGroup({
}: React.ComponentProps<typeof MenubarPrimitive.RadioGroup>) {
return (
<MenubarPrimitive.RadioGroup data-slot="menubar-radio-group" {...props} />
)
);
}
function MenubarTrigger({
@ -59,7 +59,7 @@ function MenubarTrigger({
)}
{...props}
/>
)
);
}
function MenubarContent({
@ -83,7 +83,7 @@ function MenubarContent({
{...props}
/>
</MenubarPortal>
)
);
}
function MenubarItem({
@ -92,8 +92,8 @@ function MenubarItem({
variant = "default",
...props
}: React.ComponentProps<typeof MenubarPrimitive.Item> & {
inset?: boolean
variant?: "default" | "destructive"
inset?: boolean;
variant?: "default" | "destructive";
}) {
return (
<MenubarPrimitive.Item
@ -106,7 +106,7 @@ function MenubarItem({
)}
{...props}
/>
)
);
}
function MenubarCheckboxItem({
@ -132,7 +132,7 @@ function MenubarCheckboxItem({
</span>
{children}
</MenubarPrimitive.CheckboxItem>
)
);
}
function MenubarRadioItem({
@ -156,7 +156,7 @@ function MenubarRadioItem({
</span>
{children}
</MenubarPrimitive.RadioItem>
)
);
}
function MenubarLabel({
@ -164,7 +164,7 @@ function MenubarLabel({
inset,
...props
}: React.ComponentProps<typeof MenubarPrimitive.Label> & {
inset?: boolean
inset?: boolean;
}) {
return (
<MenubarPrimitive.Label
@ -176,7 +176,7 @@ function MenubarLabel({
)}
{...props}
/>
)
);
}
function MenubarSeparator({
@ -189,7 +189,7 @@ function MenubarSeparator({
className={cn("bg-border -mx-1 my-1 h-px", className)}
{...props}
/>
)
);
}
function MenubarShortcut({
@ -205,13 +205,13 @@ function MenubarShortcut({
)}
{...props}
/>
)
);
}
function MenubarSub({
...props
}: React.ComponentProps<typeof MenubarPrimitive.Sub>) {
return <MenubarPrimitive.Sub data-slot="menubar-sub" {...props} />
return <MenubarPrimitive.Sub data-slot="menubar-sub" {...props} />;
}
function MenubarSubTrigger({
@ -220,7 +220,7 @@ function MenubarSubTrigger({
children,
...props
}: React.ComponentProps<typeof MenubarPrimitive.SubTrigger> & {
inset?: boolean
inset?: boolean;
}) {
return (
<MenubarPrimitive.SubTrigger
@ -235,7 +235,7 @@ function MenubarSubTrigger({
{children}
<ChevronRightIcon className="ml-auto h-4 w-4" />
</MenubarPrimitive.SubTrigger>
)
);
}
function MenubarSubContent({
@ -251,7 +251,7 @@ function MenubarSubContent({
)}
{...props}
/>
)
);
}
export {
@ -271,4 +271,4 @@ export {
MenubarSub,
MenubarSubTrigger,
MenubarSubContent,
}
};

View File

@ -1,9 +1,9 @@
import * as React from "react"
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu"
import { cva } from "class-variance-authority"
import { ChevronDownIcon } from "lucide-react"
import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
import { cva } from "class-variance-authority";
import { ChevronDownIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function NavigationMenu({
className,
@ -11,7 +11,7 @@ function NavigationMenu({
viewport = true,
...props
}: React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
viewport?: boolean
viewport?: boolean;
}) {
return (
<NavigationMenuPrimitive.Root
@ -26,7 +26,7 @@ function NavigationMenu({
{children}
{viewport && <NavigationMenuViewport />}
</NavigationMenuPrimitive.Root>
)
);
}
function NavigationMenuList({
@ -42,7 +42,7 @@ function NavigationMenuList({
)}
{...props}
/>
)
);
}
function NavigationMenuItem({
@ -55,12 +55,12 @@ function NavigationMenuItem({
className={cn("relative", className)}
{...props}
/>
)
);
}
const navigationMenuTriggerStyle = cva(
"group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1"
)
);
function NavigationMenuTrigger({
className,
@ -79,7 +79,7 @@ function NavigationMenuTrigger({
aria-hidden="true"
/>
</NavigationMenuPrimitive.Trigger>
)
);
}
function NavigationMenuContent({
@ -96,7 +96,7 @@ function NavigationMenuContent({
)}
{...props}
/>
)
);
}
function NavigationMenuViewport({
@ -118,7 +118,7 @@ function NavigationMenuViewport({
{...props}
/>
</div>
)
);
}
function NavigationMenuLink({
@ -134,7 +134,7 @@ function NavigationMenuLink({
)}
{...props}
/>
)
);
}
function NavigationMenuIndicator({
@ -152,7 +152,7 @@ function NavigationMenuIndicator({
>
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
</NavigationMenuPrimitive.Indicator>
)
);
}
export {
@ -165,4 +165,4 @@ export {
NavigationMenuIndicator,
NavigationMenuViewport,
navigationMenuTriggerStyle,
}
};

View File

@ -1,12 +1,12 @@
import * as React from "react"
import {
ChevronLeftIcon,
ChevronRightIcon,
MoreHorizontalIcon,
} from "lucide-react"
} from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { Button, buttonVariants } from "@/components/ui/button"
import { Button, buttonVariants } from "@/views/components/ui/button";
import { cn } from "@/views/utils";
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
return (
@ -17,7 +17,7 @@ function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
className={cn("mx-auto flex w-full justify-center", className)}
{...props}
/>
)
);
}
function PaginationContent({
@ -30,17 +30,17 @@ function PaginationContent({
className={cn("flex flex-row items-center gap-1", className)}
{...props}
/>
)
);
}
function PaginationItem({ ...props }: React.ComponentProps<"li">) {
return <li data-slot="pagination-item" {...props} />
return <li data-slot="pagination-item" {...props} />;
}
type PaginationLinkProps = {
isActive?: boolean
isActive?: boolean;
} & Pick<React.ComponentProps<typeof Button>, "size"> &
React.ComponentProps<"a">
React.ComponentProps<"a">;
function PaginationLink({
className,
@ -62,7 +62,7 @@ function PaginationLink({
)}
{...props}
/>
)
);
}
function PaginationPrevious({
@ -79,7 +79,7 @@ function PaginationPrevious({
<ChevronLeftIcon />
<span className="hidden sm:block">Previous</span>
</PaginationLink>
)
);
}
function PaginationNext({
@ -96,7 +96,7 @@ function PaginationNext({
<span className="hidden sm:block">Next</span>
<ChevronRightIcon />
</PaginationLink>
)
);
}
function PaginationEllipsis({
@ -113,7 +113,7 @@ function PaginationEllipsis({
<MoreHorizontalIcon className="size-4" />
<span className="sr-only">More pages</span>
</span>
)
);
}
export {
@ -124,4 +124,4 @@ export {
PaginationPrevious,
PaginationNext,
PaginationEllipsis,
}
};

View File

@ -1,20 +1,20 @@
"use client"
"use client";
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
import * as PopoverPrimitive from "@radix-ui/react-popover";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Popover({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
return <PopoverPrimitive.Root data-slot="popover" {...props} />
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
}
function PopoverTrigger({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
}
function PopoverContent({
@ -36,13 +36,13 @@ function PopoverContent({
{...props}
/>
</PopoverPrimitive.Portal>
)
);
}
function PopoverAnchor({
...props
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
}
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };

View File

@ -1,7 +1,7 @@
import { cn } from '@/infra/styles/utils';
import type { FC, HTMLAttributes } from 'react';
import { cn } from "@/views/utils";
import type { FC, HTMLAttributes } from "react";
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
type Size = "xs" | "sm" | "md" | "lg" | "xl";
const sizes: Record<Size, { radius: number; strokeWidth: number }> = {
xs: { radius: 15, strokeWidth: 3 },
@ -23,7 +23,7 @@ const ProgressCircle: FC<ProgressCircleProps> = ({
className,
children,
value = 0,
size = 'md',
size = "md",
radius,
strokeWidth,
showAnimation = true,
@ -39,7 +39,7 @@ const ProgressCircle: FC<ProgressCircleProps> = ({
return (
<div
className={cn('flex flex-col items-center justify-center', className)}
className={cn("flex flex-col items-center justify-center", className)}
{...props}
>
<svg
@ -56,7 +56,7 @@ const ProgressCircle: FC<ProgressCircleProps> = ({
fill="transparent"
stroke=""
strokeLinecap="round"
className={cn('stroke-secondary transition-colors ease-linear')}
className={cn("stroke-secondary transition-colors ease-linear")}
/>
{currentValue >= 0 && (
<circle
@ -70,13 +70,13 @@ const ProgressCircle: FC<ProgressCircleProps> = ({
stroke=""
strokeLinecap="round"
className={cn(
'stroke-primary transition-colors ease-linear',
showAnimation ? 'transition-all duration-300 ease-in-out' : ''
"stroke-primary transition-colors ease-linear",
showAnimation ? "transition-all duration-300 ease-in-out" : ""
)}
/>
)}
</svg>
<div className={cn('absolute flex')}>{children}</div>
<div className={cn("absolute flex")}>{children}</div>
</div>
);
};

View File

@ -1,7 +1,7 @@
import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
import * as ProgressPrimitive from "@radix-ui/react-progress";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Progress({
className,
@ -23,7 +23,7 @@ function Progress({
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
)
);
}
export { Progress }
export { Progress };

View File

@ -1,10 +1,10 @@
"use client"
"use client";
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { CircleIcon } from "lucide-react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
import { CircleIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function RadioGroup({
className,
@ -16,7 +16,7 @@ function RadioGroup({
className={cn("grid gap-3", className)}
{...props}
/>
)
);
}
function RadioGroupItem({
@ -39,7 +39,7 @@ function RadioGroupItem({
<CircleIcon className="fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
)
);
}
export { RadioGroup, RadioGroupItem }
export { RadioGroup, RadioGroupItem };

View File

@ -1,8 +1,8 @@
import * as React from "react"
import { GripVerticalIcon } from "lucide-react"
import * as ResizablePrimitive from "react-resizable-panels"
import { GripVerticalIcon } from "lucide-react";
import * as React from "react";
import * as ResizablePrimitive from "react-resizable-panels";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function ResizablePanelGroup({
className,
@ -17,13 +17,13 @@ function ResizablePanelGroup({
)}
{...props}
/>
)
);
}
function ResizablePanel({
...props
}: React.ComponentProps<typeof ResizablePrimitive.Panel>) {
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />
return <ResizablePrimitive.Panel data-slot="resizable-panel" {...props} />;
}
function ResizableHandle({
@ -31,7 +31,7 @@ function ResizableHandle({
className,
...props
}: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
withHandle?: boolean
withHandle?: boolean;
}) {
return (
<ResizablePrimitive.PanelResizeHandle
@ -48,7 +48,7 @@ function ResizableHandle({
</div>
)}
</ResizablePrimitive.PanelResizeHandle>
)
);
}
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
export { ResizablePanelGroup, ResizablePanel, ResizableHandle };

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function ScrollArea({
className,
@ -25,7 +25,7 @@ function ScrollArea({
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
)
);
}
function ScrollBar({
@ -52,7 +52,7 @@ function ScrollBar({
className="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
)
);
}
export { ScrollArea, ScrollBar }
export { ScrollArea, ScrollBar };

View File

@ -1,25 +1,25 @@
import * as React from "react"
import * as SelectPrimitive from "@radix-ui/react-select"
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
import * as SelectPrimitive from "@radix-ui/react-select";
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Select({
...props
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
return <SelectPrimitive.Root data-slot="select" {...props} />
return <SelectPrimitive.Root data-slot="select" {...props} />;
}
function SelectGroup({
...props
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
return <SelectPrimitive.Group data-slot="select-group" {...props} />
return <SelectPrimitive.Group data-slot="select-group" {...props} />;
}
function SelectValue({
...props
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
return <SelectPrimitive.Value data-slot="select-value" {...props} />
return <SelectPrimitive.Value data-slot="select-value" {...props} />;
}
function SelectTrigger({
@ -28,7 +28,7 @@ function SelectTrigger({
children,
...props
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
size?: "sm" | "default"
size?: "sm" | "default";
}) {
return (
<SelectPrimitive.Trigger
@ -45,7 +45,7 @@ function SelectTrigger({
<ChevronDownIcon className="size-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
)
);
}
function SelectContent({
@ -80,7 +80,7 @@ function SelectContent({
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
)
);
}
function SelectLabel({
@ -93,7 +93,7 @@ function SelectLabel({
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
{...props}
/>
)
);
}
function SelectItem({
@ -117,7 +117,7 @@ function SelectItem({
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
)
);
}
function SelectSeparator({
@ -130,7 +130,7 @@ function SelectSeparator({
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
{...props}
/>
)
);
}
function SelectScrollUpButton({
@ -148,7 +148,7 @@ function SelectScrollUpButton({
>
<ChevronUpIcon className="size-4" />
</SelectPrimitive.ScrollUpButton>
)
);
}
function SelectScrollDownButton({
@ -166,7 +166,7 @@ function SelectScrollDownButton({
>
<ChevronDownIcon className="size-4" />
</SelectPrimitive.ScrollDownButton>
)
);
}
export {
@ -180,4 +180,4 @@ export {
SelectSeparator,
SelectTrigger,
SelectValue,
}
};

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as SeparatorPrimitive from "@radix-ui/react-separator"
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Separator({
className,
@ -22,7 +22,7 @@ function Separator({
)}
{...props}
/>
)
);
}
export { Separator }
export { Separator };

View File

@ -1,29 +1,29 @@
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
return <SheetPrimitive.Root data-slot="sheet" {...props} />
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
}
function SheetTrigger({
...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
}
function SheetClose({
...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
}
function SheetPortal({
...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
}
function SheetOverlay({
@ -39,7 +39,7 @@ function SheetOverlay({
)}
{...props}
/>
)
);
}
function SheetContent({
@ -48,7 +48,7 @@ function SheetContent({
side = "right",
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left"
side?: "top" | "right" | "bottom" | "left";
}) {
return (
<SheetPortal>
@ -76,7 +76,7 @@ function SheetContent({
</SheetPrimitive.Close>
</SheetPrimitive.Content>
</SheetPortal>
)
);
}
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
@ -86,7 +86,7 @@ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
className={cn("flex flex-col gap-1.5 p-4", className)}
{...props}
/>
)
);
}
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
@ -96,7 +96,7 @@ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
);
}
function SheetTitle({
@ -109,7 +109,7 @@ function SheetTitle({
className={cn("text-foreground font-semibold", className)}
{...props}
/>
)
);
}
function SheetDescription({
@ -122,7 +122,7 @@ function SheetDescription({
className={cn("text-muted-foreground text-sm", className)}
{...props}
/>
)
);
}
export {
@ -134,4 +134,4 @@ export {
SheetFooter,
SheetTitle,
SheetDescription,
}
};

View File

@ -5,25 +5,25 @@ import { VariantProps, cva } from "class-variance-authority";
import { PanelLeftIcon } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { Button } from "@/views/components/ui/button";
import { Input } from "@/views/components/ui/input";
import { Separator } from "@/views/components/ui/separator";
import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from "@/components/ui/sheet";
import { Skeleton } from "@/components/ui/skeleton";
} from "@/views/components/ui/sheet";
import { Skeleton } from "@/views/components/ui/skeleton";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { useIsMobile } from "@/infra/hooks/use-mobile";
import { cn } from "@/infra/styles/utils";
} from "@/views/components/ui/tooltip";
import { useIsMobile } from "@/views/hooks/use-mobile";
import { cn } from "@/views/utils";
const SIDEBAR_COOKIE_NAME = "sidebar_state";
const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
@ -83,7 +83,7 @@ function SidebarProvider({
}
// This sets the cookie to keep the sidebar state.
// TODO: FIXME
// TODO: FIX THIS
document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
},
[setOpenProp, open]

View File

@ -1,7 +1,7 @@
import { cn } from "@/infra/styles/utils";
import type React from "react";
import { cn } from "@/views/utils";
import { ComponentProps } from "react";
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
function Skeleton({ className, ...props }: ComponentProps<"div">) {
return (
<div
data-slot="skeleton"

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as SliderPrimitive from "@radix-ui/react-slider"
import * as SliderPrimitive from "@radix-ui/react-slider";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Slider({
className,
@ -21,7 +21,7 @@ function Slider({
? defaultValue
: [min, max],
[value, defaultValue, min, max]
)
);
return (
<SliderPrimitive.Root
@ -57,7 +57,7 @@ function Slider({
/>
))}
</SliderPrimitive.Root>
)
);
}
export { Slider }
export { Slider };

View File

@ -1,24 +1,24 @@
import { cn } from '@/infra/styles/utils';
import { cn } from "@/views/utils";
import {
Loader,
LoaderCircle,
LoaderPinwheel,
type LucideProps,
} from 'lucide-react';
} from "lucide-react";
export type SpinnerVariantProps = Omit<SpinnerProps, 'variant'>;
export type SpinnerVariantProps = Omit<SpinnerProps, "variant">;
const Default = ({ className, ...props }: SpinnerVariantProps) => {
return <Loader className={cn('animate-spin', className)} {...props} />;
return <Loader className={cn("animate-spin", className)} {...props} />;
};
const Circle = ({ className, ...props }: SpinnerVariantProps) => {
return <LoaderCircle className={cn('animate-spin', className)} {...props} />;
return <LoaderCircle className={cn("animate-spin", className)} {...props} />;
};
const Pinwheel = ({ className, ...props }: SpinnerVariantProps) => {
return (
<LoaderPinwheel className={cn('animate-spin', className)} {...props} />
<LoaderPinwheel className={cn("animate-spin", className)} {...props} />
);
};
@ -32,16 +32,16 @@ const CircleFilled = ({
<div className="absolute inset-0 rotate-180">
<LoaderCircle
className={cn(
'animate-spin',
"animate-spin",
className,
'text-foreground opacity-20'
"text-foreground opacity-20"
)}
size={size}
{...props}
/>
</div>
<LoaderCircle
className={cn('relative animate-spin', className)}
className={cn("relative animate-spin", className)}
size={size}
{...props}
/>
@ -233,8 +233,8 @@ const Infinite = ({ size = 24, ...props }: SpinnerVariantProps) => (
d="M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40 C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z"
strokeLinecap="round"
style={{
transform: 'scale(0.8)',
transformOrigin: '50px 50px',
transform: "scale(0.8)",
transformOrigin: "50px 50px",
}}
>
<animate
@ -250,31 +250,31 @@ const Infinite = ({ size = 24, ...props }: SpinnerVariantProps) => (
export type SpinnerProps = LucideProps & {
variant?:
| 'default'
| 'circle'
| 'pinwheel'
| 'circle-filled'
| 'ellipsis'
| 'ring'
| 'bars'
| 'infinite';
| "default"
| "circle"
| "pinwheel"
| "circle-filled"
| "ellipsis"
| "ring"
| "bars"
| "infinite";
};
export const Spinner = ({ variant, ...props }: SpinnerProps) => {
switch (variant) {
case 'circle':
case "circle":
return <Circle {...props} />;
case 'pinwheel':
case "pinwheel":
return <Pinwheel {...props} />;
case 'circle-filled':
case "circle-filled":
return <CircleFilled {...props} />;
case 'ellipsis':
case "ellipsis":
return <Ellipsis {...props} />;
case 'ring':
case "ring":
return <Ring {...props} />;
case 'bars':
case "bars":
return <Bars {...props} />;
case 'infinite':
case "infinite":
return <Infinite {...props} />;
default:
return <Default {...props} />;

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as SwitchPrimitive from "@radix-ui/react-switch"
import * as SwitchPrimitive from "@radix-ui/react-switch";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Switch({
className,
@ -25,7 +25,7 @@ function Switch({
)}
/>
</SwitchPrimitive.Root>
)
);
}
export { Switch }
export { Switch };

View File

@ -1,6 +1,6 @@
import * as React from "react"
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Table({ className, ...props }: React.ComponentProps<"table">) {
return (
@ -14,7 +14,7 @@ function Table({ className, ...props }: React.ComponentProps<"table">) {
{...props}
/>
</div>
)
);
}
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
@ -24,7 +24,7 @@ function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
className={cn("[&_tr]:border-b", className)}
{...props}
/>
)
);
}
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
@ -34,7 +34,7 @@ function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
className={cn("[&_tr:last-child]:border-0", className)}
{...props}
/>
)
);
}
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
@ -47,7 +47,7 @@ function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
)}
{...props}
/>
)
);
}
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
@ -60,7 +60,7 @@ function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
)}
{...props}
/>
)
);
}
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
@ -73,7 +73,7 @@ function TableHead({ className, ...props }: React.ComponentProps<"th">) {
)}
{...props}
/>
)
);
}
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
@ -86,7 +86,7 @@ function TableCell({ className, ...props }: React.ComponentProps<"td">) {
)}
{...props}
/>
)
);
}
function TableCaption({
@ -99,7 +99,7 @@ function TableCaption({
className={cn("text-muted-foreground mt-4 text-sm", className)}
{...props}
/>
)
);
}
export {
@ -111,4 +111,4 @@ export {
TableRow,
TableCell,
TableCaption,
}
};

View File

@ -1,9 +1,9 @@
"use client"
"use client";
import * as React from "react"
import * as TabsPrimitive from "@radix-ui/react-tabs"
import * as TabsPrimitive from "@radix-ui/react-tabs";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Tabs({
className,
@ -15,7 +15,7 @@ function Tabs({
className={cn("flex flex-col gap-2", className)}
{...props}
/>
)
);
}
function TabsList({
@ -31,7 +31,7 @@ function TabsList({
)}
{...props}
/>
)
);
}
function TabsTrigger({
@ -47,7 +47,7 @@ function TabsTrigger({
)}
{...props}
/>
)
);
}
function TabsContent({
@ -60,7 +60,7 @@ function TabsContent({
className={cn("flex-1 outline-none", className)}
{...props}
/>
)
);
}
export { Tabs, TabsList, TabsTrigger, TabsContent }
export { Tabs, TabsList, TabsTrigger, TabsContent };

View File

@ -1,6 +1,6 @@
import * as React from "react"
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
return (
@ -12,7 +12,7 @@ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
)}
{...props}
/>
)
);
}
export { Textarea }
export { Textarea };

View File

@ -1,18 +1,18 @@
"use client"
"use client";
import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
import { type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { toggleVariants } from "@/components/ui/toggle"
import { toggleVariants } from "@/views/components/ui/toggle";
import { cn } from "@/views/utils";
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
})
});
function ToggleGroup({
className,
@ -37,7 +37,7 @@ function ToggleGroup({
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
)
);
}
function ToggleGroupItem({
@ -48,7 +48,7 @@ function ToggleGroupItem({
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>) {
const context = React.useContext(ToggleGroupContext)
const context = React.useContext(ToggleGroupContext);
return (
<ToggleGroupPrimitive.Item
@ -67,7 +67,7 @@ function ToggleGroupItem({
>
{children}
</ToggleGroupPrimitive.Item>
)
);
}
export { ToggleGroup, ToggleGroupItem }
export { ToggleGroup, ToggleGroupItem };

View File

@ -1,8 +1,8 @@
import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
import * as TogglePrimitive from "@radix-ui/react-toggle";
import { type VariantProps, cva } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
const toggleVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
@ -24,7 +24,7 @@ const toggleVariants = cva(
size: "default",
},
}
)
);
function Toggle({
className,
@ -39,7 +39,7 @@ function Toggle({
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
)
);
}
export { Toggle, toggleVariants }
export { Toggle, toggleVariants };

View File

@ -1,7 +1,7 @@
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as React from "react";
import { cn } from "@/infra/styles/utils"
import { cn } from "@/views/utils";
function TooltipProvider({
delayDuration = 0,
@ -13,7 +13,7 @@ function TooltipProvider({
delayDuration={delayDuration}
{...props}
/>
)
);
}
function Tooltip({
@ -23,13 +23,13 @@ function Tooltip({
<TooltipProvider>
<TooltipPrimitive.Root data-slot="tooltip" {...props} />
</TooltipProvider>
)
);
}
function TooltipTrigger({
...props
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
}
function TooltipContent({
@ -53,7 +53,7 @@ function TooltipContent({
<TooltipPrimitive.Arrow className="bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
</TooltipPrimitive.Content>
</TooltipPrimitive.Portal>
)
);
}
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };

View File

@ -0,0 +1,19 @@
import * as React from "react"
const MOBILE_BREAKPOINT = 768
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
return !!isMobile
}

View File

@ -1,4 +1,4 @@
import { AppNotFoundComponent } from '@/components/layout/app-not-found';
import { AppNotFoundComponent } from '@/views/components/layout/app-not-found';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/404')({

View File

@ -11,23 +11,17 @@ export const Route = createLazyFileRoute('/_app/playground/graphql-api')({
});
function PlaygroundGraphQLApiRouteComponent() {
const { authContext } = useAuth();
const { authProvider } = useAuth();
const fetcher: Fetcher = useCallback(
async (props) => {
const accessToken = await firstValueFrom(
authContext.authService.getAccessToken()
);
const authHeaders = await firstValueFrom(authProvider.getAuthHeaders());
return createGraphiQLFetcher({
url: '/api/graphql',
headers: accessToken
? {
Authorization: `Bearer ${accessToken}`,
}
: undefined,
headers: authHeaders,
})(props);
},
[authContext.authService.getAccessToken]
[authProvider]
);
return (

View File

@ -1,5 +1,5 @@
import { AppSkeleton } from '@/components/layout/app-skeleton';
import { buildLeafRouteStaticData } from '@/infra/routes/utils';
import { AppSkeleton } from '@/views/components/layout/app-skeleton';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/_app/playground/graphql-api')({

View File

@ -1,5 +1,5 @@
import { beforeLoadGuard } from '@/app/auth/guard';
import { AppAside } from '@/components/layout/app-layout';
import { AppAside } from '@/views/components/layout/app-layout';
import { Outlet, createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/_app')({

View File

@ -1,5 +1,6 @@
import { useAuth } from '@/app/auth/hooks';
import { Button } from '@/components/ui/button';
import type { RouteStateDataOption } from '@/infra/routes/traits';
import { Button } from '@/views/components/ui/button';
import {
Card,
CardContent,
@ -7,7 +8,7 @@ import {
CardFooter,
CardHeader,
CardTitle,
} from '@/components/ui/card';
} from '@/views/components/ui/card';
import {
Form,
FormControl,
@ -16,17 +17,17 @@ import {
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input';
} from '@/views/components/ui/form';
import { Input } from '@/views/components/ui/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';
import type { RouteStateDataOption } from '@/infra/routes/traits';
} from '@/views/components/ui/select';
import { Switch } from '@/views/components/ui/switch';
import { gql, useMutation } from '@apollo/client';
import { createFileRoute } from '@tanstack/react-router';
import { useNavigate } from '@tanstack/react-router';
import { useState } from 'react';
@ -47,6 +48,18 @@ type SubscriptionFormValues = {
enabled: boolean;
};
const CREATE_SUBSCRIPTION_MUTATION = gql`
mutation CreateSubscription($input: SubscriptionsInsertInput!) {
subscriptionsCreateOne(data: $input) {
id
displayName
sourceUrl
enabled
category
}
}
`;
function SubscriptionCreateRouteComponent() {
const { userData } = useAuth();
console.log(JSON.stringify(userData, null, 2));
@ -61,21 +74,12 @@ function SubscriptionCreateRouteComponent() {
},
});
const [createSubscription] = useMutation(CREATE_SUBSCRIPTION_MUTATION);
const onSubmit = async (data: SubscriptionFormValues) => {
try {
setIsSubmitting(true);
const requestData = {
query: `
mutation CreateSubscription($input: SubscriptionsInsertInput!) {
subscriptionsCreateOne(data: $input) {
id
displayName
sourceUrl
enabled
category
}
}
`,
const response = await createSubscription({
variables: {
input: {
category: data.category,
@ -84,18 +88,11 @@ function SubscriptionCreateRouteComponent() {
enabled: data.enabled,
},
},
};
const response = await fetch('/api/graphql', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData),
});
const responseData = await response.json();
if (responseData.errors) {
if (response.errors) {
throw new Error(
responseData.errors[0]?.message || 'Failed to create subscription'
response.errors[0]?.message || 'Failed to create subscription'
);
}

View File

@ -1,8 +1,9 @@
import { AppAuthMethod, AuthMethodEnum } from '@/app/auth/config';
import { authContextFromInjector } from '@/app/auth/context';
import { useAuth } from '@/app/auth/hooks';
import { ProLink } from '@/components/ui/pro-link';
import { Spinner } from '@/components/ui/spinner';
import { createFileRoute } from '@tanstack/react-router';
import { AUTH_METHOD } from '@/infra/auth/defs';
import { ProLink } from '@/views/components/ui/pro-link';
import { Spinner } from '@/views/components/ui/spinner';
import { createFileRoute, redirect } from '@tanstack/react-router';
import { useAtom } from 'jotai/react';
import { atomWithObservable } from 'jotai/utils';
import { EventTypes } from 'oidc-client-rx';
@ -11,18 +12,24 @@ import { filter, map } from 'rxjs';
export const Route = createFileRoute('/auth/oidc/callback')({
component: OidcCallbackRouteComponent,
beforeLoad: ({ context }) => {
const { authProvider } = authContextFromInjector(context.injector);
if (authProvider.authMethod !== AUTH_METHOD.OIDC) {
throw redirect({ to: '/' });
}
},
});
function OidcCallbackRouteComponent() {
const { authContext } = useAuth();
const { authService } = useAuth();
const isLoading = useAtom(
useMemo(
() =>
atomWithObservable(() =>
authContext.checkAuthResultEvent$.pipe(map(Boolean))
authService.checkAuthResultEvent$.pipe(map(Boolean))
),
[authContext.checkAuthResultEvent$]
[authService.checkAuthResultEvent$]
)
);
@ -30,7 +37,7 @@ function OidcCallbackRouteComponent() {
useMemo(
() =>
atomWithObservable(() =>
authContext.checkAuthResultEvent$.pipe(
authService.checkAuthResultEvent$.pipe(
filter(
(
e
@ -42,7 +49,7 @@ function OidcCallbackRouteComponent() {
map((e) => e.value)
)
),
[authContext.checkAuthResultEvent$]
[authService.checkAuthResultEvent$]
)
);
@ -64,27 +71,19 @@ function OidcCallbackRouteComponent() {
<div className="flex justify-center font-bold text-4xl tracking-tighter sm:text-5xl">
<Spinner variant="circle-filled" size="48" />
</div>
{AppAuthMethod === AuthMethodEnum.OIDC ? (
<>
{isLoading && (
<p className="text-gray-500">
Processing OIDC authentication callback...
</p>
)}
{checkAuthResultError && (
<p className="text-gray-500">
Failed to handle OIDC callback: {checkAuthResultError}
</p>
)}
{!isLoading && !checkAuthResultError && (
<p className="text-gray-500">
Succeed to handle OIDC authentication callback.
</p>
)}
</>
) : (
{isLoading && (
<p className="text-gray-500">
Error: Current authentication method is not OIDC!
Processing OIDC authentication callback...
</p>
)}
{checkAuthResultError && (
<p className="text-gray-500">
Failed to handle OIDC callback: {checkAuthResultError}
</p>
)}
{!isLoading && !checkAuthResultError && (
<p className="text-gray-500">
Succeed to handle OIDC authentication callback.
</p>
)}
{renderBackToHome()}

View File

@ -1,5 +1,5 @@
import { AppAside } from '@/components/layout/app-layout';
import { AppSkeleton } from '@/components/layout/app-skeleton';
import { AppAside } from '@/views/components/layout/app-layout';
import { AppSkeleton } from '@/views/components/layout/app-skeleton';
import { createFileRoute } from '@tanstack/react-router';
export const Route = createFileRoute('/')({

Some files were not shown because too many files have changed in this diff Show More