svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3',
- className
- )}
- {...props}
- />
- );
-}
-
-export {
- Avatar,
- AvatarImage,
- AvatarFallback,
- AvatarGroup,
- AvatarGroupCount,
- AvatarBadge,
-};
diff --git a/ui/components/ui/sidebar.tsx b/ui/components/ui/sidebar.tsx
deleted file mode 100644
index ee92fac9..00000000
--- a/ui/components/ui/sidebar.tsx
+++ /dev/null
@@ -1,702 +0,0 @@
-'use client';
-
-import * as React from 'react';
-import { cva, type VariantProps } from 'class-variance-authority';
-import { Slot } from 'radix-ui';
-
-import { useIsMobile } from '@/hooks/use-mobile';
-import { cn } from '@/lib/utils';
-import { Button } from '@/components/ui/button';
-import { Input } from '@/components/ui/input';
-import { Separator } from '@/components/ui/separator';
-import {
- Sheet,
- SheetContent,
- SheetDescription,
- SheetHeader,
- SheetTitle,
-} from '@/components/ui/sheet';
-import { Skeleton } from '@/components/ui/skeleton';
-import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
-} from '@/components/ui/tooltip';
-import { PanelLeftIcon } from 'lucide-react';
-
-const SIDEBAR_COOKIE_NAME = 'sidebar_state';
-const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
-const SIDEBAR_WIDTH = '16rem';
-const SIDEBAR_WIDTH_MOBILE = '18rem';
-const SIDEBAR_WIDTH_ICON = '3rem';
-const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
-
-type SidebarContextProps = {
- state: 'expanded' | 'collapsed';
- open: boolean;
- setOpen: (open: boolean) => void;
- openMobile: boolean;
- setOpenMobile: (open: boolean) => void;
- isMobile: boolean;
- toggleSidebar: () => void;
-};
-
-const SidebarContext = React.createContext
(null);
-
-function useSidebar() {
- const context = React.useContext(SidebarContext);
- if (!context) {
- throw new Error('useSidebar must be used within a SidebarProvider.');
- }
-
- return context;
-}
-
-function SidebarProvider({
- defaultOpen = true,
- open: openProp,
- onOpenChange: setOpenProp,
- className,
- style,
- children,
- ...props
-}: React.ComponentProps<'div'> & {
- defaultOpen?: boolean;
- open?: boolean;
- onOpenChange?: (open: boolean) => void;
-}) {
- const isMobile = useIsMobile();
- const [openMobile, setOpenMobile] = React.useState(false);
-
- // This is the internal state of the sidebar.
- // We use openProp and setOpenProp for control from outside the component.
- const [_open, _setOpen] = React.useState(defaultOpen);
- const open = openProp ?? _open;
- const setOpen = React.useCallback(
- (value: boolean | ((value: boolean) => boolean)) => {
- const openState = typeof value === 'function' ? value(open) : value;
- if (setOpenProp) {
- setOpenProp(openState);
- } else {
- _setOpen(openState);
- }
-
- // This sets the cookie to keep the sidebar state.
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
- },
- [setOpenProp, open]
- );
-
- // Helper to toggle the sidebar.
- const toggleSidebar = React.useCallback(() => {
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);
- }, [isMobile, setOpen, setOpenMobile]);
-
- // Adds a keyboard shortcut to toggle the sidebar.
- React.useEffect(() => {
- const handleKeyDown = (event: KeyboardEvent) => {
- if (
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
- (event.metaKey || event.ctrlKey)
- ) {
- event.preventDefault();
- toggleSidebar();
- }
- };
-
- window.addEventListener('keydown', handleKeyDown);
- return () => window.removeEventListener('keydown', handleKeyDown);
- }, [toggleSidebar]);
-
- // We add a state so that we can do data-state="expanded" or "collapsed".
- // This makes it easier to style the sidebar with Tailwind classes.
- const state = open ? 'expanded' : 'collapsed';
-
- const contextValue = React.useMemo(
- () => ({
- state,
- open,
- setOpen,
- isMobile,
- openMobile,
- setOpenMobile,
- toggleSidebar,
- }),
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
- );
-
- return (
-
-
- {children}
-
-
- );
-}
-
-function Sidebar({
- side = 'left',
- variant = 'sidebar',
- collapsible = 'offcanvas',
- className,
- children,
- dir,
- ...props
-}: React.ComponentProps<'div'> & {
- side?: 'left' | 'right';
- variant?: 'sidebar' | 'floating' | 'inset';
- collapsible?: 'offcanvas' | 'icon' | 'none';
-}) {
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
-
- if (collapsible === 'none') {
- return (
-
- {children}
-
- );
- }
-
- if (isMobile) {
- return (
-
-
-
- Sidebar
- Displays the mobile sidebar.
-
- {children}
-
-
- );
- }
-
- return (
-
- {/* This is what handles the sidebar gap on desktop */}
-
-
-
- );
-}
-
-function SidebarTrigger({
- className,
- onClick,
- ...props
-}: React.ComponentProps) {
- const { toggleSidebar } = useSidebar();
-
- return (
- {
- onClick?.(event);
- toggleSidebar();
- }}
- {...props}
- >
-
- Toggle Sidebar
-
- );
-}
-
-function SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {
- const { toggleSidebar } = useSidebar();
-
- return (
-
- );
-}
-
-function SidebarInset({ className, ...props }: React.ComponentProps<'main'>) {
- return (
-
- );
-}
-
-function SidebarInput({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function SidebarHeader({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarFooter({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarSeparator({
- className,
- ...props
-}: React.ComponentProps) {
- return (
-
- );
-}
-
-function SidebarContent({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarGroup({ className, ...props }: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarGroupLabel({
- className,
- asChild = false,
- ...props
-}: React.ComponentProps<'div'> & { asChild?: boolean }) {
- const Comp = asChild ? Slot.Root : 'div';
-
- return (
- svg]:size-4 [&>svg]:shrink-0',
- className
- )}
- {...props}
- />
- );
-}
-
-function SidebarGroupAction({
- className,
- asChild = false,
- ...props
-}: React.ComponentProps<'button'> & { asChild?: boolean }) {
- const Comp = asChild ? Slot.Root : 'button';
-
- return (
- svg]:size-4 [&>svg]:shrink-0',
- className
- )}
- {...props}
- />
- );
-}
-
-function SidebarGroupContent({
- className,
- ...props
-}: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {
- return (
-
- );
-}
-
-function SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {
- return (
-
- );
-}
-
-const sidebarMenuButtonVariants = cva(
- 'ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-[active=true]:font-medium peer/menu-button flex w-full items-center overflow-hidden outline-hidden group/menu-button disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0',
- {
- variants: {
- variant: {
- default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
- outline:
- 'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
- },
- size: {
- default: 'h-8 text-sm',
- sm: 'h-7 text-xs',
- lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
- },
- },
- defaultVariants: {
- variant: 'default',
- size: 'default',
- },
- }
-);
-
-function SidebarMenuButton({
- asChild = false,
- isActive = false,
- variant = 'default',
- size = 'default',
- tooltip,
- className,
- ...props
-}: React.ComponentProps<'button'> & {
- asChild?: boolean;
- isActive?: boolean;
- tooltip?: string | React.ComponentProps;
-} & VariantProps) {
- const Comp = asChild ? Slot.Root : 'button';
- const { isMobile, state } = useSidebar();
-
- const button = (
-
- );
-
- if (!tooltip) {
- return button;
- }
-
- if (typeof tooltip === 'string') {
- tooltip = {
- children: tooltip,
- };
- }
-
- return (
-
- {button}
-
-
- );
-}
-
-function SidebarMenuAction({
- className,
- asChild = false,
- showOnHover = false,
- ...props
-}: React.ComponentProps<'button'> & {
- asChild?: boolean;
- showOnHover?: boolean;
-}) {
- const Comp = asChild ? Slot.Root : 'button';
-
- return (
- svg]:size-4 [&>svg]:shrink-0',
- showOnHover &&
- 'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 aria-expanded:opacity-100 md:opacity-0',
- className
- )}
- {...props}
- />
- );
-}
-
-function SidebarMenuBadge({
- className,
- ...props
-}: React.ComponentProps<'div'>) {
- return (
-
- );
-}
-
-function SidebarMenuSkeleton({
- className,
- showIcon = false,
- ...props
-}: React.ComponentProps<'div'> & {
- showIcon?: boolean;
-}) {
- // Random width between 50 to 90%.
- const [width] = React.useState(() => {
- return `${Math.floor(Math.random() * 40) + 50}%`;
- });
-
- return (
-
- {showIcon && (
-
- )}
-
-
- );
-}
-
-function SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {
- return (
-
- );
-}
-
-function SidebarMenuSubItem({
- className,
- ...props
-}: React.ComponentProps<'li'>) {
- return (
-
- );
-}
-
-function SidebarMenuSubButton({
- asChild = false,
- size = 'md',
- isActive = false,
- className,
- ...props
-}: React.ComponentProps<'a'> & {
- asChild?: boolean;
- size?: 'sm' | 'md';
- isActive?: boolean;
-}) {
- const Comp = asChild ? Slot.Root : 'a';
-
- return (
- svg]:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden group-data-[collapsible=icon]:hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
- className
- )}
- {...props}
- />
- );
-}
-
-export {
- Sidebar,
- SidebarContent,
- SidebarFooter,
- SidebarGroup,
- SidebarGroupAction,
- SidebarGroupContent,
- SidebarGroupLabel,
- SidebarHeader,
- SidebarInput,
- SidebarInset,
- SidebarMenu,
- SidebarMenuAction,
- SidebarMenuBadge,
- SidebarMenuButton,
- SidebarMenuItem,
- SidebarMenuSkeleton,
- SidebarMenuSub,
- SidebarMenuSubButton,
- SidebarMenuSubItem,
- SidebarProvider,
- SidebarRail,
- SidebarSeparator,
- SidebarTrigger,
- useSidebar,
-};
diff --git a/ui/components/wallet-balance.tsx b/ui/components/wallet-balance.tsx
deleted file mode 100644
index 24f7c228..00000000
--- a/ui/components/wallet-balance.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-'use client';
-
-import { useQuery } from '@tanstack/react-query';
-import { Loader2, RefreshCw, AlertCircle } from 'lucide-react';
-import { WalletService } from '@/lib/api/services/wallet';
-import {
- Card,
- CardContent,
- CardDescription,
- CardHeader,
- CardTitle,
-} from '@/components/ui/card';
-import { Button } from '@/components/ui/button';
-import { cn } from '@/lib/utils';
-
-export function WalletBalance({
- refreshInterval = 10000,
-}: {
- refreshInterval?: number;
-}) {
- const { data, isLoading, isError, error, isFetching, refetch } = useQuery({
- queryKey: ['wallet-balance'],
- queryFn: async () => {
- return WalletService.getBalance();
- },
- refetchInterval: refreshInterval,
- });
-
- return (
-
-
-
- Wallet Balance
- refetch()}
- disabled={isLoading || isFetching}
- className='h-8 w-8'
- >
-
- Refresh balance
-
-
- Current available balance
-
-
- {isLoading ? (
-
-
-
- ) : isError ? (
-
-
-
Error loading balance: {(error as Error).message}
-
- ) : (
-
-
- {data?.balance.toLocaleString()}{' '}
- sats
-
-
- Updated {new Date().toLocaleTimeString()}
-
-
- )}
-
-
- );
-}
diff --git a/ui/lib/api/schemas/api-keys.ts b/ui/lib/api/schemas/api-keys.ts
deleted file mode 100644
index 3aa44cf8..00000000
--- a/ui/lib/api/schemas/api-keys.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { z } from 'zod';
-
-export const ApiKeySchema = z.object({
- id: z.string(),
- name: z.string(),
- key: z.string(),
- user_id: z.string(),
- organization_id: z.string(),
- last_used_at: z.string().optional(),
- expires_at: z.string().optional(),
- is_active: z.boolean().default(true),
- created_at: z.string(),
- updated_at: z.string().optional(),
-});
-
-export const CreateApiKeySchema = ApiKeySchema.omit({
- id: true,
- key: true,
- created_at: true,
- updated_at: true,
- last_used_at: true,
-});
-
-export const UpdateApiKeySchema = z.object({
- name: z.string().optional(),
- is_active: z.boolean().optional(),
- expires_at: z.string().optional(),
-});
-
-export type ApiKey = z.infer;
-export type CreateApiKey = z.infer;
-export type UpdateApiKey = z.infer;
diff --git a/ui/lib/api/schemas/credits.ts b/ui/lib/api/schemas/credits.ts
deleted file mode 100644
index f65d76d5..00000000
--- a/ui/lib/api/schemas/credits.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { z } from 'zod';
-
-export const CreditTransactionTypeEnum = z.enum([
- 'deposit',
- 'refund',
- 'usage',
- 'withdrawal',
-]);
-export type CreditTransactionType = z.infer;
-
-export const CreditTransactionSchema = z.object({
- id: z.string(),
- user_id: z.string(),
- api_key_id: z.string().optional(),
- amount: z.number().int(),
- transaction_type: CreditTransactionTypeEnum,
- provider_id: z.string().optional(),
- model_id: z.string().optional(),
- created_at: z.string().datetime(),
- status: z.enum(['pending', 'completed', 'failed', 'cancelled']),
- description: z.string().optional(),
-});
-export type CreditTransaction = z.infer;
-
-export const CreditBalanceSchema = z.object({
- user_id: z.string(),
- total_balance: z.number().int(),
- available_balance: z.number().int(),
- pending_balance: z.number().int(),
- last_updated: z.string().datetime(),
-});
-export type CreditBalance = z.infer;
-
-export const CreditUsageByApiKeySchema = z.object({
- api_key_id: z.string(),
- api_key_name: z.string(),
- total_spent: z.number().int(),
- usage_by_provider: z.record(z.string(), z.number().int()).optional(),
- usage_by_model: z.record(z.string(), z.number().int()).optional(),
-});
-export type CreditUsageByApiKey = z.infer;
-
-export const CreditUsageByPeriodSchema = z.object({
- period: z.string(),
- total_spent: z.number().int(),
- by_api_key: z.record(z.string(), z.number().int()).optional(),
- by_provider: z.record(z.string(), z.number().int()).optional(),
- by_model: z.record(z.string(), z.number().int()).optional(),
-});
-export type CreditUsageByPeriod = z.infer;
-
-export const CreditUsageStatisticsSchema = z.object({
- user_id: z.string(),
- total_spent: z.number().int(),
- by_api_key: z.array(CreditUsageByApiKeySchema),
- by_period: z.array(CreditUsageByPeriodSchema),
- from_date: z.string().datetime(),
- to_date: z.string().datetime(),
-});
-export type CreditUsageStatistics = z.infer;
-
-export const AddCreditsRequestSchema = z.object({
- amount: z.number().int().positive(),
- provider_id: z.string().optional(),
-});
-export type AddCreditsRequest = z.infer;
-
-export const RefundCreditsRequestSchema = z.object({
- amount: z.number().int().positive(),
- api_key_id: z.string().optional(),
-});
-export type RefundCreditsRequest = z.infer;
-
-export const GetUsageStatisticsRequestSchema = z.object({
- from_date: z.string().datetime().optional(),
- to_date: z.string().datetime().optional(),
- group_by: z.enum(['day', 'week', 'month']).optional(),
- api_key_id: z.string().optional(),
-});
-export type GetUsageStatisticsRequest = z.infer<
- typeof GetUsageStatisticsRequestSchema
->;
diff --git a/ui/lib/api/schemas/organizations.ts b/ui/lib/api/schemas/organizations.ts
deleted file mode 100644
index 939716aa..00000000
--- a/ui/lib/api/schemas/organizations.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { z } from 'zod';
-
-export const OrganizationSchema = z.object({
- id: z.string(),
- name: z.string(),
- slug: z.string().optional(),
- logo_url: z.string().optional(),
- domain: z.string().optional(),
- is_active: z.boolean().default(true),
- plan: z.string().optional().default('free'),
- created_at: z.string(),
- updated_at: z.string().optional(),
-});
-
-export const CreateOrganizationSchema = z.object({
- name: z.string(),
- slug: z.string().optional(),
- logo_url: z.string().optional(),
- domain: z.string().optional(),
- is_active: z.boolean().default(true),
- plan: z.string().optional().default('free'),
-});
-
-export const UpdateOrganizationSchema = CreateOrganizationSchema.partial();
-
-export type Organization = z.infer;
-export type CreateOrganization = z.infer;
-export type UpdateOrganization = z.infer;
diff --git a/ui/lib/api/schemas/providers.ts b/ui/lib/api/schemas/providers.ts
deleted file mode 100644
index 8f5eff60..00000000
--- a/ui/lib/api/schemas/providers.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { z } from 'zod';
-
-// Schema for provider
-export const ProviderSchema = z.object({
- id: z.string(),
- name: z.string(),
- url: z.string().url(),
- iconUrl: z.string().optional(),
- apiKeyRequired: z.boolean().default(true),
- created_at: z.string().optional(),
- updated_at: z.string().optional(),
- description: z.string().optional(),
- isEnabled: z.boolean().default(true),
-});
-
-// Schema for creating a provider
-export const CreateProviderSchema = ProviderSchema.omit({
- id: true,
- created_at: true,
- updated_at: true,
-});
-
-// Schema for updating a provider
-export const UpdateProviderSchema = CreateProviderSchema.partial();
-
-// Export types
-export type Provider = z.infer;
-export type CreateProvider = z.infer;
-export type UpdateProvider = z.infer;
diff --git a/ui/lib/api/schemas/users.ts b/ui/lib/api/schemas/users.ts
deleted file mode 100644
index 9fe3fc1f..00000000
--- a/ui/lib/api/schemas/users.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { z } from 'zod';
-
-export const UserRoleEnum = z.enum([
- 'superuser',
- 'admin',
- 'manager',
- 'group_leader',
- 'developer',
-]);
-export type UserRole = z.infer;
-
-export const UserSchema = z.object({
- id: z.string(),
- email: z.string().email(),
- name: z.string(),
- avatar_url: z.string().optional(),
- organization_id: z.string(),
- role: UserRoleEnum,
- is_active: z.boolean().default(true),
- created_at: z.string().optional(),
- updated_at: z.string().optional(),
-});
-
-export const CreateUserSchema = UserSchema.omit({
- id: true,
- created_at: true,
- updated_at: true,
-});
-
-export const UpdateUserSchema = CreateUserSchema.partial();
-
-export type User = z.infer;
-export type CreateUser = z.infer;
-export type UpdateUser = z.infer;
diff --git a/ui/lib/api/services/api-keys.ts b/ui/lib/api/services/api-keys.ts
deleted file mode 100644
index 44b037f6..00000000
--- a/ui/lib/api/services/api-keys.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-import { apiClient } from '../client';
-import { ApiKey, CreateApiKey, UpdateApiKey } from '../schemas/api-keys';
-
-// Commented out as it's not used
-// const mockApiKeys: ApiKey[] = [
-// {
-// id: '1',
-// name: 'Production API Key',
-// key: 'sk_prod_' + crypto.randomBytes(16).toString('hex'),
-// user_id: '1',
-// organization_id: '1',
-// is_active: true,
-// created_at: new Date('2023-01-01').toISOString(),
-// },
-// {
-// id: '2',
-// name: 'Development API Key',
-// key: 'sk_dev_' + crypto.randomBytes(16).toString('hex'),
-// user_id: '2',
-// organization_id: '1',
-// is_active: true,
-// created_at: new Date('2023-02-15').toISOString(),
-// },
-// {
-// id: '3',
-// name: 'Testing API Key',
-// key: 'sk_test_' + crypto.randomBytes(16).toString('hex'),
-// user_id: '3',
-// organization_id: '1',
-// is_active: false,
-// created_at: new Date('2023-03-10').toISOString(),
-// },
-// ];
-
-export class ApiKeyService {
- static async listApiKeys(organizationId?: string): Promise {
- try {
- const params: Record = {};
- if (organizationId) {
- params.organization_id = organizationId;
- }
-
- return await apiClient.get('/api/api-keys', params);
- } catch (error) {
- console.error('Error fetching API keys:', error);
- throw error;
- }
- }
-
- static async getApiKey(id: string): Promise {
- try {
- return await apiClient.get(`/api/api-keys/${id}`);
- } catch (error) {
- console.error(`Error fetching API key ${id}:`, error);
- throw error;
- }
- }
-
- static async createApiKey(data: CreateApiKey): Promise {
- try {
- return await apiClient.post(
- '/api/api-keys',
- data as Record
- );
- } catch (error) {
- console.error('Error creating API key:', error);
- throw error;
- }
- }
-
- static async updateApiKey(id: string, data: UpdateApiKey): Promise {
- try {
- return await apiClient.put(
- `/api/api-keys/${id}`,
- data as Record
- );
- } catch (error) {
- console.error(`Error updating API key ${id}:`, error);
- throw error;
- }
- }
-
- static async deleteApiKey(id: string): Promise {
- try {
- await apiClient.delete(`/api/api-keys/${id}`);
- } catch (error) {
- console.error(`Error deleting API key ${id}:`, error);
- throw error;
- }
- }
-}
diff --git a/ui/lib/api/services/api.ts b/ui/lib/api/services/api.ts
deleted file mode 100644
index 6804d6b1..00000000
--- a/ui/lib/api/services/api.ts
+++ /dev/null
@@ -1,93 +0,0 @@
-import axios from 'axios';
-import type { z } from 'zod';
-
-const PRODUCTION = 'production';
-
-export enum HTTPMethod {
- GET = 'GET',
- POST = 'POST',
-}
-
-export enum HTTPStatusCode {
- OK = 200,
-}
-
-// Define the Nostr Event interface
-interface NostrEvent {
- kind: number;
- created_at: number;
- content: string;
- tags: string[][];
-}
-
-interface NostrProvider {
- signEvent: (event: NostrEvent) => Promise;
-}
-
-type WindowWithNostr = Window & {
- nostr?: NostrProvider;
-};
-
-function getNostrProvider(): NostrProvider {
- if (typeof window === 'undefined') {
- throw new Error('Nostr provider is unavailable on the server');
- }
-
- const windowWithNostr = window as WindowWithNostr;
- if (
- !windowWithNostr.nostr ||
- typeof windowWithNostr.nostr.signEvent !== 'function'
- ) {
- throw new Error('Nostr provider is unavailable');
- }
-
- return windowWithNostr.nostr;
-}
-
-export default function api({
- method,
- path,
- requestSchema,
- responseSchema,
-}: {
- method: HTTPMethod;
- path: string;
- requestSchema: z.ZodType;
- responseSchema: z.ZodType;
-}): (data: Request) => Promise {
- return function (requestData: Request) {
- requestSchema.parse(requestData);
-
- async function apiCall() {
- const nostr = getNostrProvider();
- const auth_event = await nostr.signEvent({
- kind: 27235,
- created_at: Math.floor(new Date().getTime() / 1000),
- content: 'application/json',
- tags: [
- ['u', `${process.env.API_URL}${path}`],
- ['method', method],
- ],
- });
-
- const response = await axios({
- baseURL: process.env.NEXT_PUBLIC_API_URL,
- headers: {
- authorization: `Nostr ${btoa(JSON.stringify(auth_event))}`,
- 'Content-Type': 'application/json',
- },
- method,
- url: path,
- [method === HTTPMethod.GET ? 'params' : 'data']: requestData,
- });
-
- if (process.env.NODE_ENV === PRODUCTION) {
- return response.data as Response;
- }
-
- return responseSchema.parse(response.data);
- }
-
- return apiCall();
- };
-}
diff --git a/ui/lib/api/services/users.ts b/ui/lib/api/services/users.ts
deleted file mode 100644
index 9bb78677..00000000
--- a/ui/lib/api/services/users.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { apiClient } from '../client';
-import { User, CreateUser, UpdateUser } from '../schemas/users';
-
-export class UserService {
- static async listUsers(organizationId?: string): Promise {
- try {
- const params: Record = {};
- if (organizationId) {
- params.organization_id = organizationId;
- }
-
- return await apiClient.get('/api/users', params);
- } catch (error) {
- console.error('Error fetching users:', error);
- throw error;
- }
- }
-
- static async getUser(userId: string): Promise {
- try {
- return await apiClient.get(`/api/users/${userId}`);
- } catch (error) {
- console.error(`Error fetching user ${userId}:`, error);
- throw error;
- }
- }
-
- static async createUser(userData: CreateUser): Promise {
- try {
- return await apiClient.post(
- '/api/users',
- userData as Record
- );
- } catch (error) {
- console.error('Error creating user:', error);
- throw error;
- }
- }
-
- static async updateUser(userId: string, userData: UpdateUser): Promise {
- try {
- return await apiClient.put(
- `/api/users/${userId}`,
- userData as Record
- );
- } catch (error) {
- console.error(`Error updating user ${userId}:`, error);
- throw error;
- }
- }
-
- static async deleteUser(userId: string): Promise {
- try {
- await apiClient.delete(`/api/users/${userId}`);
- } catch (error) {
- console.error(`Error deleting user ${userId}:`, error);
- throw error;
- }
- }
-}
diff --git a/ui/lib/auth/auth-context.tsx b/ui/lib/auth/auth-context.tsx
deleted file mode 100644
index d1a8e356..00000000
--- a/ui/lib/auth/auth-context.tsx
+++ /dev/null
@@ -1,159 +0,0 @@
-import React, { createContext, useContext, useState } from 'react';
-import { User } from '@/lib/api/schemas/users';
-import { UserService } from '@/lib/api/services/users';
-
-// Nostr extension interface
-interface NostrWindow extends Window {
- nostr: {
- getPublicKey: () => Promise;
- };
-}
-
-// Define the shape of our auth context state
-type AuthContextType = {
- user: User | null;
- isLoading: boolean;
- error: Error | null;
- isAuthenticated: boolean;
- nostrPublicKey: string | null;
- signin: () => Promise;
- signout: () => void;
- connectNostr: () => Promise;
-};
-
-// Create the auth context with default values
-const AuthContext = createContext({
- user: null,
- isLoading: false,
- error: null,
- isAuthenticated: false,
- nostrPublicKey: null,
- signin: async () => {},
- signout: () => {},
- connectNostr: async () => null,
-});
-
-// Auth context provider component
-export function AuthProvider({ children }: { children: React.ReactNode }) {
- const [user, setUser] = useState(null);
- const [isLoading, setIsLoading] = useState(true);
- const [error, setError] = useState(null);
- const [nostrPublicKey, setNostrPublicKey] = useState(null);
-
- // useEffect(() => {
- // const setupAuthState = async () => {
- // try {
- // const savedUser = localStorage.getItem('auth_user');
- // if (savedUser) {
- // setUser(JSON.parse(savedUser));
- // } else {
- // try {
- // const demoUser = await UserService.getUser('1');
- // if (demoUser) {
- // setUser(demoUser);
- // localStorage.setItem('auth_user', JSON.stringify(demoUser));
- // }
- // } catch (error) {
- // console.error('Error getting demo user:', error);
- // }
- // }
-
- // const savedPublicKey = localStorage.getItem('nostr_public_key');
- // if (savedPublicKey) {
- // setNostrPublicKey(savedPublicKey);
- // }
- // } catch (error) {
- // console.error('Error restoring auth state:', error);
- // } finally {
- // setIsLoading(false);
- // }
- // };
-
- // setupAuthState();
- // }, []);
-
- // Connect to Nostr and get public key
- const connectNostr = async (): Promise => {
- try {
- // Check if window.nostr exists
- if (typeof window !== 'undefined' && 'nostr' in window) {
- // Request public key from extension
- const publicKey = await (window as NostrWindow).nostr.getPublicKey();
-
- // Store the public key
- setNostrPublicKey(publicKey);
- localStorage.setItem('nostr_public_key', publicKey);
-
- return publicKey;
- } else {
- console.error('Nostr extension not found');
- return null;
- }
- } catch (error) {
- console.error('Error connecting to Nostr:', error);
- return null;
- }
- };
-
- // Signin function that returns the admin user for now
- const signin = async () => {
- setIsLoading(true);
- setError(null);
-
- try {
- // For now, just return the admin user (id: 1) regardless of credentials
- const adminUser = await UserService.getUser('1');
-
- if (!adminUser) {
- throw new Error('Admin user not found');
- }
-
- // Store user in state and localStorage
- setUser(adminUser);
- localStorage.setItem('auth_user', JSON.stringify(adminUser));
-
- // Try to connect to Nostr if not already connected
- if (!nostrPublicKey) {
- await connectNostr();
- }
- } catch (error) {
- setError(error instanceof Error ? error : new Error('Sign in failed'));
- throw error;
- } finally {
- setIsLoading(false);
- }
- };
-
- // Sign out function
- const signout = () => {
- setUser(null);
- localStorage.removeItem('auth_user');
- // We don't clear the Nostr public key on logout to maintain the connection
- };
-
- return (
-
- {children}
-
- );
-}
-
-// Custom hook to use the auth context
-export function useAuth() {
- const context = useContext(AuthContext);
- if (context === undefined) {
- throw new Error('useAuth must be used within an AuthProvider');
- }
- return context;
-}
diff --git a/ui/lib/hooks/use-models.ts b/ui/lib/hooks/use-models.ts
deleted file mode 100644
index c35a0798..00000000
--- a/ui/lib/hooks/use-models.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { useQuery, useQueryClient } from '@tanstack/react-query';
-import { ModelService } from '../api/services/models';
-
-// Query keys for models
-const modelKeys = {
- all: ['models'] as const,
- list: () => [...modelKeys.all, 'list'] as const,
- detail: (id: string) => [...modelKeys.all, 'detail', id] as const,
- test: (id: string) => [...modelKeys.all, 'test', id] as const,
-};
-
-/**
- * Hook to fetch the list of available models
- */
-export function useModels(options?: {
- team_id?: string;
- return_wildcard_routes?: boolean;
- enabled?: boolean;
-}) {
- return useQuery({
- queryKey: modelKeys.list(),
- queryFn: () => ModelService.listModels(options),
- enabled: options?.enabled ?? true,
- });
-}
-
-/**
- * Hook to fetch detailed information about a specific model
- */
-export function useModelInfo(modelId: string, options?: { enabled?: boolean }) {
- return useQuery({
- queryKey: modelKeys.detail(modelId),
- queryFn: () => ModelService.getModelInfo(modelId),
- enabled: !!modelId && (options?.enabled ?? true),
- });
-}
-
-export function usePrefetchModelInfo() {
- // This is only used for this function, not needed in the larger scope
- const queryClient = useQueryClient();
-
- return async (modelId: string) => {
- await queryClient.prefetchQuery({
- queryKey: modelKeys.detail(modelId),
- queryFn: () => ModelService.getModelInfo(modelId),
- });
- };
-}
diff --git a/ui/lib/hooks/use-users.ts b/ui/lib/hooks/use-users.ts
deleted file mode 100644
index 00a5c75e..00000000
--- a/ui/lib/hooks/use-users.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
-import { UserService } from '../api/services/users';
-import { CreateUser, UpdateUser } from '../api/schemas/users';
-import { toast } from 'sonner';
-
-// Query keys for users
-const userKeys = {
- all: ['users'] as const,
- lists: () => [...userKeys.all, 'list'] as const,
- list: (filters: { organizationId?: string }) =>
- [...userKeys.lists(), filters] as const,
- details: () => [...userKeys.all, 'detail'] as const,
- detail: (id: string) => [...userKeys.details(), id] as const,
-};
-
-/**
- * Hook to fetch users list with optional organization filter
- */
-export function useUsers(filters?: {
- organizationId?: string;
- enabled?: boolean;
-}) {
- const { organizationId, enabled } = filters || {};
-
- return useQuery({
- queryKey: userKeys.list({ organizationId }),
- queryFn: () => UserService.listUsers(organizationId),
- enabled: enabled ?? true,
- });
-}
-
-/**
- * Hook to fetch a specific user by ID
- */
-export function useUser(userId: string, options?: { enabled?: boolean }) {
- return useQuery({
- queryKey: userKeys.detail(userId),
- queryFn: () => UserService.getUser(userId),
- enabled: !!userId && (options?.enabled ?? true),
- });
-}
-
-/**
- * Hook to create a new user
- */
-export function useCreateUser() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: (userData: CreateUser) => {
- return UserService.createUser(userData);
- },
- onSuccess: (user) => {
- toast.success('User created successfully');
- queryClient.invalidateQueries({ queryKey: userKeys.lists() });
- queryClient.invalidateQueries({
- queryKey: userKeys.list({ organizationId: user.organization_id }),
- });
- },
- onError: (error) => {
- toast.error(`Failed to create user: ${error.message}`);
- },
- });
-}
-
-/**
- * Hook to update an existing user
- */
-export function useUpdateUser() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: ({
- userId,
- userData,
- }: {
- userId: string;
- userData: UpdateUser;
- }) => {
- return UserService.updateUser(userId, userData);
- },
- onSuccess: (updatedUser) => {
- if (updatedUser) {
- toast.success('User updated successfully');
- queryClient.invalidateQueries({
- queryKey: userKeys.detail(updatedUser.id),
- });
- queryClient.invalidateQueries({ queryKey: userKeys.lists() });
- queryClient.invalidateQueries({
- queryKey: userKeys.list({
- organizationId: updatedUser.organization_id,
- }),
- });
- }
- },
- onError: (error) => {
- toast.error(`Failed to update user: ${error.message}`);
- },
- });
-}
-
-/**
- * Hook to delete a user
- */
-export function useDeleteUser() {
- const queryClient = useQueryClient();
-
- return useMutation({
- mutationFn: (userId: string) => {
- return UserService.deleteUser(userId);
- },
- onSuccess: () => {
- toast.success('User deleted successfully');
- queryClient.invalidateQueries({ queryKey: userKeys.lists() });
- },
- onError: (error) => {
- toast.error(`Failed to delete user: ${error.message}`);
- },
- });
-}
diff --git a/ui/package.json b/ui/package.json
index 256286d7..87f289fc 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -14,13 +14,8 @@
},
"dependencies": {
"@base-ui/react": "^1.2.0",
- "@dnd-kit/core": "^6.3.1",
- "@dnd-kit/modifiers": "^9.0.0",
- "@dnd-kit/sortable": "^10.0.0",
- "@dnd-kit/utilities": "^3.2.2",
"@hookform/resolvers": "^5.2.2",
"@radix-ui/react-alert-dialog": "^1.1.15",
- "@radix-ui/react-avatar": "^1.1.11",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-context-menu": "^2.2.16",
@@ -44,7 +39,6 @@
"@radix-ui/react-toggle-group": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-query": "^5.90.21",
- "@tanstack/react-table": "^8.21.3",
"axios": "^1.16.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
@@ -57,7 +51,6 @@
"next": "16.2.6",
"next-themes": "^0.4.6",
"qrcode": "^1.5.4",
- "qrcode.react": "^4.2.0",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-day-picker": "^9.13.2",
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index b78acbbe..d57e95ee 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -25,27 +25,12 @@ importers:
'@base-ui/react':
specifier: ^1.2.0
version: 1.2.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@dnd-kit/core':
- specifier: ^6.3.1
- version: 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@dnd-kit/modifiers':
- specifier: ^9.0.0
- version: 9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)
- '@dnd-kit/sortable':
- specifier: ^10.0.0
- version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)
- '@dnd-kit/utilities':
- specifier: ^3.2.2
- version: 3.2.2(react@19.2.4)
'@hookform/resolvers':
specifier: ^5.2.2
version: 5.2.2(react-hook-form@7.71.2(react@19.2.4))
'@radix-ui/react-alert-dialog':
specifier: ^1.1.15
version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@radix-ui/react-avatar':
- specifier: ^1.1.11
- version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-checkbox':
specifier: ^1.3.3
version: 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -115,9 +100,6 @@ importers:
'@tanstack/react-query':
specifier: ^5.90.21
version: 5.90.21(react@19.2.4)
- '@tanstack/react-table':
- specifier: ^8.21.3
- version: 8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
axios:
specifier: ^1.16.0
version: 1.18.1
@@ -154,9 +136,6 @@ importers:
qrcode:
specifier: ^1.5.4
version: 1.5.4
- qrcode.react:
- specifier: ^4.2.0
- version: 4.2.0(react@19.2.4)
radix-ui:
specifier: ^1.4.3
version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@@ -372,34 +351,6 @@ packages:
'@date-fns/tz@1.4.1':
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
- '@dnd-kit/accessibility@3.1.1':
- resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
- peerDependencies:
- react: '>=16.8.0'
-
- '@dnd-kit/core@6.3.1':
- resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==}
- peerDependencies:
- react: '>=16.8.0'
- react-dom: '>=16.8.0'
-
- '@dnd-kit/modifiers@9.0.0':
- resolution: {integrity: sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw==}
- peerDependencies:
- '@dnd-kit/core': ^6.3.0
- react: '>=16.8.0'
-
- '@dnd-kit/sortable@10.0.0':
- resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==}
- peerDependencies:
- '@dnd-kit/core': ^6.3.0
- react: '>=16.8.0'
-
- '@dnd-kit/utilities@3.2.2':
- resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==}
- peerDependencies:
- react: '>=16.8.0'
-
'@emnapi/core@1.8.1':
resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==}
@@ -797,19 +748,6 @@ packages:
'@types/react-dom':
optional: true
- '@radix-ui/react-avatar@1.1.11':
- resolution: {integrity: sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-checkbox@1.3.3':
resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==}
peerDependencies:
@@ -1618,17 +1556,6 @@ packages:
peerDependencies:
react: ^18 || ^19
- '@tanstack/react-table@8.21.3':
- resolution: {integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==}
- engines: {node: '>=12'}
- peerDependencies:
- react: '>=16.8'
- react-dom: '>=16.8'
-
- '@tanstack/table-core@8.21.3':
- resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==}
- engines: {node: '>=12'}
-
'@tybys/wasm-util@0.10.1':
resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==}
@@ -3104,11 +3031,6 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
- qrcode.react@4.2.0:
- resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
-
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
@@ -3772,38 +3694,6 @@ snapshots:
'@date-fns/tz@1.4.1': {}
- '@dnd-kit/accessibility@3.1.1(react@19.2.4)':
- dependencies:
- react: 19.2.4
- tslib: 2.8.1
-
- '@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
- dependencies:
- '@dnd-kit/accessibility': 3.1.1(react@19.2.4)
- '@dnd-kit/utilities': 3.2.2(react@19.2.4)
- react: 19.2.4
- react-dom: 19.2.4(react@19.2.4)
- tslib: 2.8.1
-
- '@dnd-kit/modifiers@9.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)':
- dependencies:
- '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@dnd-kit/utilities': 3.2.2(react@19.2.4)
- react: 19.2.4
- tslib: 2.8.1
-
- '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react@19.2.4)':
- dependencies:
- '@dnd-kit/core': 6.3.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@dnd-kit/utilities': 3.2.2(react@19.2.4)
- react: 19.2.4
- tslib: 2.8.1
-
- '@dnd-kit/utilities@3.2.2(react@19.2.4)':
- dependencies:
- react: 19.2.4
- tslib: 2.8.1
-
'@emnapi/core@1.8.1':
dependencies:
'@emnapi/wasi-threads': 1.1.0
@@ -4143,19 +4033,6 @@ snapshots:
'@types/react': 19.2.14
'@types/react-dom': 19.2.3(@types/react@19.2.14)
- '@radix-ui/react-avatar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
- dependencies:
- '@radix-ui/react-context': 1.1.3(@types/react@19.2.14)(react@19.2.4)
- '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
- '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4)
- '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.14)(react@19.2.4)
- '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.4)
- react: 19.2.4
- react-dom: 19.2.4(react@19.2.4)
- optionalDependencies:
- '@types/react': 19.2.14
- '@types/react-dom': 19.2.3(@types/react@19.2.14)
-
'@radix-ui/react-checkbox@1.3.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -4986,14 +4863,6 @@ snapshots:
'@tanstack/query-core': 5.90.20
react: 19.2.4
- '@tanstack/react-table@8.21.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
- dependencies:
- '@tanstack/table-core': 8.21.3
- react: 19.2.4
- react-dom: 19.2.4(react@19.2.4)
-
- '@tanstack/table-core@8.21.3': {}
-
'@tybys/wasm-util@0.10.1':
dependencies:
tslib: 2.8.1
@@ -6574,10 +6443,6 @@ snapshots:
punycode@2.3.1: {}
- qrcode.react@4.2.0(react@19.2.4):
- dependencies:
- react: 19.2.4
-
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
diff --git a/ui/public/file.svg b/ui/public/file.svg
deleted file mode 100644
index 004145cd..00000000
--- a/ui/public/file.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ui/public/globe.svg b/ui/public/globe.svg
deleted file mode 100644
index 567f17b0..00000000
--- a/ui/public/globe.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ui/public/next.svg b/ui/public/next.svg
deleted file mode 100644
index 5174b28c..00000000
--- a/ui/public/next.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ui/public/vercel.svg b/ui/public/vercel.svg
deleted file mode 100644
index 77053960..00000000
--- a/ui/public/vercel.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/ui/public/window.svg b/ui/public/window.svg
deleted file mode 100644
index b2b2a44f..00000000
--- a/ui/public/window.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file