portal: Apollo dashboard queries, strict TypeScript build, UI primitives
- Add GraphQL dashboard operations, ApolloProvider, CardDescription, label/checkbox/alert - Fix case-sensitive UI imports, Crossplane VM metadata uid, VMList spec parsing - Extend next-auth session user (id, role); fairness filters as unknown; ESLint relax to warnings - Remove unused session destructure across pages; next.config without skip TS/ESLint api: GraphQL/WebSocket hardening, logger import in websocket service Made-with: Cursor
This commit is contained in:
@@ -33,3 +33,7 @@ export function CardContent({ children, className = '' }: CardProps) {
|
||||
return <div className={`p-6 pt-0 ${className}`}>{children}</div>;
|
||||
}
|
||||
|
||||
export function CardDescription({ children, className = '' }: CardProps) {
|
||||
return <p className={`text-sm text-muted-foreground ${className}`}>{children}</p>;
|
||||
}
|
||||
|
||||
|
||||
34
portal/src/components/ui/alert.tsx
Normal file
34
portal/src/components/ui/alert.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface AlertProps {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
variant?: 'default' | 'destructive'
|
||||
}
|
||||
|
||||
export function Alert({ children, className, variant = 'default' }: AlertProps) {
|
||||
return (
|
||||
<div
|
||||
role="alert"
|
||||
className={cn(
|
||||
'relative w-full rounded-lg border p-4 flex gap-3',
|
||||
variant === 'destructive'
|
||||
? 'border-red-500/50 bg-red-950/30 text-red-200'
|
||||
: 'border-gray-700 bg-gray-800/50 text-gray-200',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
interface AlertDescriptionProps {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function AlertDescription({ children, className }: AlertDescriptionProps) {
|
||||
return <div className={cn('text-sm flex-1', className)}>{children}</div>
|
||||
}
|
||||
28
portal/src/components/ui/checkbox.tsx
Normal file
28
portal/src/components/ui/checkbox.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface CheckboxProps {
|
||||
id?: string
|
||||
checked?: boolean
|
||||
onCheckedChange?: () => void
|
||||
className?: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export function Checkbox({ id, checked, onCheckedChange, className, disabled }: CheckboxProps) {
|
||||
return (
|
||||
<input
|
||||
id={id}
|
||||
type="checkbox"
|
||||
checked={!!checked}
|
||||
disabled={disabled}
|
||||
onChange={() => onCheckedChange?.()}
|
||||
className={cn(
|
||||
'h-4 w-4 rounded border border-gray-600 bg-gray-900 text-blue-600 focus:ring-2 focus:ring-blue-500',
|
||||
className
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
13
portal/src/components/ui/label.tsx
Normal file
13
portal/src/components/ui/label.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {}
|
||||
|
||||
export function Label({ className, ...props }: LabelProps) {
|
||||
return (
|
||||
<label
|
||||
className={cn('text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react'
|
||||
import * as SelectPrimitive from '@radix-ui/react-select'
|
||||
import { Check, ChevronDown, ChevronUp } from 'lucide-react'
|
||||
import { Check, ChevronDown } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const Select = SelectPrimitive.Root
|
||||
|
||||
Reference in New Issue
Block a user