diff --git a/src/components/Kubernetes/ClusterDetails.tsx b/src/components/Kubernetes/ClusterDetails.tsx
new file mode 100644
index 00000000..09a95aff
--- /dev/null
+++ b/src/components/Kubernetes/ClusterDetails.tsx
@@ -0,0 +1,181 @@
+import React from "react";
+import { Badge } from "@/components/ui";
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
+
+interface ClusterDetailsProps {
+ clusterId: string;
+}
+
+export function ClusterDetails({ clusterId }: ClusterDetailsProps) {
+ return (
+
+
+
Cluster Details
+
Cluster ID: {clusterId}
+
+
+
+
+
+
Basic Information
+
+
+
+
+
Name
+
production-cluster
+
+
+
+
Kubernetes Version
+
v1.28.4
+
+
+
+
API Server
+
https://abc123.gr7.us-east-1.eks.amazonaws.com
+
+
+ Status
+ Running
+
+
+
+
+
+
+
+
Network Configuration
+
+
+
+
+
VPC ID
+
vpc-0abc123def456
+
+
+
Subnets
+
+ subnet-1
+ subnet-2
+ subnet-3
+
+
+
+
Security Groups
+
+ sg-001
+ sg-002
+
+
+
+
CIDR Block
+
10.0.0.0/16
+
+
+
+
+
+
+
+
Node Configuration
+
+
+
+
+
Instance Type
+
m5.xlarge
+
+
+
+
+ Autoscaling
+ Enabled
+
+
+
+
+
+
+
+
Security Configuration
+
+
+
+
+ Network Policy
+ Enabled
+
+
+ Pod Security Policy
+ Enabled
+
+
+ RBAC
+ Enabled
+
+
+ Secret Encryption
+ Enabled
+
+
+
+
+
+
+
+
+
Node Pools
+
+
+
+
+
+ Name
+ Instance Type
+ Nodes
+ Status
+ Auto-scaling
+
+
+
+
+ general-purpose
+ m5.xlarge
+ 3
+ Running
+ Enabled
+
+
+ compute-optimized
+ c5.2xlarge
+ 2
+ Running
+ Enabled
+
+
+ memory-optimized
+ r5.4xlarge
+ 2
+ Running
+ Enabled
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/ClusterOverview.tsx b/src/components/Kubernetes/ClusterOverview.tsx
new file mode 100644
index 00000000..22463f4d
--- /dev/null
+++ b/src/components/Kubernetes/ClusterOverview.tsx
@@ -0,0 +1,148 @@
+import React from "react";
+import { Server, Database, Globe } from "lucide-react";
+import { MetricsChart } from "./MetricsChart";
+
+interface ClusterOverviewProps {
+ clusterId: string;
+}
+
+export function ClusterOverview({ clusterId }: ClusterOverviewProps) {
+ return (
+
+
+
Cluster Overview
+
Cluster ID: {clusterId}
+
+
+
+
+
+
Nodes
+
+
+
15
+
+2 since last week
+
+
+
+
+
Pods
+
+
+
247
+
+15 since last week
+
+
+
+
+
Workloads
+
+
+
32
+
+4 since last week
+
+
+
+
+
+
+
+
+
+
+
Cluster Resources
+
+
+
+
+
Allocatable Resources
+
+
+ CPU (cores)
+ 32
+
+
+ Memory (GB)
+ 128
+
+
+ Pods
+ 110
+
+
+
+
+
Used Resources
+
+
+ CPU (cores)
+ 18.5 (58%)
+
+
+ Memory (GB)
+ 52.3 (41%)
+
+
+ Pods
+ 247 (22%)
+
+
+
+
+
+
+
+
+
+
Recent Events
+
+
+
+
+ 5 minutes ago
+ NodeReady
+ Normal
+ Node node-1 is ready
+
+
+ 1 hour ago
+ Pulled
+ Normal
+ Container image pulled successfully
+
+
+ 2 hours ago
+ ScalingReplicaSet
+ Normal
+ Scaled up deployment web-app
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/CommandPalette.tsx b/src/components/Kubernetes/CommandPalette.tsx
new file mode 100644
index 00000000..8d716394
--- /dev/null
+++ b/src/components/Kubernetes/CommandPalette.tsx
@@ -0,0 +1,103 @@
+import React from "react";
+import { Command, X } from "lucide-react";
+import { Input } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { Badge } from "@/components/ui";
+
+interface CommandPaletteProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onCommand: (command: string) => void;
+}
+
+export function CommandPalette({ isOpen, onClose, onCommand }: CommandPaletteProps) {
+ const [query, setQuery] = React.useState("");
+
+ if (!isOpen) return null;
+
+ const commands = [
+ { name: "Open Terminal", command: "terminal:open" },
+ { name: "Create Pod", command: "resource:create:pod" },
+ { name: "Create Deployment", command: "resource:create:deployment" },
+ { name: "Create Service", command: "resource:create:service" },
+ { name: "View Logs", command: "logs:view" },
+ { name: "Scale Resource", command: "resource:scale" },
+ { name: "Delete Resource", command: "resource:delete" },
+ { name: "Export YAML", command: "yaml:export" },
+ { name: "Refresh Cluster", command: "cluster:refresh" },
+ { name: "Switch Context", command: "context:switch" },
+ ];
+
+ const filteredCommands = commands.filter((cmd) =>
+ cmd.name.toLowerCase().includes(query.toLowerCase())
+ );
+
+ return (
+
+
+
+
+
+
Command Palette
+
+
+
+
+
+ setQuery(e.target.value)}
+ placeholder="Type a command or search..."
+ autoFocus
+ className="pl-10"
+ />
+
+
+
+
+ {filteredCommands.length === 0 ? (
+
+ No commands found
+
+ ) : (
+ filteredCommands.map((cmd, index) => (
+
{
+ onCommand(cmd.command);
+ onClose();
+ }}
+ >
+ {cmd.name}
+
+ {cmd.command}
+
+
+ ))
+ )}
+
+
+
+
+ ↑
+ ↓
+ to navigate
+
+
+ ↵
+ to select
+
+
+ esc
+ to close
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/ConfigMapDetail.tsx b/src/components/Kubernetes/ConfigMapDetail.tsx
new file mode 100644
index 00000000..fab03bf0
--- /dev/null
+++ b/src/components/Kubernetes/ConfigMapDetail.tsx
@@ -0,0 +1,111 @@
+import React from "react";
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui";
+import { Badge } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { X } from "lucide-react";
+import { YamlEditor } from "./YamlEditor";
+
+interface ConfigMapDetailProps {
+ configMapName: string;
+ namespace: string;
+ _clusterId: string;
+ onClose: () => void;
+}
+
+export function ConfigMapDetail({ configMapName, namespace, _clusterId, onClose }: ConfigMapDetailProps) {
+ const [activeTab, setActiveTab] = React.useState("data");
+
+ return (
+
+
+
+
ConfigMap: {configMapName}
+ {namespace}
+
+
+
+
+
+
+ Data
+ YAML
+ Metadata
+
+
+
+
+
+
+ ConfigMap Data
+
+
+
+
+
config.json:
+
{`{
+ "debug": true,
+ "logLevel": "info"
+}`}
+
+
+
app.properties:
+
{`app.name=MyApp
+app.version=1.0.0
+app.port=8080`}
+
+
+
+
+
+
+
+ {}} />
+
+
+
+
+
+
+ Metadata
+
+
+
+ Name
+ {configMapName}
+
+
+ Namespace
+ {namespace}
+
+
+ UID
+ abc123-def456
+
+
+ Created
+ 2 hours ago
+
+
+
+
+
+
+ Labels
+
+
+
+ app=web
+ tier=frontend
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/CreateResourceModal.tsx b/src/components/Kubernetes/CreateResourceModal.tsx
new file mode 100644
index 00000000..7898bad2
--- /dev/null
+++ b/src/components/Kubernetes/CreateResourceModal.tsx
@@ -0,0 +1,131 @@
+import React from "react";
+import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { Input } from "@/components/ui";
+import { Label } from "@/components/ui";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { YamlEditor } from "./YamlEditor";
+
+interface CreateResourceModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onSubmit: (resource: { type: string; name: string; namespace: string }) => void;
+}
+
+export function CreateResourceModal({ isOpen, onClose, onSubmit }: CreateResourceModalProps) {
+ const [activeTab, setActiveTab] = React.useState("form");
+ const [resourceType, setResourceType] = React.useState("pod");
+ const [name, setName] = React.useState("");
+ const [namespace, setNamespace] = React.useState("default");
+
+ const handleSubmit = () => {
+ onSubmit({
+ type: resourceType,
+ name,
+ namespace,
+ });
+ onClose();
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/Kubernetes/DeploymentDetail.tsx b/src/components/Kubernetes/DeploymentDetail.tsx
new file mode 100644
index 00000000..ee144058
--- /dev/null
+++ b/src/components/Kubernetes/DeploymentDetail.tsx
@@ -0,0 +1,163 @@
+import React from "react";
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui";
+import { Badge } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { X } from "lucide-react";
+import { YamlEditor } from "./YamlEditor";
+
+interface DeploymentDetailProps {
+ deploymentName: string;
+ namespace: string;
+ _clusterId: string;
+ onClose: () => void;
+}
+
+export function DeploymentDetail({ deploymentName, namespace, _clusterId, onClose }: DeploymentDetailProps) {
+ const [activeTab, setActiveTab] = React.useState("overview");
+
+ return (
+
+
+
+
Deployment: {deploymentName}
+ {namespace}
+
+
+
+
+
+
+ Overview
+ Replicas
+ YAML
+ Events
+
+
+
+
+
+
+
+ Deployment Information
+
+
+
+ Name
+ {deploymentName}
+
+
+ Namespace
+ {namespace}
+
+
+ Replicas
+ 3/3 Ready
+
+
+ Strategy
+ RollingUpdate
+
+
+ Image
+ nginx:latest
+
+
+ Created
+ 2 hours ago
+
+
+
+
+
+
+ Selector
+
+
+
+ app=web
+ tier=frontend
+
+
+
+
+
+
+ Labels
+
+
+
+ app=web
+ tier=frontend
+ version=v1
+
+
+
+
+
+
+
+
+
+
+ Name
+ Status
+ Ready
+ Age
+
+
+
+
+ {deploymentName}-abc123
+ Running
+ 1/1
+ 2h
+
+
+ {deploymentName}-def456
+ Running
+ 1/1
+ 2h
+
+
+ {deploymentName}-ghi789
+ Running
+ 1/1
+ 2h
+
+
+
+
+
+
+ {}} />
+
+
+
+
+
+
+ Time
+ Reason
+ Type
+ Message
+
+
+
+
+ 2 hours ago
+ ScalingReplicaSet
+ Normal
+ Scaled up replica set {deploymentName}-abc123 to 3
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/EditResourceModal.tsx b/src/components/Kubernetes/EditResourceModal.tsx
new file mode 100644
index 00000000..02e19217
--- /dev/null
+++ b/src/components/Kubernetes/EditResourceModal.tsx
@@ -0,0 +1,110 @@
+import React from "react";
+import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { Input } from "@/components/ui";
+import { Label } from "@/components/ui";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { YamlEditor } from "./YamlEditor";
+
+interface EditResourceModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onSubmit: (resource: { name: string; namespace: string }) => void;
+ initialData?: { name?: string; namespace?: string };
+}
+
+export function EditResourceModal({ isOpen, onClose, onSubmit, initialData }: EditResourceModalProps) {
+ const [activeTab, setActiveTab] = React.useState("form");
+ const [name, setName] = React.useState(initialData?.name || "");
+ const [namespace, setNamespace] = React.useState(initialData?.namespace || "default");
+
+ const handleSubmit = () => {
+ onSubmit({
+ name,
+ namespace,
+ });
+ onClose();
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/Kubernetes/Hotbar.tsx b/src/components/Kubernetes/Hotbar.tsx
new file mode 100644
index 00000000..cf3a67b5
--- /dev/null
+++ b/src/components/Kubernetes/Hotbar.tsx
@@ -0,0 +1,57 @@
+import React from "react";
+import { Button } from "@/components/ui";
+import { Settings, Bell, User, Search, Plus, RefreshCw } from "lucide-react";
+import { Badge } from "@/components/ui";
+import { useKubernetesStore } from "@/stores/kubernetesStore";
+import { useStore } from "zustand";
+
+interface HotbarProps {
+ onRefresh: () => void;
+ onAddResource: () => void;
+ onSettings: () => void;
+}
+
+export function Hotbar({ onRefresh, onAddResource, onSettings }: HotbarProps) {
+ const clusters = useStore(useKubernetesStore, (state) => state.clusters);
+ const selectedClusterId = useStore(useKubernetesStore, (state) => state.selectedClusterId);
+ const selectedCluster = clusters.find((c: { id: string }) => c.id === selectedClusterId);
+
+ return (
+
+
+
+
+
+
+
+ {selectedCluster?.name || "No cluster selected"}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/LoadingSpinner.tsx b/src/components/Kubernetes/LoadingSpinner.tsx
new file mode 100644
index 00000000..7c575c21
--- /dev/null
+++ b/src/components/Kubernetes/LoadingSpinner.tsx
@@ -0,0 +1,22 @@
+import React from "react";
+import { Loader2 } from "lucide-react";
+
+interface LoadingSpinnerProps {
+ size?: "sm" | "md" | "lg";
+ text?: string;
+}
+
+export function LoadingSpinner({ size = "md", text }: LoadingSpinnerProps) {
+ const sizes = {
+ sm: "w-4 h-4",
+ md: "w-8 h-8",
+ lg: "w-12 h-12",
+ };
+
+ return (
+
+ );
+}
diff --git a/src/components/Kubernetes/RbacEditor.tsx b/src/components/Kubernetes/RbacEditor.tsx
new file mode 100644
index 00000000..5a9e71d5
--- /dev/null
+++ b/src/components/Kubernetes/RbacEditor.tsx
@@ -0,0 +1,116 @@
+import React from "react";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { Plus, X, Check } from "lucide-react";
+import { Input } from "@/components/ui";
+
+interface RbacEditorProps {
+ _clusterId: string;
+ namespace: string;
+ onClose: () => void;
+}
+
+export function RbacEditor({ _clusterId, namespace, onClose }: RbacEditorProps) {
+ const [activeTab, setActiveTab] = React.useState("roles");
+ const [newRoleName, setNewRoleName] = React.useState("");
+
+ return (
+
+
+
RBAC Editor
+
+
+
+
+
+
+
+
+ Roles
+ ClusterRoles
+ RoleBindings
+ ClusterRoleBindings
+
+
+
+
+
+
setNewRoleName(e.target.value)}
+ />
+
+
+
+
+
+
+
Role YAML Editor
+
+
+
+
+ apiVersion: rbac.authorization.k8s.io/v1
+
+
+ kind: Role
+
+
+ metadata:
+
+
+ name: {newRoleName || "role-name"}
+
+
+ namespace: {namespace}
+
+
+ rules:
+
+
+ - apiGroups: [""]
+
+
+ resources: ["pods"]
+
+
+ verbs: ["get", "list", "watch"]
+
+
+
+
+
+
+
+
+
+
ClusterRole editing would be displayed here
+
+
+
+
+
+
RoleBinding editing would be displayed here
+
+
+
+
+
+
ClusterRoleBinding editing would be displayed here
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/RbacViewer.tsx b/src/components/Kubernetes/RbacViewer.tsx
new file mode 100644
index 00000000..996e101c
--- /dev/null
+++ b/src/components/Kubernetes/RbacViewer.tsx
@@ -0,0 +1,196 @@
+import React from "react";
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { Plus, Shield, User } from "lucide-react";
+
+interface RbacViewerProps {
+ clusterId: string;
+ namespace: string;
+}
+
+export function RbacViewer({ clusterId, namespace }: RbacViewerProps) {
+ return (
+
+
+
+
RBAC Management
+
Cluster ID: {clusterId} | Namespace: {namespace}
+
+
+
+
+
+
+
+
+
+ Roles
+
+
+
+
+
+
+ Name
+ Namespace
+ Rules
+ Actions
+
+
+
+
+ pod-reader
+ {namespace}
+ get, list, watch pods
+
+
+
+
+
+ secret-viewer
+ {namespace}
+ get, list secrets
+
+
+
+
+
+ deployment-manager
+ {namespace}
+ get, list, create, update deployments
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ClusterRoles
+
+
+
+
+
+
+ Name
+ Rules
+ Actions
+
+
+
+
+ admin
+ Full access to all resources
+
+
+
+
+
+ edit
+ Modify resources in namespace
+
+
+
+
+
+ view
+ Read-only access to resources
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RoleBindings
+
+
+
+
+
+
+ Name
+ Role
+ Subjects
+ Actions
+
+
+
+
+ pod-reader-binding
+ pod-reader
+ user:alice
+
+
+
+
+
+ deployment-manager-binding
+ deployment-manager
+ group:devs
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ClusterRoleBindings
+
+
+
+
+
+
+ Name
+ ClusterRole
+ Subjects
+ Actions
+
+
+
+
+ admin-binding
+ admin
+ group:admins
+
+
+
+
+
+ view-binding
+ view
+ group:auditors
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/SecretDetail.tsx b/src/components/Kubernetes/SecretDetail.tsx
new file mode 100644
index 00000000..0c91a43a
--- /dev/null
+++ b/src/components/Kubernetes/SecretDetail.tsx
@@ -0,0 +1,122 @@
+import React from "react";
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui";
+import { Badge } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { X } from "lucide-react";
+import { YamlEditor } from "./YamlEditor";
+
+interface SecretDetailProps {
+ secretName: string;
+ namespace: string;
+ _clusterId: string;
+ onClose: () => void;
+}
+
+export function SecretDetail({ secretName, namespace, _clusterId, onClose }: SecretDetailProps) {
+ const [activeTab, setActiveTab] = React.useState("data");
+ const [showValues, setShowValues] = React.useState(false);
+
+ return (
+
+
+
+
Secret: {secretName}
+ Secret
+
+
+
+
+
+
+ Data
+ YAML
+ Metadata
+
+
+
+
+
+
+
+ Secret Data
+
+
+
+
+
+
+ username:
+
+ {showValues ? "admin" : "****"}
+
+
+
+ password:
+
+ {showValues ? "secret123" : "****"}
+
+
+
+ api-key:
+
+ {showValues ? "sk-abc123xyz" : "****"}
+
+
+
+
+
+
+
+
+ {}} />
+
+
+
+
+
+
+ Metadata
+
+
+
+ Name
+ {secretName}
+
+
+ Namespace
+ {namespace}
+
+
+ Type
+ Opaque
+
+
+ Created
+ 2 hours ago
+
+
+
+
+
+
+ Labels
+
+
+
+ app=web
+ tier=frontend
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/ServiceDetail.tsx b/src/components/Kubernetes/ServiceDetail.tsx
new file mode 100644
index 00000000..613c5548
--- /dev/null
+++ b/src/components/Kubernetes/ServiceDetail.tsx
@@ -0,0 +1,157 @@
+import React from "react";
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui";
+import { Badge } from "@/components/ui";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui";
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
+import { Button } from "@/components/ui";
+import { X } from "lucide-react";
+import { YamlEditor } from "./YamlEditor";
+
+interface ServiceDetailProps {
+ serviceName: string;
+ namespace: string;
+ _clusterId: string;
+ onClose: () => void;
+}
+
+export function ServiceDetail({ serviceName, namespace, _clusterId, onClose }: ServiceDetailProps) {
+ const [activeTab, setActiveTab] = React.useState("overview");
+
+ return (
+
+
+
+
Service: {serviceName}
+ {namespace}
+
+
+
+
+
+
+ Overview
+ Endpoints
+ YAML
+ Events
+
+
+
+
+
+
+
+ Service Information
+
+
+
+ Name
+ {serviceName}
+
+
+ Namespace
+ {namespace}
+
+
+ Type
+ ClusterIP
+
+
+ Cluster IP
+ 10.96.0.1
+
+
+ External IP
+ none
+
+
+ Port
+ 80/TCP
+
+
+
+
+
+
+ Selector
+
+
+
+ app=web
+
+
+
+
+
+
+ Labels
+
+
+
+ app=web
+ tier=frontend
+
+
+
+
+
+
+
+
+
+
+ IP
+ Port
+ Node
+
+
+
+
+ 10.0.0.1
+ 80
+ node-1
+
+
+ 10.0.0.2
+ 80
+ node-2
+
+
+ 10.0.0.3
+ 80
+ node-3
+
+
+
+
+
+
+ {}} />
+
+
+
+
+
+
+ Time
+ Reason
+ Type
+ Message
+
+
+
+
+ 2 hours ago
+ SettingClusterIP
+ Normal
+ Assigned cluster IP 10.96.0.1
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/Toast.tsx b/src/components/Kubernetes/Toast.tsx
new file mode 100644
index 00000000..f15499cb
--- /dev/null
+++ b/src/components/Kubernetes/Toast.tsx
@@ -0,0 +1,66 @@
+import React from "react";
+import { X, AlertCircle, CheckCircle, Info, AlertTriangle } from "lucide-react";
+import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui";
+import { Button } from "@/components/ui";
+
+interface ToastProps {
+ message: string;
+ type?: "success" | "error" | "info" | "warning";
+ duration?: number;
+ onClose: () => void;
+}
+
+export function Toast({ message, type = "info", duration = 5000, onClose }: ToastProps) {
+ const [visible, setVisible] = React.useState(true);
+
+ React.useEffect(() => {
+ if (duration > 0) {
+ const timer = setTimeout(() => {
+ setVisible(false);
+ setTimeout(onClose, 300);
+ }, duration);
+ return () => clearTimeout(timer);
+ }
+ }, [duration, onClose]);
+
+ const icons = {
+ success: ,
+ error: ,
+ info: ,
+ warning: ,
+ };
+
+ const bgColors = {
+ success: "bg-green-50 border-green-200",
+ error: "bg-red-50 border-red-200",
+ info: "bg-blue-50 border-blue-200",
+ warning: "bg-yellow-50 border-yellow-200",
+ };
+
+ return (
+
+
+
+
+
+ {icons[type]}
+
+ {type.charAt(0).toUpperCase() + type.slice(1)}
+
+
+
+
+
+
+ {message}
+
+
+
+ );
+}
diff --git a/src/components/Kubernetes/index.tsx b/src/components/Kubernetes/index.tsx
index 3def9745..3619ee2d 100644
--- a/src/components/Kubernetes/index.tsx
+++ b/src/components/Kubernetes/index.tsx
@@ -31,3 +31,17 @@ export { SearchBar } from "./SearchBar";
export { ContextSwitcher } from "./ContextSwitcher";
export { ApplicationView } from "./ApplicationView";
export { PodDetail } from "./PodDetail";
+export { DeploymentDetail } from "./DeploymentDetail";
+export { ServiceDetail } from "./ServiceDetail";
+export { ConfigMapDetail } from "./ConfigMapDetail";
+export { SecretDetail } from "./SecretDetail";
+export { ClusterOverview } from "./ClusterOverview";
+export { ClusterDetails } from "./ClusterDetails";
+export { Hotbar } from "./Hotbar";
+export { CommandPalette } from "./CommandPalette";
+export { Toast } from "./Toast";
+export { LoadingSpinner } from "./LoadingSpinner";
+export { CreateResourceModal } from "./CreateResourceModal";
+export { EditResourceModal } from "./EditResourceModal";
+export { RbacViewer } from "./RbacViewer";
+export { RbacEditor } from "./RbacEditor";