refactor: refactor webui
This commit is contained in:
parent
b20f7cd1ad
commit
ee1b1ae5e6
@ -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"
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -26,9 +26,9 @@ export function useAuth() {
|
||||
);
|
||||
|
||||
return {
|
||||
...authContext,
|
||||
userData,
|
||||
injector,
|
||||
isAuthenticated,
|
||||
authContext,
|
||||
};
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
27
apps/webui/src/infra/auth/auth.provider.ts
Normal file
27
apps/webui/src/infra/auth/auth.provider.ts
Normal 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');
|
22
apps/webui/src/infra/auth/basic/basic-auth.provider.ts
Normal file
22
apps/webui/src/infra/auth/basic/basic-auth.provider.ts
Normal 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');
|
||||
}
|
||||
}
|
1
apps/webui/src/infra/auth/basic/index.ts
Normal file
1
apps/webui/src/infra/auth/basic/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { BasicAuthProvider } from './basic-auth.provider';
|
12
apps/webui/src/infra/auth/defs.ts
Normal file
12
apps/webui/src/infra/auth/defs.ts
Normal 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;
|
||||
}
|
@ -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;
|
2
apps/webui/src/infra/auth/oidc/index.ts
Normal file
2
apps/webui/src/infra/auth/oidc/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { buildOidcConfig } from './config';
|
||||
export { OidcAuthProvider } from './oidc-auth.provider';
|
41
apps/webui/src/infra/auth/oidc/oidc-auth.provider.ts
Normal file
41
apps/webui/src/infra/auth/oidc/oidc-auth.provider.ts
Normal 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()
|
||||
);
|
||||
}
|
||||
}
|
16
apps/webui/src/infra/graphql/context.ts
Normal file
16
apps/webui/src/infra/graphql/context.ts
Normal 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),
|
||||
};
|
||||
}
|
30
apps/webui/src/infra/graphql/graphql.service.ts
Normal file
30
apps/webui/src/infra/graphql/graphql.service.ts
Normal 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;
|
||||
}
|
2
apps/webui/src/infra/graphql/index.ts
Normal file
2
apps/webui/src/infra/graphql/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { GraphQLService } from './graphql.service';
|
||||
export { provideGraphql } from './context';
|
@ -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;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { Injectable, inject } from '@outposts/injection-js';
|
||||
import { OidcSecurityService } from 'oidc-client-rx';
|
||||
|
||||
@Injectable()
|
||||
export class HttpService {
|
||||
authService = inject(OidcSecurityService);
|
||||
}
|
@ -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';
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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 (
|
@ -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,
|
@ -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';
|
@ -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';
|
||||
|
@ -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({
|
@ -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,
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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 };
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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;
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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;
|
||||
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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,
|
||||
}
|
||||
};
|
@ -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 };
|
@ -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>
|
||||
);
|
||||
};
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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]
|
@ -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"
|
@ -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 };
|
@ -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} />;
|
@ -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 };
|
@ -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,
|
||||
}
|
||||
};
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
@ -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 };
|
19
apps/webui/src/views/hooks/use-mobile.ts
Normal file
19
apps/webui/src/views/hooks/use-mobile.ts
Normal 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
|
||||
}
|
@ -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')({
|
@ -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 (
|
@ -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')({
|
@ -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')({
|
@ -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'
|
||||
);
|
||||
}
|
||||
|
@ -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()}
|
@ -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
Loading…
Reference in New Issue
Block a user