@codeswayam/ui 1.2.1 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +727 -173
- package/dist/components/base/badge.d.ts +1 -1
- package/dist/components/base/button.d.ts +2 -2
- package/dist/components/brand/BrandFooterSection.d.ts +8 -0
- package/dist/components/brand/BrandFooterSection.d.ts.map +1 -0
- package/dist/components/brand/BrandFooterSection.js +97 -0
- package/dist/components/brand/BrandNav.d.ts +17 -0
- package/dist/components/brand/BrandNav.d.ts.map +1 -0
- package/dist/components/brand/BrandNav.js +64 -0
- package/dist/components/neural/AICreditBadge.d.ts +9 -0
- package/dist/components/neural/AICreditBadge.d.ts.map +1 -0
- package/dist/components/neural/AICreditBadge.js +31 -0
- package/dist/components/neural/AIImageGeneratorModal.d.ts +9 -0
- package/dist/components/neural/AIImageGeneratorModal.d.ts.map +1 -0
- package/dist/components/neural/AIImageGeneratorModal.js +66 -0
- package/dist/components/neural/AIPromptPlayground.d.ts +10 -0
- package/dist/components/neural/AIPromptPlayground.d.ts.map +1 -0
- package/dist/components/neural/AIPromptPlayground.js +66 -0
- package/dist/components/neural/KnowledgeBasePicker.d.ts +18 -0
- package/dist/components/neural/KnowledgeBasePicker.d.ts.map +1 -0
- package/dist/components/neural/KnowledgeBasePicker.js +42 -0
- package/dist/components/neural/WorkflowPicker.d.ts +18 -0
- package/dist/components/neural/WorkflowPicker.d.ts.map +1 -0
- package/dist/components/neural/WorkflowPicker.js +46 -0
- package/dist/components/neural/index.d.ts +11 -0
- package/dist/components/neural/index.d.ts.map +1 -0
- package/dist/components/neural/index.js +5 -0
- package/dist/components/saas/NotificationBell.d.ts +12 -0
- package/dist/components/saas/NotificationBell.d.ts.map +1 -0
- package/dist/components/saas/NotificationBell.js +52 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/useNotifications.d.ts +24 -0
- package/dist/utils/useNotifications.d.ts.map +1 -0
- package/dist/utils/useNotifications.js +71 -0
- package/dist/utils/useWebPush.d.ts +14 -0
- package/dist/utils/useWebPush.d.ts.map +1 -0
- package/dist/utils/useWebPush.js +110 -0
- package/package.json +2 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
|
-
variant?: "default" | "
|
|
4
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "success" | "warning" | "info" | "purple" | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
6
|
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
7
7
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
declare const buttonVariants: (props?: ({
|
|
4
|
-
variant?: "
|
|
5
|
-
size?: "default" | "
|
|
4
|
+
variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
5
|
+
size?: "default" | "icon" | "sm" | "lg" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
8
8
|
asChild?: boolean;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface BrandFooterSectionProps {
|
|
2
|
+
currentApp?: 'codeswayam' | 'pixelforge' | 'pdfcraft' | 'neural' | 'auraflow';
|
|
3
|
+
theme?: 'auto' | 'light' | 'dark';
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function BrandFooterSection({ currentApp, theme, className, }: BrandFooterSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=BrandFooterSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandFooterSection.d.ts","sourceRoot":"","sources":["../../../src/components/brand/BrandFooterSection.tsx"],"names":[],"mappings":"AAKA,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqCD,wBAAgB,kBAAkB,CAAC,EACjC,UAAU,EACV,KAAc,EACd,SAAc,GACf,EAAE,uBAAuB,2CA2JzB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Layers, Sparkles, FileText, Bot, ArrowUpRight } from 'lucide-react';
|
|
4
|
+
const BRAND_CARDS = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Code Swayam',
|
|
7
|
+
slug: 'codeswayam',
|
|
8
|
+
url: 'https://codeswayam.com',
|
|
9
|
+
icon: Layers,
|
|
10
|
+
desc: 'Central platform, design systems, and digital product portfolio.',
|
|
11
|
+
iconColor: 'text-blue-500 bg-blue-500/10 border-blue-500/20',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'PixelForge',
|
|
15
|
+
slug: 'pixelforge',
|
|
16
|
+
url: 'https://pixelforge.codeswayam.com',
|
|
17
|
+
icon: Sparkles,
|
|
18
|
+
desc: '50+ free image tools: compress JPG to 20KB, convert WebP, resize for portals.',
|
|
19
|
+
iconColor: 'text-purple-500 bg-purple-500/10 border-purple-500/20',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'PDFCraft',
|
|
23
|
+
slug: 'pdfcraft',
|
|
24
|
+
url: 'https://pdfcraft.codeswayam.com',
|
|
25
|
+
icon: FileText,
|
|
26
|
+
desc: 'Fast, secure PDF tools: compress to 100KB, merge, split, sign & convert.',
|
|
27
|
+
iconColor: 'text-emerald-500 bg-emerald-500/10 border-emerald-500/20',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Neural AI',
|
|
31
|
+
slug: 'neural',
|
|
32
|
+
url: 'https://neural.codeswayam.com',
|
|
33
|
+
icon: Bot,
|
|
34
|
+
desc: 'Unified multi-model AI studio, image generation, and API gateways.',
|
|
35
|
+
iconColor: 'text-amber-500 bg-amber-500/10 border-amber-500/20',
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
export function BrandFooterSection({ currentApp, theme = 'auto', className = '', }) {
|
|
39
|
+
const isDark = theme === 'dark';
|
|
40
|
+
const schemaOrg = {
|
|
41
|
+
'@context': 'https://schema.org',
|
|
42
|
+
'@type': 'Organization',
|
|
43
|
+
name: 'Code Swayam',
|
|
44
|
+
url: 'https://codeswayam.com',
|
|
45
|
+
logo: 'https://codeswayam.com/logo.png',
|
|
46
|
+
sameAs: [
|
|
47
|
+
'https://twitter.com/codeswayam',
|
|
48
|
+
'https://linkedin.com/company/codeswayam',
|
|
49
|
+
'https://github.com/codeswayam',
|
|
50
|
+
],
|
|
51
|
+
hasPart: [
|
|
52
|
+
{
|
|
53
|
+
'@type': 'WebApplication',
|
|
54
|
+
name: 'PixelForge',
|
|
55
|
+
url: 'https://pixelforge.codeswayam.com',
|
|
56
|
+
applicationCategory: 'MultimediaApplication',
|
|
57
|
+
operatingSystem: 'All',
|
|
58
|
+
description: 'Free image compression, conversion, resizing, and AI editing suite.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
'@type': 'WebApplication',
|
|
62
|
+
name: 'PDFCraft',
|
|
63
|
+
url: 'https://pdfcraft.codeswayam.com',
|
|
64
|
+
applicationCategory: 'UtilitiesApplication',
|
|
65
|
+
operatingSystem: 'All',
|
|
66
|
+
description: 'Free browser-based PDF compression, merge, split, and conversion suite.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
'@type': 'WebApplication',
|
|
70
|
+
name: 'Neural AI',
|
|
71
|
+
url: 'https://neural.codeswayam.com',
|
|
72
|
+
applicationCategory: 'ArtificialIntelligenceApplication',
|
|
73
|
+
operatingSystem: 'All',
|
|
74
|
+
description: 'Enterprise generative AI studio, multi-model gateway, and automation platform.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
'@type': 'WebApplication',
|
|
78
|
+
name: 'AuraFlow',
|
|
79
|
+
url: 'https://auraflow.codeswayam.com',
|
|
80
|
+
applicationCategory: 'DeveloperApplication',
|
|
81
|
+
operatingSystem: 'All',
|
|
82
|
+
description: 'High-performance cloud infrastructure and microservice automation fabric.',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
return (_jsxs(_Fragment, { children: [_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: JSON.stringify(schemaOrg) } }), _jsx("div", { className: `border-t pt-12 pb-8 ${isDark ? 'border-white/10 text-white' : 'border-border/60 text-foreground'} ${className}`, children: _jsxs("div", { className: "max-w-7xl mx-auto px-6", children: [_jsxs("div", { className: "flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [_jsx("span", { className: "w-2 h-2 rounded-full bg-primary" }), _jsx("span", { className: `text-[11px] font-black uppercase tracking-[0.2em] ${isDark ? 'text-white' : 'text-foreground'}`, children: "The CodeSwayam Product Ecosystem" })] }), _jsx("p", { className: `text-xs max-w-xl leading-relaxed ${isDark ? 'text-white/60' : 'text-muted-foreground'}`, children: "Interconnected developer, media, and artificial intelligence tools engineered for speed, privacy, and zero bloat." })] }), _jsxs("a", { href: "https://codeswayam.com/tools", className: "inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-primary/10 hover:bg-primary text-primary hover:text-primary-foreground text-xs font-bold uppercase tracking-wider transition-all shrink-0 shadow-sm", children: ["Explore 150+ Free Tools Directory", _jsx(ArrowUpRight, { className: "w-3.5 h-3.5" })] })] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4", children: BRAND_CARDS.map((card) => {
|
|
87
|
+
const Icon = card.icon;
|
|
88
|
+
const isCurrent = currentApp === card.slug;
|
|
89
|
+
return (_jsx("a", { href: card.url, className: `group p-5 rounded-2xl border transition-all duration-300 flex flex-col justify-between ${isDark
|
|
90
|
+
? isCurrent
|
|
91
|
+
? 'border-primary/50 bg-primary/10'
|
|
92
|
+
: 'border-white/10 hover:border-primary/40 bg-white/[0.03] hover:bg-white/[0.06]'
|
|
93
|
+
: isCurrent
|
|
94
|
+
? 'border-primary/40 bg-primary/5'
|
|
95
|
+
: 'border-border hover:border-primary/40 bg-card hover:bg-card/80 shadow-sm'}`, children: _jsxs("div", { children: [_jsxs("div", { className: "flex items-center gap-3 mb-2.5", children: [_jsx("div", { className: `w-9 h-9 rounded-xl flex items-center justify-center shrink-0 border ${card.iconColor}`, children: _jsx(Icon, { className: "w-4 h-4" }) }), _jsx("div", { className: "min-w-0 flex-1", children: _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: `text-xs font-bold truncate group-hover:text-primary transition-colors ${isDark ? 'text-white' : 'text-foreground'}`, children: card.name }), isCurrent && (_jsx("span", { className: "w-2 h-2 rounded-full bg-primary shrink-0 animate-pulse", title: "Current Active App" }))] }) })] }), _jsx("p", { className: `text-[11px] leading-relaxed line-clamp-2 ${isDark ? 'text-white/60' : 'text-muted-foreground'}`, children: card.desc })] }) }, card.name));
|
|
96
|
+
}) })] }) })] }));
|
|
97
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface EcosystemApp {
|
|
3
|
+
name: string;
|
|
4
|
+
tagline: string;
|
|
5
|
+
url: string;
|
|
6
|
+
icon: React.ElementType;
|
|
7
|
+
badge?: string;
|
|
8
|
+
color: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const ECOSYSTEM_APPS: EcosystemApp[];
|
|
11
|
+
interface BrandAppSwitcherProps {
|
|
12
|
+
currentApp?: 'codeswayam' | 'pixelforge' | 'pdfcraft' | 'neural' | 'auraflow';
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function BrandAppSwitcher({ currentApp, className }: BrandAppSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=BrandNav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandNav.d.ts","sourceRoot":"","sources":["../../../src/components/brand/BrandNav.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAY3D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,cAAc,EAAE,YAAY,EAuCxC,CAAC;AAEF,UAAU,qBAAqB;IAC7B,UAAU,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,UAAU,EAAE,SAAc,EAAE,EAAE,qBAAqB,2CAuGrF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef, useEffect } from 'react';
|
|
4
|
+
import { Grid, Sparkles, FileText, Zap, Bot, ArrowRight, ExternalLink, Layers, } from 'lucide-react';
|
|
5
|
+
export const ECOSYSTEM_APPS = [
|
|
6
|
+
{
|
|
7
|
+
name: 'Code Swayam',
|
|
8
|
+
tagline: 'Enterprise Digital Ecosystem & Platform',
|
|
9
|
+
url: 'https://codeswayam.com',
|
|
10
|
+
icon: Layers,
|
|
11
|
+
color: 'text-blue-500 bg-blue-500/10 border-blue-500/20',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'PixelForge',
|
|
15
|
+
tagline: '50+ Free High-Speed Image Tools (Compress, Convert, AI)',
|
|
16
|
+
url: 'https://pixelforge.codeswayam.com',
|
|
17
|
+
icon: Sparkles,
|
|
18
|
+
badge: 'Popular',
|
|
19
|
+
color: 'text-purple-500 bg-purple-500/10 border-purple-500/20',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'PDFCraft',
|
|
23
|
+
tagline: 'Browser-Based PDF Suite (Merge, Compress, Convert, Sign)',
|
|
24
|
+
url: 'https://pdfcraft.codeswayam.com',
|
|
25
|
+
icon: FileText,
|
|
26
|
+
badge: 'Free',
|
|
27
|
+
color: 'text-emerald-500 bg-emerald-500/10 border-emerald-500/20',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Neural AI',
|
|
31
|
+
tagline: 'Multi-Model AI Gateway, Studio & Workflow Automation',
|
|
32
|
+
url: 'https://neural.codeswayam.com',
|
|
33
|
+
icon: Bot,
|
|
34
|
+
badge: 'AI',
|
|
35
|
+
color: 'text-amber-500 bg-amber-500/10 border-amber-500/20',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'AuraFlow',
|
|
39
|
+
tagline: 'Cloud Infrastructure, Pipelines & Microservice Fabric',
|
|
40
|
+
url: 'https://auraflow.codeswayam.com',
|
|
41
|
+
icon: Zap,
|
|
42
|
+
color: 'text-rose-500 bg-rose-500/10 border-rose-500/20',
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
export function BrandAppSwitcher({ currentApp, className = '' }) {
|
|
46
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
47
|
+
const menuRef = useRef(null);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
function handleClickOutside(event) {
|
|
50
|
+
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
|
51
|
+
setIsOpen(false);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
55
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
56
|
+
}, []);
|
|
57
|
+
return (_jsxs("div", { className: `relative inline-flex items-center ${className}`, ref: menuRef, children: [_jsxs("button", { onClick: () => setIsOpen(!isOpen), className: "inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full border border-border/70 bg-muted/40 hover:bg-muted text-muted-foreground hover:text-foreground transition-all cursor-pointer text-[11px] font-bold uppercase tracking-wider", title: "CodeSwayam Ecosystem Apps", "aria-label": "CodeSwayam Ecosystem Apps", "aria-expanded": isOpen, children: [_jsx(Grid, { className: "w-3.5 h-3.5 shrink-0 text-primary" }), _jsx("span", { children: "Apps" })] }), isOpen && (_jsxs("div", { className: "absolute right-0 top-full mt-2 w-80 md:w-96 rounded-2xl bg-card border border-border p-3 shadow-2xl z-50 animate-in fade-in zoom-in-95 duration-150", children: [_jsxs("div", { className: "px-3 py-2 border-b border-border mb-2 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "w-2 h-2 rounded-full bg-primary animate-pulse" }), _jsx("span", { className: "text-xs font-black uppercase tracking-wider text-foreground", children: "CodeSwayam Ecosystem" })] }), _jsxs("a", { href: "https://codeswayam.com/tools", className: "text-[10px] font-bold uppercase tracking-wider text-primary hover:underline flex items-center gap-1", children: ["All Tools ", _jsx(ExternalLink, { className: "w-2.5 h-2.5" })] })] }), _jsx("div", { className: "space-y-1", children: ECOSYSTEM_APPS.map((app) => {
|
|
58
|
+
const Icon = app.icon;
|
|
59
|
+
const isCurrent = currentApp && app.url.toLowerCase().includes(currentApp.toLowerCase());
|
|
60
|
+
return (_jsxs("a", { href: app.url, className: `flex items-start gap-3 p-2.5 rounded-xl transition-all ${isCurrent
|
|
61
|
+
? 'bg-primary/10 border border-primary/20'
|
|
62
|
+
: 'hover:bg-muted/60 border border-transparent hover:border-border/60'}`, children: [_jsx("div", { className: `w-9 h-9 rounded-xl flex items-center justify-center shrink-0 border ${app.color}`, children: _jsx(Icon, { className: "w-4 h-4" }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-bold text-xs text-foreground truncate", children: app.name }), app.badge && (_jsx("span", { className: "px-1.5 py-0.5 rounded text-[9px] font-black uppercase tracking-widest bg-primary/20 text-primary", children: app.badge })), isCurrent && (_jsx("span", { className: "text-[9px] text-muted-foreground font-medium ml-auto", children: "Current" }))] }), _jsx("p", { className: "text-[11px] text-muted-foreground line-clamp-1 mt-0.5", children: app.tagline })] })] }, app.name));
|
|
63
|
+
}) }), _jsxs("div", { className: "mt-3 pt-2.5 border-t border-border px-3 py-1.5 flex items-center justify-between text-xs text-muted-foreground bg-muted/20 rounded-xl", children: [_jsx("span", { children: "150+ free tools & services" }), _jsxs("a", { href: "https://codeswayam.com/tools", className: "font-bold text-foreground hover:text-primary flex items-center gap-1 transition-colors", children: ["Explore Directory ", _jsx(ArrowRight, { className: "w-3 h-3" })] })] })] }))] }));
|
|
64
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface AICreditBadgeProps {
|
|
2
|
+
apiUrl?: string;
|
|
3
|
+
costPreview?: number;
|
|
4
|
+
showAddButton?: boolean;
|
|
5
|
+
onUpgradeClick?: () => void;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function AICreditBadge({ apiUrl, costPreview, showAddButton, onUpgradeClick, className, }: AICreditBadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=AICreditBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AICreditBadge.d.ts","sourceRoot":"","sources":["../../../src/components/neural/AICreditBadge.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAgC,EAChC,WAAW,EACX,aAAqB,EACrB,cAAc,EACd,SAAc,GACf,EAAE,kBAAkB,2CAuDpB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Zap, Loader2, Plus } from "lucide-react";
|
|
5
|
+
export function AICreditBadge({ apiUrl = "http://localhost:3000", costPreview, showAddButton = false, onUpgradeClick, className = "", }) {
|
|
6
|
+
const [balance, setBalance] = useState(null);
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
let mounted = true;
|
|
10
|
+
async function fetchCredits() {
|
|
11
|
+
try {
|
|
12
|
+
const res = await fetch(`${apiUrl}/credits/balance`, { credentials: "include" });
|
|
13
|
+
if (res.ok) {
|
|
14
|
+
const data = await res.json();
|
|
15
|
+
if (mounted)
|
|
16
|
+
setBalance(data.balance ?? data.credits ?? 0);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
console.error("[AICreditBadge] Failed to fetch credits:", err);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
if (mounted)
|
|
24
|
+
setLoading(false);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
fetchCredits();
|
|
28
|
+
return () => { mounted = false; };
|
|
29
|
+
}, [apiUrl]);
|
|
30
|
+
return (_jsxs("div", { className: `inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-amber-500/10 border border-amber-500/20 text-amber-300 text-xs font-medium ${className}`, children: [_jsx(Zap, { className: "w-3.5 h-3.5 text-amber-400 fill-amber-400/30" }), loading ? (_jsx(Loader2, { className: "w-3 h-3 animate-spin text-amber-400" })) : (_jsxs("span", { children: [balance !== null ? balance.toLocaleString() : "0", " ", _jsx("span", { className: "text-[10px] text-amber-400/80 font-normal", children: "Credits" })] })), costPreview !== undefined && costPreview > 0 && (_jsxs("span", { className: "text-[10px] text-amber-400/70 border-l border-amber-500/30 pl-1.5", children: ["-", costPreview] })), showAddButton && (_jsx("button", { type: "button", onClick: onUpgradeClick, className: "ml-1 p-0.5 rounded-full hover:bg-amber-500/20 text-amber-300 transition", title: "Get more credits", children: _jsx(Plus, { className: "w-3 h-3" }) }))] }));
|
|
31
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface AIImageGeneratorModalProps {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
onSelectImage: (base64OrUrl: string) => void;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
defaultAspectRatio?: "1:1" | "16:9" | "9:16" | "4:3";
|
|
7
|
+
}
|
|
8
|
+
export declare function AIImageGeneratorModal({ isOpen, onClose, onSelectImage, apiUrl, defaultAspectRatio, }: AIImageGeneratorModalProps): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=AIImageGeneratorModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIImageGeneratorModal.d.ts","sourceRoot":"","sources":["../../../src/components/neural/AIImageGeneratorModal.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;CACtD;AAED,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,OAAO,EACP,aAAa,EACb,MAAgC,EAChC,kBAA0B,GAC3B,EAAE,0BAA0B,kDA6N5B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Image as ImageIcon, Sparkles, Loader2, X, Download, Check, RefreshCw } from "lucide-react";
|
|
5
|
+
export function AIImageGeneratorModal({ isOpen, onClose, onSelectImage, apiUrl = "http://localhost:3000", defaultAspectRatio = "1:1", }) {
|
|
6
|
+
const [prompt, setPrompt] = useState("");
|
|
7
|
+
const [negativePrompt, setNegativePrompt] = useState("");
|
|
8
|
+
const [aspectRatio, setAspectRatio] = useState(defaultAspectRatio);
|
|
9
|
+
const [loading, setLoading] = useState(false);
|
|
10
|
+
const [generatedImage, setGeneratedImage] = useState(null);
|
|
11
|
+
const [error, setError] = useState(null);
|
|
12
|
+
if (!isOpen)
|
|
13
|
+
return null;
|
|
14
|
+
const handleGenerate = async (e) => {
|
|
15
|
+
if (e)
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
if (!prompt.trim() || loading)
|
|
18
|
+
return;
|
|
19
|
+
setLoading(true);
|
|
20
|
+
setError(null);
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(`${apiUrl}/v1/generate-image`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
credentials: "include",
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
prompt: prompt.trim(),
|
|
28
|
+
negativePrompt: negativePrompt.trim() || undefined,
|
|
29
|
+
aspectRatio,
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
if (res.ok) {
|
|
33
|
+
const data = await res.json();
|
|
34
|
+
if (data.imageBase64) {
|
|
35
|
+
const imgSrc = `data:${data.mimeType || "image/png"};base64,${data.imageBase64}`;
|
|
36
|
+
setGeneratedImage(imgSrc);
|
|
37
|
+
}
|
|
38
|
+
else if (data.imageUrl) {
|
|
39
|
+
setGeneratedImage(data.imageUrl);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
setError("No image data returned from generation model.");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const errData = await res.json().catch(() => ({}));
|
|
47
|
+
setError(errData.message || "Failed to generate image. Please check your credit balance.");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
setError("Network error occurred during image generation.");
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
setLoading(false);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleUse = () => {
|
|
58
|
+
if (generatedImage) {
|
|
59
|
+
onSelectImage(generatedImage);
|
|
60
|
+
onClose();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return (_jsx("div", { className: "fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in-0 duration-200", children: _jsxs("div", { className: "bg-neutral-900 border border-neutral-800 w-full max-w-2xl rounded-2xl shadow-2xl flex flex-col max-h-[90vh] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-neutral-800 bg-neutral-900/60", children: [_jsxs("div", { className: "flex items-center gap-2.5", children: [_jsx("div", { className: "p-2 bg-primary/10 rounded-xl text-primary", children: _jsx(Sparkles, { className: "w-4 h-4" }) }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold text-neutral-100 text-sm", children: "AI Image Studio" }), _jsx("p", { className: "text-xs text-neutral-400", children: "Generate custom high-resolution images" })] })] }), _jsx("button", { type: "button", onClick: onClose, className: "p-1.5 text-neutral-400 hover:text-neutral-200 hover:bg-neutral-800 rounded-lg transition", children: _jsx(X, { className: "w-4 h-4" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-6 space-y-5", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-neutral-300 mb-1.5", children: "Describe what you want to generate" }), _jsx("textarea", { rows: 3, value: prompt, onChange: (e) => setPrompt(e.target.value), placeholder: "e.g. A sleek modern workspace with soft neon lighting and minimalist aesthetics...", className: "w-full px-3.5 py-2.5 text-sm bg-neutral-800/80 border border-neutral-700/70 rounded-xl text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-primary resize-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-neutral-300 mb-1.5", children: "Aspect Ratio" }), _jsx("div", { className: "grid grid-cols-4 gap-2", children: ["1:1", "16:9", "9:16", "4:3"].map((ratio) => (_jsxs("button", { type: "button", onClick: () => setAspectRatio(ratio), className: `py-2 px-3 text-xs rounded-xl border text-center transition font-medium ${aspectRatio === ratio
|
|
64
|
+
? "bg-primary/20 border-primary text-primary"
|
|
65
|
+
: "bg-neutral-800/60 border-neutral-700/60 text-neutral-300 hover:bg-neutral-800"}`, children: [ratio === "1:1" && "1:1 (Square)", ratio === "16:9" && "16:9 (Landscape)", ratio === "9:16" && "9:16 (Story/Reel)", ratio === "4:3" && "4:3 (Standard)"] }, ratio))) })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-neutral-400 mb-1", children: "Negative Prompt (Optional)" }), _jsx("input", { type: "text", value: negativePrompt, onChange: (e) => setNegativePrompt(e.target.value), placeholder: "e.g. blurry, low quality, distorted text, watermark", className: "w-full px-3.5 py-2 text-xs bg-neutral-800/60 border border-neutral-700/50 rounded-lg text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-primary" })] }), _jsxs("div", { className: "rounded-2xl border border-neutral-800 bg-neutral-950/50 p-4 flex flex-col items-center justify-center min-h-[220px]", children: [loading ? (_jsxs("div", { className: "flex flex-col items-center justify-center text-center py-8", children: [_jsx(Loader2, { className: "w-8 h-8 text-primary animate-spin mb-3" }), _jsx("p", { className: "text-sm font-medium text-neutral-300", children: "Generating your image..." }), _jsx("p", { className: "text-xs text-neutral-500 mt-1", children: "Rendering details, please wait" })] })) : generatedImage ? (_jsxs("div", { className: "flex flex-col items-center gap-4 w-full", children: [_jsx("div", { className: "relative max-h-72 rounded-xl overflow-hidden border border-neutral-800 shadow-lg", children: _jsx("img", { src: generatedImage, alt: "AI Generated", className: "max-h-72 object-contain rounded-xl" }) }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleGenerate, className: "px-3 py-1.5 text-xs bg-neutral-800 hover:bg-neutral-700 text-neutral-200 rounded-lg transition flex items-center gap-1.5", children: [_jsx(RefreshCw, { className: "w-3.5 h-3.5" }), " Regenerate"] }), _jsxs("a", { href: generatedImage, download: "ai-image.png", className: "px-3 py-1.5 text-xs bg-neutral-800 hover:bg-neutral-700 text-neutral-200 rounded-lg transition flex items-center gap-1.5", children: [_jsx(Download, { className: "w-3.5 h-3.5" }), " Download"] })] })] })) : (_jsxs("div", { className: "flex flex-col items-center justify-center text-center text-neutral-500 py-6", children: [_jsx(ImageIcon, { className: "w-10 h-10 mb-2 opacity-30 text-neutral-400" }), _jsx("p", { className: "text-xs text-neutral-400 font-medium", children: "No image generated yet" }), _jsx("p", { className: "text-[11px] text-neutral-500 max-w-xs mt-0.5", children: "Enter a prompt above and click generate to create a new image." })] })), error && (_jsx("div", { className: "mt-3 p-2.5 bg-red-500/10 border border-red-500/20 rounded-xl text-xs text-red-400 text-center w-full", children: error }))] })] }), _jsxs("div", { className: "px-6 py-4 border-t border-neutral-800 bg-neutral-900/60 flex items-center justify-between", children: [_jsx("span", { className: "text-xs text-neutral-400", children: "\u26A1 Estimated cost: 10 credits" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: onClose, className: "px-4 py-2 text-xs text-neutral-400 hover:text-neutral-200 font-medium transition", children: "Cancel" }), generatedImage ? (_jsxs("button", { type: "button", onClick: handleUse, className: "px-4 py-2 bg-primary text-primary-foreground text-xs font-semibold rounded-xl hover:bg-primary/90 transition flex items-center gap-1.5 shadow-lg shadow-primary/20", children: [_jsx(Check, { className: "w-3.5 h-3.5" }), " Use This Image"] })) : (_jsxs("button", { type: "button", disabled: !prompt.trim() || loading, onClick: handleGenerate, className: "px-5 py-2 bg-primary text-primary-foreground text-xs font-semibold rounded-xl hover:bg-primary/90 disabled:opacity-50 transition flex items-center gap-1.5 shadow-lg shadow-primary/20", children: [loading ? _jsx(Loader2, { className: "w-3.5 h-3.5 animate-spin" }) : _jsx(Sparkles, { className: "w-3.5 h-3.5" }), "Generate Image"] }))] })] })] }) }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface AIPromptPlaygroundProps {
|
|
2
|
+
systemPrompt: string;
|
|
3
|
+
knowledgeBaseId?: number | null;
|
|
4
|
+
appName?: string;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function AIPromptPlayground({ systemPrompt, knowledgeBaseId, appName, isOpen, onClose, apiUrl, }: AIPromptPlaygroundProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=AIPromptPlayground.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AIPromptPlayground.d.ts","sourceRoot":"","sources":["../../../src/components/neural/AIPromptPlayground.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,kBAAkB,CAAC,EACjC,YAAY,EACZ,eAAe,EACf,OAAsB,EACtB,MAAM,EACN,OAAO,EACP,MAAgC,GACjC,EAAE,uBAAuB,kDA0KzB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Send, Bot, User, Sparkles, Loader2, X, RefreshCw } from "lucide-react";
|
|
5
|
+
export function AIPromptPlayground({ systemPrompt, knowledgeBaseId, appName = "playground", isOpen, onClose, apiUrl = "http://localhost:3000", }) {
|
|
6
|
+
const [messages, setMessages] = useState([]);
|
|
7
|
+
const [input, setInput] = useState("");
|
|
8
|
+
const [loading, setLoading] = useState(false);
|
|
9
|
+
const [sessionId] = useState(() => `play_${Math.random().toString(36).substring(2, 9)}`);
|
|
10
|
+
if (!isOpen)
|
|
11
|
+
return null;
|
|
12
|
+
const handleSend = async (e) => {
|
|
13
|
+
if (e)
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
if (!input.trim() || loading)
|
|
16
|
+
return;
|
|
17
|
+
const userText = input.trim();
|
|
18
|
+
setInput("");
|
|
19
|
+
setMessages((prev) => [...prev, { role: "user", content: userText }]);
|
|
20
|
+
setLoading(true);
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(`${apiUrl}/agents/entity/chat`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "Content-Type": "application/json" },
|
|
25
|
+
credentials: "include",
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
appName,
|
|
28
|
+
entityId: `test_${sessionId}`,
|
|
29
|
+
systemPrompt,
|
|
30
|
+
knowledgeBaseId: knowledgeBaseId ?? undefined,
|
|
31
|
+
message: userText,
|
|
32
|
+
sessionId,
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
if (res.ok) {
|
|
36
|
+
const data = await res.json();
|
|
37
|
+
setMessages((prev) => [
|
|
38
|
+
...prev,
|
|
39
|
+
{
|
|
40
|
+
role: "assistant",
|
|
41
|
+
content: data.text || "No response received",
|
|
42
|
+
latencyMs: data.latencyMs,
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
setMessages((prev) => [
|
|
48
|
+
...prev,
|
|
49
|
+
{ role: "assistant", content: "Error: Failed to generate response from AI agent." },
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
setMessages((prev) => [
|
|
55
|
+
...prev,
|
|
56
|
+
{ role: "assistant", content: "Error: Network request failed." },
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
setLoading(false);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return (_jsx("div", { className: "fixed inset-0 z-50 bg-black/80 flex items-center justify-center p-4 backdrop-blur-sm animate-in fade-in-0 duration-200", children: _jsxs("div", { className: "bg-neutral-900 border border-neutral-800 w-full max-w-xl rounded-2xl shadow-2xl flex flex-col h-[600px] overflow-hidden", children: [_jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-neutral-800 bg-neutral-900/60", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "p-2 bg-primary/10 rounded-lg text-primary", children: _jsx(Sparkles, { className: "w-4 h-4" }) }), _jsxs("div", { children: [_jsx("h3", { className: "font-semibold text-neutral-100 text-sm", children: "AI Agent Live Playground" }), _jsx("p", { className: "text-xs text-neutral-400", children: knowledgeBaseId ? `Testing with KB #${knowledgeBaseId}` : "Testing prompt without KB" })] })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { type: "button", onClick: () => setMessages([]), title: "Clear chat", className: "p-1.5 text-neutral-400 hover:text-neutral-200 hover:bg-neutral-800 rounded-lg transition", children: _jsx(RefreshCw, { className: "w-4 h-4" }) }), _jsx("button", { type: "button", onClick: onClose, className: "p-1.5 text-neutral-400 hover:text-neutral-200 hover:bg-neutral-800 rounded-lg transition", children: _jsx(X, { className: "w-4 h-4" }) })] })] }), _jsxs("div", { className: "flex-1 overflow-y-auto p-4 space-y-4 text-sm", children: [messages.length === 0 && (_jsxs("div", { className: "flex flex-col items-center justify-center h-full text-center text-neutral-500 py-12", children: [_jsx(Bot, { className: "w-10 h-10 mb-2 opacity-40 text-primary" }), _jsx("p", { className: "font-medium text-neutral-400 text-sm", children: "Ready to test your prompt" }), _jsx("p", { className: "text-xs text-neutral-500 max-w-xs mt-1", children: "Type a message below to see how your AI agent will respond before publishing." })] })), messages.map((m, idx) => (_jsxs("div", { className: `flex gap-3 ${m.role === "user" ? "justify-end" : "justify-start"}`, children: [m.role === "assistant" && (_jsx("div", { className: "w-7 h-7 rounded-full bg-primary/20 text-primary flex items-center justify-center shrink-0 mt-0.5", children: _jsx(Bot, { className: "w-4 h-4" }) })), _jsxs("div", { className: `max-w-[80%] rounded-2xl px-4 py-2.5 text-sm ${m.role === "user"
|
|
64
|
+
? "bg-primary text-primary-foreground font-medium rounded-br-none"
|
|
65
|
+
: "bg-neutral-800/90 text-neutral-200 border border-neutral-700/60 rounded-bl-none"}`, children: [_jsx("div", { className: "whitespace-pre-wrap", children: m.content }), m.latencyMs !== undefined && (_jsxs("div", { className: "text-[10px] text-neutral-400 mt-1 text-right", children: [m.latencyMs, "ms"] }))] }), m.role === "user" && (_jsx("div", { className: "w-7 h-7 rounded-full bg-neutral-800 text-neutral-300 flex items-center justify-center shrink-0 mt-0.5", children: _jsx(User, { className: "w-4 h-4" }) }))] }, idx))), loading && (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "w-7 h-7 rounded-full bg-primary/20 text-primary flex items-center justify-center shrink-0", children: _jsx(Loader2, { className: "w-4 h-4 animate-spin" }) }), _jsx("div", { className: "bg-neutral-800/70 border border-neutral-700/40 rounded-2xl rounded-bl-none px-4 py-2 text-xs text-neutral-400", children: "Thinking..." })] }))] }), _jsxs("form", { onSubmit: handleSend, className: "p-3 border-t border-neutral-800 bg-neutral-900/60 flex gap-2", children: [_jsx("input", { type: "text", placeholder: "Send a test message...", value: input, onChange: (e) => setInput(e.target.value), disabled: loading, className: "flex-1 px-3.5 py-2 text-sm bg-neutral-800/80 border border-neutral-700/70 rounded-xl text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-primary" }), _jsx("button", { type: "submit", disabled: !input.trim() || loading, className: "px-4 py-2 bg-primary text-primary-foreground rounded-xl text-sm font-medium hover:bg-primary/90 disabled:opacity-50 transition flex items-center gap-1.5", children: _jsx(Send, { className: "w-3.5 h-3.5" }) })] })] }) }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface KnowledgeBaseItem {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
docCount: number;
|
|
6
|
+
status: "active" | "indexing" | "error";
|
|
7
|
+
createdAt?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface KnowledgeBasePickerProps {
|
|
10
|
+
value?: number | null;
|
|
11
|
+
onChange: (kbId: number | null) => void;
|
|
12
|
+
apiUrl?: string;
|
|
13
|
+
neuralWebUrl?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function KnowledgeBasePicker({ value, onChange, apiUrl, neuralWebUrl, className, disabled, }: KnowledgeBasePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=KnowledgeBasePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KnowledgeBasePicker.d.ts","sourceRoot":"","sources":["../../../src/components/neural/KnowledgeBasePicker.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,QAAQ,EACR,MAAgC,EAChC,YAAsC,EACtC,SAAc,EACd,QAAgB,GACjB,EAAE,wBAAwB,2CAyI1B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Database, Search, ExternalLink, Check, Loader2, Sparkles } from "lucide-react";
|
|
5
|
+
export function KnowledgeBasePicker({ value, onChange, apiUrl = "http://localhost:3000", neuralWebUrl = "http://localhost:3007", className = "", disabled = false, }) {
|
|
6
|
+
const [items, setItems] = useState([]);
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
const [search, setSearch] = useState("");
|
|
9
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
let mounted = true;
|
|
12
|
+
async function fetchKBs() {
|
|
13
|
+
try {
|
|
14
|
+
const res = await fetch(`${apiUrl}/knowledge-base`, { credentials: "include" });
|
|
15
|
+
if (res.ok) {
|
|
16
|
+
const data = await res.json();
|
|
17
|
+
if (mounted)
|
|
18
|
+
setItems(Array.isArray(data) ? data : data.items || []);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error("[KnowledgeBasePicker] Failed to load KBs:", err);
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
if (mounted)
|
|
26
|
+
setLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
fetchKBs();
|
|
30
|
+
return () => { mounted = false; };
|
|
31
|
+
}, [apiUrl]);
|
|
32
|
+
const filtered = items.filter((kb) => kb.name.toLowerCase().includes(search.toLowerCase()) ||
|
|
33
|
+
(kb.description && kb.description.toLowerCase().includes(search.toLowerCase())));
|
|
34
|
+
const selectedItem = items.find((k) => k.id === value);
|
|
35
|
+
return (_jsxs("div", { className: `relative ${className}`, children: [_jsxs("button", { type: "button", disabled: disabled, onClick: () => setIsOpen((prev) => !prev), className: "w-full flex items-center justify-between px-3 py-2 text-sm bg-neutral-900 border border-neutral-800 rounded-lg text-neutral-200 hover:border-neutral-700 focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-50 transition", children: [_jsxs("div", { className: "flex items-center gap-2 truncate", children: [_jsx(Database, { className: "w-4 h-4 text-primary shrink-0" }), loading ? (_jsxs("span", { className: "text-neutral-500 flex items-center gap-1", children: [_jsx(Loader2, { className: "w-3 h-3 animate-spin" }), " Loading knowledge bases..."] })) : selectedItem ? (_jsxs("span", { className: "truncate font-medium text-neutral-100", children: [selectedItem.name, " ", _jsxs("span", { className: "text-xs text-neutral-400 font-normal", children: ["(", selectedItem.docCount, " docs)"] })] })) : (_jsx("span", { className: "text-neutral-500", children: "None (General Knowledge)" }))] }), _jsx("span", { className: "text-xs text-neutral-500 ml-2", children: "\u25BC" })] }), isOpen && (_jsxs("div", { className: "absolute z-50 mt-1 w-full bg-neutral-900 border border-neutral-800 rounded-xl shadow-2xl p-2 text-sm max-h-72 flex flex-col", children: [_jsxs("div", { className: "relative mb-2", children: [_jsx(Search, { className: "w-3.5 h-3.5 text-neutral-400 absolute left-2.5 top-2.5" }), _jsx("input", { type: "text", placeholder: "Search knowledge bases...", value: search, onChange: (e) => setSearch(e.target.value), className: "w-full pl-8 pr-2 py-1.5 text-xs bg-neutral-800/80 border border-neutral-700/60 rounded-md text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-primary" })] }), _jsxs("div", { className: "overflow-y-auto flex-1 space-y-1", children: [_jsxs("button", { type: "button", onClick: () => {
|
|
36
|
+
onChange(null);
|
|
37
|
+
setIsOpen(false);
|
|
38
|
+
}, className: `w-full flex items-center justify-between px-2.5 py-1.5 rounded-lg text-left text-xs transition ${!value ? "bg-primary/20 text-primary font-medium" : "text-neutral-300 hover:bg-neutral-800/60"}`, children: [_jsx("span", { children: "None (No RAG attached)" }), !value && _jsx(Check, { className: "w-3.5 h-3.5" })] }), filtered.map((kb) => (_jsxs("button", { type: "button", onClick: () => {
|
|
39
|
+
onChange(kb.id);
|
|
40
|
+
setIsOpen(false);
|
|
41
|
+
}, className: `w-full flex items-center justify-between px-2.5 py-2 rounded-lg text-left text-xs transition ${value === kb.id ? "bg-primary/20 text-primary font-medium" : "text-neutral-200 hover:bg-neutral-800/60"}`, children: [_jsxs("div", { className: "truncate pr-2", children: [_jsx("div", { className: "font-medium truncate", children: kb.name }), kb.description && (_jsx("div", { className: "text-[10px] text-neutral-400 truncate", children: kb.description }))] }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [_jsxs("span", { className: "text-[10px] bg-neutral-800 text-neutral-400 px-1.5 py-0.5 rounded", children: [kb.docCount, " docs"] }), value === kb.id && _jsx(Check, { className: "w-3.5 h-3.5 text-primary" })] })] }, kb.id))), filtered.length === 0 && !loading && (_jsx("div", { className: "text-center py-4 text-xs text-neutral-500", children: "No knowledge bases found" }))] }), _jsx("div", { className: "pt-2 mt-1 border-t border-neutral-800/80", children: _jsxs("a", { href: `${neuralWebUrl}/knowledge-base`, target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-center gap-1.5 text-xs text-primary hover:underline font-medium py-1", children: [_jsx(Sparkles, { className: "w-3 h-3" }), " Create / Manage in Neural Hub", _jsx(ExternalLink, { className: "w-2.5 h-2.5" })] }) })] }))] }));
|
|
42
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface WorkflowItem {
|
|
2
|
+
id: number;
|
|
3
|
+
name: string;
|
|
4
|
+
slug?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
status: string;
|
|
7
|
+
nodeCount?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface WorkflowPickerProps {
|
|
10
|
+
value?: string | number | null;
|
|
11
|
+
onChange: (workflowIdentifier: string | number | null) => void;
|
|
12
|
+
apiUrl?: string;
|
|
13
|
+
neuralWebUrl?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function WorkflowPicker({ value, onChange, apiUrl, neuralWebUrl, className, disabled, }: WorkflowPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=WorkflowPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowPicker.d.ts","sourceRoot":"","sources":["../../../src/components/neural/WorkflowPicker.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,MAAgC,EAChC,YAAsC,EACtC,SAAc,EACd,QAAgB,GACjB,EAAE,mBAAmB,2CAoJrB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { GitBranch, Search, Check, Loader2, ExternalLink, Play } from "lucide-react";
|
|
5
|
+
export function WorkflowPicker({ value, onChange, apiUrl = "http://localhost:3000", neuralWebUrl = "http://localhost:3007", className = "", disabled = false, }) {
|
|
6
|
+
const [workflows, setWorkflows] = useState([]);
|
|
7
|
+
const [loading, setLoading] = useState(true);
|
|
8
|
+
const [search, setSearch] = useState("");
|
|
9
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
let mounted = true;
|
|
12
|
+
async function fetchWorkflows() {
|
|
13
|
+
try {
|
|
14
|
+
const res = await fetch(`${apiUrl}/workflows`, { credentials: "include" });
|
|
15
|
+
if (res.ok) {
|
|
16
|
+
const data = await res.json();
|
|
17
|
+
if (mounted)
|
|
18
|
+
setWorkflows(Array.isArray(data) ? data : data.items || []);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error("[WorkflowPicker] Failed to load workflows:", err);
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
if (mounted)
|
|
26
|
+
setLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
fetchWorkflows();
|
|
30
|
+
return () => { mounted = false; };
|
|
31
|
+
}, [apiUrl]);
|
|
32
|
+
const filtered = workflows.filter((w) => w.name.toLowerCase().includes(search.toLowerCase()) ||
|
|
33
|
+
(w.slug && w.slug.toLowerCase().includes(search.toLowerCase())) ||
|
|
34
|
+
(w.description && w.description.toLowerCase().includes(search.toLowerCase())));
|
|
35
|
+
const selectedItem = workflows.find((w) => w.id === value || w.slug === value);
|
|
36
|
+
return (_jsxs("div", { className: `relative ${className}`, children: [_jsxs("button", { type: "button", disabled: disabled, onClick: () => setIsOpen((prev) => !prev), className: "w-full flex items-center justify-between px-3 py-2 text-sm bg-neutral-900 border border-neutral-800 rounded-lg text-neutral-200 hover:border-neutral-700 focus:outline-none focus:ring-1 focus:ring-primary disabled:opacity-50 transition", children: [_jsxs("div", { className: "flex items-center gap-2 truncate", children: [_jsx(GitBranch, { className: "w-4 h-4 text-emerald-400 shrink-0" }), loading ? (_jsxs("span", { className: "text-neutral-500 flex items-center gap-1", children: [_jsx(Loader2, { className: "w-3 h-3 animate-spin" }), " Loading workflows..."] })) : selectedItem ? (_jsxs("span", { className: "truncate font-medium text-neutral-100", children: [selectedItem.name, " ", selectedItem.slug && (_jsxs("span", { className: "text-xs text-neutral-400 font-mono font-normal", children: ["(", selectedItem.slug, ")"] }))] })) : (_jsx("span", { className: "text-neutral-500", children: "None (No workflow attached)" }))] }), _jsx("span", { className: "text-xs text-neutral-500 ml-2", children: "\u25BC" })] }), isOpen && (_jsxs("div", { className: "absolute z-50 mt-1 w-full bg-neutral-900 border border-neutral-800 rounded-xl shadow-2xl p-2 text-sm max-h-72 flex flex-col", children: [_jsxs("div", { className: "relative mb-2", children: [_jsx(Search, { className: "w-3.5 h-3.5 text-neutral-400 absolute left-2.5 top-2.5" }), _jsx("input", { type: "text", placeholder: "Search workflows by name or slug...", value: search, onChange: (e) => setSearch(e.target.value), className: "w-full pl-8 pr-2 py-1.5 text-xs bg-neutral-800/80 border border-neutral-700/60 rounded-md text-neutral-200 placeholder-neutral-500 focus:outline-none focus:border-primary" })] }), _jsxs("div", { className: "overflow-y-auto flex-1 space-y-1", children: [_jsxs("button", { type: "button", onClick: () => {
|
|
37
|
+
onChange(null);
|
|
38
|
+
setIsOpen(false);
|
|
39
|
+
}, className: `w-full flex items-center justify-between px-2.5 py-1.5 rounded-lg text-left text-xs transition ${!value ? "bg-primary/20 text-primary font-medium" : "text-neutral-300 hover:bg-neutral-800/60"}`, children: [_jsx("span", { children: "None (Do not run workflow)" }), !value && _jsx(Check, { className: "w-3.5 h-3.5" })] }), filtered.map((wf) => {
|
|
40
|
+
const isSelected = value === wf.id || value === wf.slug;
|
|
41
|
+
return (_jsxs("button", { type: "button", onClick: () => {
|
|
42
|
+
onChange(wf.slug || wf.id);
|
|
43
|
+
setIsOpen(false);
|
|
44
|
+
}, className: `w-full flex items-center justify-between px-2.5 py-2 rounded-lg text-left text-xs transition ${isSelected ? "bg-primary/20 text-primary font-medium" : "text-neutral-200 hover:bg-neutral-800/60"}`, children: [_jsxs("div", { className: "truncate pr-2", children: [_jsxs("div", { className: "font-medium truncate flex items-center gap-1.5", children: [_jsx(Play, { className: "w-2.5 h-2.5 text-emerald-400" }), wf.name] }), wf.description && (_jsx("div", { className: "text-[10px] text-neutral-400 truncate", children: wf.description }))] }), _jsxs("div", { className: "flex items-center gap-1.5 shrink-0", children: [wf.nodeCount !== undefined && (_jsxs("span", { className: "text-[10px] bg-neutral-800 text-neutral-400 px-1.5 py-0.5 rounded", children: [wf.nodeCount, " steps"] })), isSelected && _jsx(Check, { className: "w-3.5 h-3.5 text-primary" })] })] }, wf.id));
|
|
45
|
+
}), filtered.length === 0 && !loading && (_jsx("div", { className: "text-center py-4 text-xs text-neutral-500", children: "No workflows found" }))] }), _jsx("div", { className: "pt-2 mt-1 border-t border-neutral-800/80", children: _jsxs("a", { href: `${neuralWebUrl}/workflows`, target: "_blank", rel: "noopener noreferrer", className: "flex items-center justify-center gap-1.5 text-xs text-primary hover:underline font-medium py-1", children: [_jsx(GitBranch, { className: "w-3 h-3" }), " Build New Workflow in Neural Hub", _jsx(ExternalLink, { className: "w-2.5 h-2.5" })] }) })] }))] }));
|
|
46
|
+
}
|