@retrivora-ai/rag-engine 1.9.6 → 1.9.8

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.
Files changed (62) hide show
  1. package/README.md +130 -113
  2. package/dist/{ILLMProvider-DNhyOYoK.d.mts → ILLMProvider-B8ROITYK.d.mts} +59 -8
  3. package/dist/{ILLMProvider-DNhyOYoK.d.ts → ILLMProvider-B8ROITYK.d.ts} +59 -8
  4. package/dist/handlers/index.d.mts +2 -2
  5. package/dist/handlers/index.d.ts +2 -2
  6. package/dist/handlers/index.js +2376 -489
  7. package/dist/handlers/index.mjs +2372 -489
  8. package/dist/{index-CjQdL0cX.d.ts → index-B8PbEFSY.d.mts} +17 -3
  9. package/dist/{index-CHL1jdYm.d.mts → index-BCPKUAVL.d.ts} +33 -41
  10. package/dist/{index-Hgbwl9X4.d.ts → index-CrxCy36A.d.mts} +33 -41
  11. package/dist/{index-C9v7-tWd.d.mts → index-DNvoi-sV.d.ts} +17 -3
  12. package/dist/index.css +695 -203
  13. package/dist/index.d.mts +37 -7
  14. package/dist/index.d.ts +37 -7
  15. package/dist/index.js +1197 -286
  16. package/dist/index.mjs +1221 -297
  17. package/dist/server.d.mts +62 -6
  18. package/dist/server.d.ts +62 -6
  19. package/dist/server.js +2526 -574
  20. package/dist/server.mjs +2517 -573
  21. package/package.json +12 -10
  22. package/src/app/constants.tsx +207 -212
  23. package/src/app/layout.tsx +4 -28
  24. package/src/app/types.ts +17 -17
  25. package/src/components/AmbientBackground.tsx +10 -10
  26. package/src/components/ArchitectureCard.tsx +43 -7
  27. package/src/components/ArchitectureCardsSection.tsx +37 -4
  28. package/src/components/ChatWidget.tsx +4 -1
  29. package/src/components/ChatWindow.tsx +9 -2
  30. package/src/components/CodeViewer.tsx +19 -14
  31. package/src/components/DocViewer.tsx +75 -15
  32. package/src/components/Documentation.tsx +111 -28
  33. package/src/components/Hero.tsx +103 -20
  34. package/src/components/Lifecycle.tsx +65 -25
  35. package/src/components/MarkdownComponents.tsx +44 -1
  36. package/src/components/MessageBubble.tsx +162 -50
  37. package/src/components/constants.tsx +279 -0
  38. package/src/config/RagConfig.ts +56 -10
  39. package/src/config/constants.ts +5 -0
  40. package/src/config/serverConfig.ts +15 -0
  41. package/src/core/ConfigResolver.ts +30 -25
  42. package/src/core/DatabaseStorage.ts +469 -0
  43. package/src/core/LicenseVerifier.ts +154 -0
  44. package/src/core/MultiAgentCoordinator.ts +239 -0
  45. package/src/core/Pipeline.ts +148 -16
  46. package/src/core/ProviderRegistry.ts +5 -5
  47. package/src/core/Retrivora.ts +52 -6
  48. package/src/core/VectorPlugin.ts +74 -11
  49. package/src/core/mcp.ts +261 -0
  50. package/src/exceptions/index.ts +52 -0
  51. package/src/handlers/index.ts +504 -47
  52. package/src/hooks/useRagChat.ts +100 -43
  53. package/src/hooks/useStoredMessages.ts +15 -4
  54. package/src/index.ts +7 -0
  55. package/src/llm/LLMFactory.ts +15 -6
  56. package/src/llm/providers/GroqProvider.ts +176 -0
  57. package/src/llm/providers/QwenProvider.ts +191 -0
  58. package/src/server.ts +23 -13
  59. package/src/types/chat.ts +16 -0
  60. package/src/types/props.ts +50 -1
  61. package/.env.example +0 -80
  62. package/LICENSE.txt +0 -21
@@ -1,27 +1,27 @@
1
1
  'use client';
2
2
 
3
3
  import React from 'react';
4
- import { useConfig } from '@/components/ConfigProvider';
5
4
 
6
5
  export function AmbientBackground() {
7
- const { ui } = useConfig();
8
-
9
6
  return (
10
7
  <div className="absolute inset-0 overflow-hidden pointer-events-none">
8
+ {/* Soft indigo orb — top left */}
11
9
  <div
12
- className="absolute -top-40 -left-40 w-[600px] h-[600px] rounded-full opacity-20 blur-3xl"
13
- style={{ background: ui.primaryColor }}
10
+ className="absolute -top-24 -left-24 w-[600px] h-[600px] rounded-full opacity-25 blur-3xl"
11
+ style={{ background: 'radial-gradient(circle, #c7d2fe 0%, #a5b4fc 40%, transparent 70%)' }}
14
12
  />
13
+ {/* Soft violet orb — top right */}
15
14
  <div
16
- className="absolute -bottom-40 -right-40 w-[600px] h-[600px] rounded-full opacity-15 blur-3xl"
17
- style={{ background: ui.accentColor }}
15
+ className="absolute -top-20 right-0 w-[500px] h-[500px] rounded-full opacity-20 blur-3xl"
16
+ style={{ background: 'radial-gradient(circle, #ddd6fe 0%, #c4b5fd 50%, transparent 70%)' }}
18
17
  />
18
+ {/* Subtle grid */}
19
19
  <div
20
- className="absolute inset-0 opacity-[0.05] dark:opacity-[0.03]"
20
+ className="absolute inset-0 opacity-[0.025]"
21
21
  style={{
22
22
  backgroundImage:
23
- 'linear-gradient(currentColor 1px, transparent 1px), linear-gradient(90deg, currentColor 1px, transparent 1px)',
24
- backgroundSize: '48px 48px',
23
+ 'linear-gradient(#6366f1 1px, transparent 1px), linear-gradient(90deg, #6366f1 1px, transparent 1px)',
24
+ backgroundSize: '56px 56px',
25
25
  }}
26
26
  />
27
27
  </div>
@@ -1,17 +1,53 @@
1
1
  import React from 'react';
2
2
  import { ArchitectureCardProps } from '@/app/types';
3
+ import { ArrowRight } from 'lucide-react';
3
4
 
4
- export function ArchitectureCard({ icon, title, description, badge, badgeColor }: ArchitectureCardProps) {
5
+ interface ExtendedArchitectureCardProps extends ArchitectureCardProps {
6
+ gradientFrom?: string;
7
+ gradientTo?: string;
8
+ }
9
+
10
+ export function ArchitectureCard({ icon, title, description, badge, badgeColor, gradientFrom = '#6366f1', gradientTo = '#8b5cf6' }: ExtendedArchitectureCardProps) {
5
11
  return (
6
- <div className="group rounded-2xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/5 p-6 shadow-sm transition-all duration-300 hover:border-indigo-500/50 dark:hover:border-indigo-500/30 hover:shadow-xl hover:shadow-indigo-500/5">
7
- <div className="mb-4 flex items-center justify-between">
8
- <div className="text-3xl transition-transform duration-300 group-hover:scale-110">{icon}</div>
9
- <span className={`rounded-full border px-3 py-0.5 text-[10px] font-bold uppercase tracking-wider ${badgeColor}`}>
12
+ <div className="group relative bg-white rounded-2xl border border-slate-200 p-6 transition-all duration-300 hover:-translate-y-1 hover:shadow-xl hover:shadow-slate-200/80 overflow-hidden cursor-default">
13
+ {/* Gradient top accent */}
14
+ <div
15
+ className="absolute top-0 left-0 right-0 h-0.5 rounded-t-2xl opacity-80 group-hover:opacity-100 transition-opacity"
16
+ style={{ background: `linear-gradient(90deg, ${gradientFrom}, ${gradientTo})` }}
17
+ />
18
+
19
+ {/* Card top row */}
20
+ <div className="mb-5 flex items-center justify-between">
21
+ <div
22
+ className="w-12 h-12 rounded-xl flex items-center justify-center text-2xl transition-transform duration-300 group-hover:scale-110"
23
+ style={{
24
+ background: `linear-gradient(135deg, ${gradientFrom}18, ${gradientTo}10)`,
25
+ border: `1px solid ${gradientFrom}20`,
26
+ }}
27
+ >
28
+ {icon}
29
+ </div>
30
+ <span className={`rounded-full border px-3 py-1 text-[10px] font-bold uppercase tracking-wider ${badgeColor}`}>
10
31
  {badge}
11
32
  </span>
12
33
  </div>
13
- <h3 className="mb-2 font-bold text-slate-900 dark:text-white">{title}</h3>
14
- <p className="text-xs text-slate-500 dark:text-white/40 leading-relaxed font-medium">{description}</p>
34
+
35
+ <h3 className="mb-2 font-bold text-slate-900 text-base">{title}</h3>
36
+ <p className="text-sm text-slate-500 leading-relaxed">{description}</p>
37
+
38
+ {/* "Learn more" on hover */}
39
+ <div
40
+ className="mt-5 flex items-center gap-1 text-[11px] font-semibold opacity-0 group-hover:opacity-100 transition-all duration-300 -translate-y-1 group-hover:translate-y-0"
41
+ style={{ color: gradientFrom }}
42
+ >
43
+ Learn more <ArrowRight className="h-3 w-3" />
44
+ </div>
45
+
46
+ {/* Subtle hover bg tint */}
47
+ <div
48
+ className="absolute inset-0 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity duration-500 pointer-events-none"
49
+ style={{ background: `radial-gradient(ellipse at 50% 0%, ${gradientFrom}05 0%, transparent 70%)` }}
50
+ />
15
51
  </div>
16
52
  );
17
53
  }
@@ -1,15 +1,48 @@
1
1
  'use client';
2
2
 
3
3
  import React from 'react';
4
+ import Link from 'next/link';
4
5
  import { ArchitectureCard } from '@/components/ArchitectureCard';
5
6
  import { ARCHITECTURE_CARDS } from '@/app/constants';
7
+ import { ArrowRight } from 'lucide-react';
8
+
9
+ const CARD_GRADIENTS = [
10
+ { from: '#6366f1', to: '#8b5cf6' },
11
+ { from: '#f59e0b', to: '#f97316' },
12
+ { from: '#10b981', to: '#06b6d4' },
13
+ ];
6
14
 
7
15
  export function ArchitectureCardsSection() {
8
16
  return (
9
- <div className="relative z-10 mt-24 mb-32 grid gap-6 sm:grid-cols-3 max-w-5xl mx-auto">
10
- {ARCHITECTURE_CARDS.map((card, i) => (
11
- <ArchitectureCard key={i} {...card} />
12
- ))}
17
+ <div className="relative">
18
+ <div className="text-center mb-12">
19
+ <h2 className="text-3xl md:text-4xl font-black text-slate-900 mb-4">
20
+ Built for every layer of the stack
21
+ </h2>
22
+ <p className="text-slate-500 max-w-xl mx-auto text-base leading-relaxed">
23
+ Swap providers without rewriting a single line of business logic.
24
+ </p>
25
+ </div>
26
+
27
+ <div className="grid gap-5 sm:grid-cols-3 max-w-5xl mx-auto">
28
+ {ARCHITECTURE_CARDS.map((card, i) => (
29
+ <ArchitectureCard
30
+ key={i}
31
+ {...card}
32
+ gradientFrom={CARD_GRADIENTS[i]?.from}
33
+ gradientTo={CARD_GRADIENTS[i]?.to}
34
+ />
35
+ ))}
36
+ </div>
37
+
38
+ <div className="mt-10 text-center">
39
+ <Link
40
+ href="/features"
41
+ className="inline-flex items-center gap-2 px-6 py-3 rounded-xl text-sm font-semibold text-slate-600 hover:text-indigo-600 border border-slate-200 hover:border-indigo-200 bg-white hover:bg-indigo-50 transition-all shadow-sm"
42
+ >
43
+ Explore all features <ArrowRight className="h-4 w-4" />
44
+ </Link>
45
+ </div>
13
46
  </div>
14
47
  );
15
48
  }
@@ -46,7 +46,7 @@ const GEMINI_STYLES = `
46
46
  }
47
47
  `;
48
48
 
49
- export function ChatWidget({ position = 'bottom-right', onAddToCart }: ChatWidgetProps) {
49
+ export function ChatWidget({ position = 'bottom-right', onAddToCart, apiUrl, retrivoraApiBase, headers }: ChatWidgetProps) {
50
50
  const { ui } = useConfig();
51
51
  const [isOpen, setIsOpen] = useState(false);
52
52
  const [hasUnread, setHasUnread] = useState(false);
@@ -146,6 +146,9 @@ export function ChatWidget({ position = 'bottom-right', onAddToCart }: ChatWidge
146
146
  onMaximize={ui.allowResize !== false ? handleMaximize : undefined}
147
147
  isMaximized={isMaximized}
148
148
  onAddToCart={onAddToCart}
149
+ apiUrl={apiUrl}
150
+ retrivoraApiBase={retrivoraApiBase}
151
+ headers={headers}
149
152
  />
150
153
  {/* Pointer (Tail) */}
151
154
  <div
@@ -62,7 +62,10 @@ export function ChatWindow({
62
62
  isResized = false,
63
63
  onMaximize,
64
64
  isMaximized = false,
65
- onAddToCart
65
+ onAddToCart,
66
+ apiUrl,
67
+ retrivoraApiBase,
68
+ headers
66
69
  }: ChatWindowProps) {
67
70
  const { ui, projectId } = useConfig();
68
71
  const [input, setInput] = useState('');
@@ -71,8 +74,11 @@ export function ChatWindow({
71
74
  const windowRef = useRef<HTMLDivElement>(null);
72
75
  const bottomRef = useRef<HTMLDivElement>(null);
73
76
  const inputRef = useRef<HTMLTextAreaElement>(null);
74
- const { messages, send, clear, isLoading, error, stop } = useRagChat(projectId, {
77
+ const { messages, send, clear, isLoading, error, stop, submitFeedback } = useRagChat(projectId, {
75
78
  namespace: projectId,
79
+ apiUrl,
80
+ retrivoraApiBase,
81
+ headers,
76
82
  });
77
83
 
78
84
  const [suggestions, setSuggestions] = useState<string[]>([]);
@@ -372,6 +378,7 @@ export function ChatWindow({
372
378
  accentColor={ui.accentColor}
373
379
  onAddToCart={onAddToCart}
374
380
  viewportSize={viewportSize}
381
+ onFeedback={submitFeedback}
375
382
  />
376
383
  ))
377
384
  )}
@@ -14,35 +14,40 @@ export function CodeViewer({ snippet }: { snippet: Snippet }) {
14
14
  };
15
15
 
16
16
  return (
17
- <div className="flex flex-col h-full rounded-2xl border border-slate-200 dark:border-white/10 bg-slate-50 dark:bg-slate-900/50 shadow-lg overflow-hidden min-h-[440px]">
18
- <div className="flex items-center justify-between px-5 py-3 border-b border-slate-200 dark:border-white/10 bg-white dark:bg-slate-900">
19
- <div className="flex items-center gap-3">
17
+ <div className="flex flex-col rounded-2xl border border-white/8 overflow-hidden min-h-[300px] shadow-xl">
18
+ {/* VS Code-style chrome header */}
19
+ <div className="flex items-center justify-between px-5 py-3 border-b border-white/5 bg-[#0d0d1a]">
20
+ <div className="flex items-center gap-4">
20
21
  <div className="flex gap-1.5">
21
- <div className="w-2.5 h-2.5 rounded-full bg-red-500" />
22
- <div className="w-2.5 h-2.5 rounded-full bg-yellow-500" />
23
- <div className="w-2.5 h-2.5 rounded-full bg-green-500" />
22
+ <div className="w-2.5 h-2.5 rounded-full bg-rose-500/80" />
23
+ <div className="w-2.5 h-2.5 rounded-full bg-amber-500/80" />
24
+ <div className="w-2.5 h-2.5 rounded-full bg-emerald-500/80" />
24
25
  </div>
25
- <span className="text-[10px] font-mono text-slate-400 dark:text-white/30 uppercase tracking-widest ml-2">{snippet.language}</span>
26
+ <span className="text-[10px] font-mono text-white/25 uppercase tracking-widest">
27
+ {snippet.language}
28
+ </span>
26
29
  </div>
27
30
  <button
28
31
  onClick={handleCopy}
29
- className="flex items-center gap-2 text-[10px] font-bold text-slate-500 dark:text-white/40 hover:text-indigo-600 dark:hover:text-indigo-400 transition-all active:scale-95"
32
+ className="flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-[10px] font-bold text-white/35 hover:text-white/80 hover:bg-white/5 transition-all active:scale-95"
30
33
  >
31
34
  {copied ? (
32
35
  <>
33
- <Check size={14} className="text-emerald-500" />
34
- <span className="text-emerald-500">Copied!</span>
36
+ <Check size={12} className="text-emerald-400" />
37
+ <span className="text-emerald-400">Copied!</span>
35
38
  </>
36
39
  ) : (
37
40
  <>
38
- <Copy size={14} />
39
- <span>Copy Code</span>
41
+ <Copy size={12} />
42
+ Copy Code
40
43
  </>
41
44
  )}
42
45
  </button>
43
46
  </div>
44
- <div className="p-8 font-mono text-[12px] leading-relaxed overflow-auto custom-scrollbar flex-grow bg-[#0f172a] text-indigo-50">
45
- <pre className="whitespace-pre">
47
+
48
+ {/* Code body */}
49
+ <div className="p-6 font-mono text-[12px] leading-relaxed overflow-auto flex-grow bg-[#080818]">
50
+ <pre className="whitespace-pre text-indigo-200/85">
46
51
  <code>{snippet.code}</code>
47
52
  </pre>
48
53
  </div>
@@ -4,34 +4,94 @@ import React from 'react';
4
4
  import { Snippet } from '@/app/types';
5
5
  import { SNIPPETS } from '@/app/constants';
6
6
  import { CodeViewer } from './CodeViewer';
7
+ import { ArrowLeft, ArrowRight } from 'lucide-react';
8
+
9
+ export function DocViewer({ activeSnippet, setActiveSnippet }: { activeSnippet: Snippet; setActiveSnippet: (s: Snippet) => void }) {
10
+ const currentIndex = SNIPPETS.findIndex(s => s.id === activeSnippet.id);
11
+ const totalSteps = SNIPPETS.length;
12
+ const isFirst = currentIndex === 0;
13
+ const isLast = currentIndex === totalSteps - 1;
14
+
15
+ const handlePrev = () => { if (!isFirst) setActiveSnippet(SNIPPETS[currentIndex - 1]); };
16
+ const handleNext = () => { if (!isLast) setActiveSnippet(SNIPPETS[currentIndex + 1]); };
17
+
18
+ const progressPercent = Math.round(((currentIndex + 1) / totalSteps) * 100);
7
19
 
8
- export function DocViewer({ activeSnippet, setActiveSnippet }: { activeSnippet: Snippet, setActiveSnippet: (s: Snippet) => void }) {
9
20
  return (
10
- <>
11
- <div className="mb-6 flex flex-wrap gap-2 border-b border-slate-100 dark:border-white/5 pb-6">
12
- {SNIPPETS.map((snippet) => (
21
+ <div className="flex flex-col h-full p-6 gap-5">
22
+ {/* Tab selector */}
23
+ <div className="flex flex-wrap gap-1.5 border-b border-slate-100 pb-5">
24
+ {SNIPPETS.map(snippet => (
13
25
  <button
14
26
  key={snippet.id}
15
27
  onClick={() => setActiveSnippet(snippet)}
16
- className={`px-5 py-2 rounded-xl text-[10px] font-bold uppercase tracking-wider transition-all border ${activeSnippet.id === snippet.id
17
- ? 'bg-indigo-600 text-white border-indigo-600 shadow-lg shadow-indigo-200 dark:shadow-indigo-500/20 scale-105'
18
- : 'bg-white dark:bg-white/5 border-slate-200 dark:border-white/10 text-slate-500 dark:text-white/40 hover:text-indigo-600 dark:hover:text-indigo-400 hover:border-indigo-300 dark:hover:border-white/20'
19
- }`}
28
+ className={`px-4 py-1.5 rounded-lg text-[10px] font-bold uppercase tracking-wider transition-all border ${
29
+ activeSnippet.id === snippet.id
30
+ ? 'bg-indigo-600 text-white border-indigo-600 shadow-sm scale-[1.03]'
31
+ : 'bg-slate-50 border-slate-200 text-slate-500 hover:text-indigo-600 hover:border-indigo-200 hover:bg-indigo-50'
32
+ }`}
20
33
  >
21
34
  {snippet.title}
22
35
  </button>
23
36
  ))}
24
37
  </div>
25
38
 
26
- <div className="flex-grow flex flex-col gap-6 animate-in fade-in slide-in-from-bottom-2 duration-500">
27
- <div className="max-w-2xl">
28
- <h3 className="text-xl font-bold text-slate-900 dark:text-white mb-2">{activeSnippet.title}</h3>
29
- <p className="text-sm text-slate-500 dark:text-white/40 leading-relaxed font-medium italic">
30
- {activeSnippet.description}
31
- </p>
39
+ {/* Progress bar */}
40
+ <div className="bg-slate-100 rounded-full h-1.5 overflow-hidden">
41
+ <div
42
+ className="h-full rounded-full transition-all duration-500"
43
+ style={{
44
+ width: `${progressPercent}%`,
45
+ background: 'linear-gradient(90deg, #4f46e5, #7c3aed)',
46
+ boxShadow: '0 0 6px rgba(79, 102, 241, 0.4)',
47
+ }}
48
+ />
49
+ </div>
50
+
51
+ {/* Content */}
52
+ <div className="flex-grow flex flex-col gap-5">
53
+ <div className="flex items-start justify-between gap-4 flex-wrap sm:flex-nowrap">
54
+ <div>
55
+ <h3 className="text-lg font-bold text-slate-900 mb-1.5 flex items-center gap-3">
56
+ {activeSnippet.title}
57
+ <span className="text-[9px] font-extrabold uppercase px-2 py-0.5 rounded bg-indigo-50 border border-indigo-100 text-indigo-600">
58
+ Step {currentIndex + 1} of {totalSteps}
59
+ </span>
60
+ </h3>
61
+ <p className="text-xs text-slate-500 leading-relaxed italic">{activeSnippet.description}</p>
62
+ </div>
63
+ <span className="text-xs font-mono font-bold text-indigo-600 self-center shrink-0">{progressPercent}% Complete</span>
32
64
  </div>
65
+
33
66
  <CodeViewer snippet={activeSnippet} />
67
+
68
+ {/* Navigation */}
69
+ <div className="flex items-center justify-between border-t border-slate-100 pt-5 mt-auto">
70
+ <button
71
+ onClick={handlePrev}
72
+ disabled={isFirst}
73
+ className={`flex items-center gap-2 px-5 py-2.5 rounded-xl text-xs font-bold transition-all border ${
74
+ isFirst
75
+ ? 'opacity-35 cursor-not-allowed border-slate-100 text-slate-300 bg-slate-50'
76
+ : 'bg-white border-slate-200 text-slate-600 hover:border-slate-300 hover:bg-slate-50 active:scale-95'
77
+ }`}
78
+ >
79
+ <ArrowLeft size={13} /> Previous Step
80
+ </button>
81
+ <button
82
+ onClick={handleNext}
83
+ disabled={isLast}
84
+ className={`flex items-center gap-2 px-6 py-2.5 rounded-xl text-xs font-bold transition-all border ${
85
+ isLast
86
+ ? 'opacity-35 cursor-not-allowed border-slate-100 text-slate-300 bg-slate-50'
87
+ : 'text-white border-transparent shadow-md active:scale-95 hover:-translate-y-0.5'
88
+ }`}
89
+ style={!isLast ? { background: 'linear-gradient(135deg, #4f46e5, #7c3aed)', boxShadow: '0 4px 14px -4px rgba(79,70,229,0.35)' } : {}}
90
+ >
91
+ {isLast ? 'Complete!' : 'Next Step'} <ArrowRight size={13} />
92
+ </button>
93
+ </div>
34
94
  </div>
35
- </>
95
+ </div>
36
96
  );
37
97
  }
@@ -1,56 +1,139 @@
1
1
  'use client';
2
2
 
3
3
  import React from 'react';
4
- import { FileText, Zap, Package, ExternalLink } from 'lucide-react';
4
+ import { FileText, Zap, Package, ExternalLink, Code } from 'lucide-react';
5
5
  import { DocViewer } from '@/components/DocViewer';
6
- import { LANDING_PAGE_CONTENT, QUICK_START_STEPS, API_ENDPOINTS, SNIPPETS } from '@/app/constants';
6
+ import { LANDING_PAGE_CONTENT, QUICK_START_STEPS, ADVANCED_STEPS, API_ENDPOINTS, SNIPPETS } from '@/app/constants';
7
7
  import { Snippet } from '@/app/types';
8
8
 
9
9
  export function Documentation() {
10
10
  const [activeSnippet, setActiveSnippet] = React.useState<Snippet>(SNIPPETS[0]);
11
11
 
12
12
  return (
13
- <div className="mt-32 max-w-6xl mx-auto mb-24 relative">
14
- <div className="text-center mb-16">
15
- <h2 className="text-3xl font-bold text-slate-900 dark:text-white mb-4">{LANDING_PAGE_CONTENT.guide.title}</h2>
16
- <p className="text-slate-600 dark:text-white/40 max-w-2xl mx-auto">{LANDING_PAGE_CONTENT.guide.subtitle}</p>
13
+ <div className="max-w-6xl mx-auto">
14
+ {/* Header */}
15
+ <div className="text-center mb-14">
16
+ <span className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-indigo-50 border border-indigo-100 text-[10px] font-bold uppercase tracking-widest text-indigo-600 mb-5">
17
+ <span className="w-1.5 h-1.5 rounded-full bg-indigo-500 animate-pulse" />
18
+ Developer Guide
19
+ </span>
20
+ <h2 className="text-3xl md:text-4xl font-black text-slate-900 mb-4">
21
+ {LANDING_PAGE_CONTENT.guide.title}
22
+ </h2>
23
+ <p className="text-slate-500 max-w-xl mx-auto text-base leading-relaxed">
24
+ {LANDING_PAGE_CONTENT.guide.subtitle}
25
+ </p>
17
26
  </div>
18
- <div className="relative z-10 w-full grid gap-16 lg:grid-cols-[280px_1fr] items-start">
19
- <aside className="flex flex-col gap-10">
27
+
28
+ {/* Grid */}
29
+ <div className="w-full grid gap-8 lg:grid-cols-[270px_1fr] items-start">
30
+ {/* Sidebar */}
31
+ <aside className="flex flex-col gap-5">
32
+ {/* Quick Start */}
20
33
  <section>
21
- <h2 className="mb-6 text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.3em] flex items-center gap-3">
22
- <FileText size={14} className="text-indigo-500" /> Quick Start
34
+ <h2 className="mb-3 text-[10px] font-black text-slate-400 uppercase tracking-[0.3em] flex items-center gap-2">
35
+ <FileText size={12} className="text-indigo-500" /> Quick Start
23
36
  </h2>
24
- <ol className="space-y-6">
25
- {QUICK_START_STEPS.map((step, i) => (
26
- <li key={i} className="group flex items-start gap-4">
27
- <span className="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg bg-white dark:bg-white/5 text-slate-600 dark:text-white/40 font-mono text-[10px] border border-slate-200 dark:border-white/10 shadow-sm">{i + 1}</span>
28
- <span className="text-xs text-slate-500 dark:text-white/50 font-medium leading-relaxed pt-1">{step}</span>
29
- </li>
30
- ))}
37
+ <ol className="space-y-1">
38
+ {QUICK_START_STEPS.map((step, i) => {
39
+ const isActive = activeSnippet.id === step.id;
40
+ return (
41
+ <li key={step.id}>
42
+ <button
43
+ onClick={() => { const s = SNIPPETS.find(s => s.id === step.id); if (s) setActiveSnippet(s); }}
44
+ className={`w-full flex items-start gap-3 p-3 rounded-xl border text-left transition-all active:scale-[0.98] ${
45
+ isActive
46
+ ? 'bg-indigo-50 border-indigo-200 shadow-sm'
47
+ : 'bg-white border-slate-200 hover:border-slate-300 hover:bg-slate-50'
48
+ }`}
49
+ >
50
+ <span className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-lg font-mono text-[10px] font-bold border transition-all ${
51
+ isActive ? 'bg-indigo-600 text-white border-indigo-600 shadow-sm' : 'bg-slate-100 text-slate-500 border-slate-200'
52
+ }`}>{i + 1}</span>
53
+ <div className="pt-0.5">
54
+ <span className={`text-xs font-semibold block ${isActive ? 'text-indigo-700 font-bold' : 'text-slate-700'}`}>{step.text}</span>
55
+ <span className="text-[9px] text-slate-400 block mt-0.5">Step {i + 1}</span>
56
+ </div>
57
+ </button>
58
+ </li>
59
+ );
60
+ })}
61
+ </ol>
62
+ </section>
63
+
64
+ {/* Advanced */}
65
+ <section>
66
+ <h2 className="mb-3 text-[10px] font-black text-slate-400 uppercase tracking-[0.3em] flex items-center gap-2">
67
+ <Code size={12} className="text-violet-500" /> Advanced Options
68
+ </h2>
69
+ <ol className="space-y-1">
70
+ {ADVANCED_STEPS.map((step, i) => {
71
+ const isActive = activeSnippet.id === step.id;
72
+ return (
73
+ <li key={step.id}>
74
+ <button
75
+ onClick={() => { const s = SNIPPETS.find(s => s.id === step.id); if (s) setActiveSnippet(s); }}
76
+ className={`w-full flex items-start gap-3 p-3 rounded-xl border text-left transition-all active:scale-[0.98] ${
77
+ isActive
78
+ ? 'bg-violet-50 border-violet-200 shadow-sm'
79
+ : 'bg-white border-slate-200 hover:border-slate-300 hover:bg-slate-50'
80
+ }`}
81
+ >
82
+ <span className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-lg font-mono text-[10px] font-bold border transition-all ${
83
+ isActive ? 'bg-violet-600 text-white border-violet-600 shadow-sm' : 'bg-slate-100 text-slate-500 border-slate-200'
84
+ }`}>{i + 5}</span>
85
+ <div className="pt-0.5">
86
+ <span className={`text-xs font-semibold block ${isActive ? 'text-violet-700 font-bold' : 'text-slate-700'}`}>{step.text}</span>
87
+ <span className="text-[9px] text-slate-400 block mt-0.5">Extension</span>
88
+ </div>
89
+ </button>
90
+ </li>
91
+ );
92
+ })}
31
93
  </ol>
32
94
  </section>
33
- <section className="rounded-2xl border border-slate-200 dark:border-white/10 bg-white dark:bg-white/3 p-6 shadow-sm">
34
- <h2 className="mb-6 text-[10px] font-black text-slate-400 dark:text-white/30 uppercase tracking-[0.3em] flex items-center gap-3">
35
- <Zap size={14} className="text-indigo-500" /> API Endpoints
95
+
96
+ {/* API Endpoints */}
97
+ <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
98
+ <h2 className="mb-4 text-[10px] font-black text-slate-400 uppercase tracking-[0.3em] flex items-center gap-2">
99
+ <Zap size={12} className="text-indigo-500" /> API Endpoints
36
100
  </h2>
37
- <div className="grid gap-2.5">
101
+ <div className="grid gap-2">
38
102
  {API_ENDPOINTS.map((slug) => (
39
- <div key={slug} className="group flex items-center justify-between p-2 rounded-lg bg-slate-50 dark:bg-white/5 border border-slate-100 dark:border-white/5 hover:border-indigo-200 dark:hover:border-indigo-500/30">
40
- <span className="text-[10px] font-mono text-slate-500 dark:text-white/30 group-hover:text-indigo-600">/api/{slug}</span>
41
- <span className="text-[8px] font-bold text-indigo-600 dark:text-indigo-400 bg-indigo-50 dark:bg-indigo-500/10 px-1.5 py-0.5 rounded border border-indigo-100 dark:border-indigo-500/20">POST</span>
103
+ <div
104
+ key={slug}
105
+ className="flex items-center justify-between p-2.5 rounded-lg bg-slate-50 border border-slate-100 hover:border-indigo-200 hover:bg-indigo-50 transition-all group"
106
+ >
107
+ <span className="text-[10px] font-mono text-slate-500 group-hover:text-indigo-600 transition-colors">/api/{slug}</span>
108
+ <span className="text-[8px] font-bold text-indigo-600 bg-indigo-50 px-1.5 py-0.5 rounded border border-indigo-100">POST</span>
42
109
  </div>
43
110
  ))}
44
111
  </div>
45
112
  </section>
46
113
  </aside>
114
+
115
+ {/* Code Viewer */}
47
116
  <section className="flex flex-col h-full min-h-[560px]">
48
- <DocViewer activeSnippet={activeSnippet} setActiveSnippet={setActiveSnippet} />
117
+ <div className="rounded-2xl border border-slate-200 bg-white overflow-hidden h-full shadow-sm">
118
+ <DocViewer activeSnippet={activeSnippet} setActiveSnippet={setActiveSnippet} />
119
+ </div>
49
120
  </section>
50
121
  </div>
51
- <div className="mt-16 text-center">
52
- <a href="https://www.npmjs.com/package/@retrivora-ai/rag-engine" className="inline-flex items-center gap-3 px-8 py-4 rounded-2xl bg-slate-900 dark:bg-white text-white dark:text-slate-900 font-bold shadow-xl shadow-indigo-500/20">
53
- <Package className="w-5 h-5" /> Get Started on NPM <ExternalLink className="w-4 h-4" />
122
+
123
+ {/* CTA */}
124
+ <div className="mt-14 text-center">
125
+ <a
126
+ href="https://www.npmjs.com/package/@retrivora-ai/rag-engine"
127
+ target="_blank" rel="noreferrer"
128
+ className="inline-flex items-center gap-3 px-8 py-4 rounded-2xl text-white font-bold text-sm shadow-lg transition-all hover:-translate-y-0.5"
129
+ style={{
130
+ background: 'linear-gradient(135deg, #4f46e5, #7c3aed)',
131
+ boxShadow: '0 8px 24px -6px rgba(79, 70, 229, 0.35)',
132
+ }}
133
+ >
134
+ <Package className="w-5 h-5" />
135
+ Get Started on NPM
136
+ <ExternalLink className="w-4 h-4" />
54
137
  </a>
55
138
  </div>
56
139
  </div>