dhi-copilot-ai 1.0.0

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 ADDED
@@ -0,0 +1,38 @@
1
+ # DHI Copilot - Interface Web (Next.js)
2
+
3
+ This is the graphical interface for the HR Copilot. It allows users to chat with the AI, view conversation history, and configure document sources.
4
+
5
+ ## 🚀 How to Start the Project
6
+
7
+ 1. **Prerequisites :** Have Node.js installed. The Python Backend must be started first.
8
+
9
+ 2. **Installation :**
10
+ Open a terminal in this folder and type:
11
+
12
+ ```bash
13
+ npm install
14
+ ```
15
+
16
+ 3. **Configuration :**
17
+ Rename the .env.example file to .env and verify the backend address:
18
+
19
+ ```env
20
+ NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
21
+ ```
22
+
23
+ 4. **Startup :**
24
+ Type the following command:
25
+
26
+ ```bash
27
+ npm run dev
28
+ ```
29
+
30
+ The interface will be available at: http://localhost:3000
31
+
32
+ ## 🎨 Features
33
+
34
+ - Chat: Fluid conversation with source display (document references).
35
+
36
+ - History: Sidebar to find and reload past conversations.
37
+
38
+ - Settings: Simplified forms to connect Azure Storage, S3, or local folders.
@@ -0,0 +1,139 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1 from 'react';
3
+
4
+ interface WidgetConfig {
5
+ primaryColor: string;
6
+ logoUrl: string;
7
+ botName: string;
8
+ position: "left" | "right";
9
+ apiUrl: string;
10
+ expandedDefault: boolean;
11
+ }
12
+ declare function WidgetProvider({ children, config }: {
13
+ children: React$1.ReactNode;
14
+ config?: Partial<WidgetConfig>;
15
+ }): react_jsx_runtime.JSX.Element;
16
+ declare const useWidgetConfig: () => WidgetConfig;
17
+
18
+ interface CopilotAppProps {
19
+ config: Partial<WidgetConfig>;
20
+ children?: React.ReactNode;
21
+ }
22
+ /**
23
+ * Composant principal à utiliser pour intégrer le Copilot
24
+ * dans une application React/Next.js existante.
25
+ */
26
+ declare function CopilotApp({ config, children }: CopilotAppProps): react_jsx_runtime.JSX.Element;
27
+
28
+ type MessageRole = "user" | "assistant" | "system" | "tool";
29
+ interface SourceReference {
30
+ file_name: string;
31
+ path: string;
32
+ score: number;
33
+ preview?: string;
34
+ }
35
+ interface Message {
36
+ id: string;
37
+ role: MessageRole;
38
+ content: string;
39
+ timestamp: Date;
40
+ sources?: string[];
41
+ isStreaming?: boolean;
42
+ }
43
+ interface ChatSession {
44
+ id: string;
45
+ title: string;
46
+ messages: Message[];
47
+ createdAt: Date;
48
+ updatedAt: Date;
49
+ }
50
+ interface ChatRequest {
51
+ message: string;
52
+ thread_id: string;
53
+ }
54
+ interface ChatResponse {
55
+ response: string;
56
+ thread_id: string;
57
+ sources: string[];
58
+ }
59
+ type StorageType = "SFTP" | "AWS_S3" | "AZURE_BLOB" | "GOOGLE_DRIVE" | "LOCAL" | "WEB";
60
+ interface SFTPCredentials {
61
+ host: string;
62
+ port: string;
63
+ user: string;
64
+ password: string;
65
+ }
66
+ interface S3Credentials {
67
+ aws_access_key_id: string;
68
+ aws_secret_access_key: string;
69
+ region: string;
70
+ bucket_name: string;
71
+ }
72
+ interface AzureCredentials {
73
+ protocol?: string;
74
+ account_name?: string;
75
+ account_key?: string;
76
+ suffix?: string;
77
+ connection_string?: string;
78
+ container: string;
79
+ }
80
+ interface GoogleDriveCredentials {
81
+ service_account_info: Record<string, string | number>;
82
+ folder_id: string;
83
+ }
84
+ interface WebCredentials {
85
+ [key: string]: never;
86
+ }
87
+ type ConnectorCredentials = SFTPCredentials | S3Credentials | AzureCredentials | GoogleDriveCredentials | WebCredentials | Record<string, never>;
88
+ interface ConnectorFormData {
89
+ source_id: string;
90
+ storage_type: StorageType;
91
+ path: string;
92
+ recursive: boolean;
93
+ credentials: ConnectorCredentials;
94
+ }
95
+ interface Connector extends ConnectorFormData {
96
+ status: "active" | "indexing" | "error" | "idle";
97
+ }
98
+ interface SyncResponse {
99
+ status: string;
100
+ details: string;
101
+ }
102
+
103
+ interface ChatWindowProps {
104
+ session: ChatSession;
105
+ isLoading: boolean;
106
+ error: string | null;
107
+ onSend: (message: string) => void;
108
+ onReset: () => void;
109
+ }
110
+ declare function ChatWindow({ session, isLoading, error, onSend, onReset, }: ChatWindowProps): react_jsx_runtime.JSX.Element;
111
+
112
+ interface SidebarProps {
113
+ expanded: boolean;
114
+ setExpanded: (val: boolean) => void;
115
+ isEmbed: boolean;
116
+ }
117
+ declare function Sidebar({ expanded, setExpanded, isEmbed }: SidebarProps): react_jsx_runtime.JSX.Element;
118
+
119
+ declare function useChat(): {
120
+ session: ChatSession;
121
+ isLoading: boolean;
122
+ error: string | null;
123
+ send: (userInput: string, files?: File[]) => Promise<void>;
124
+ reset: () => void;
125
+ };
126
+
127
+ declare function useConnectors(): {
128
+ connectors: Connector[];
129
+ isFetching: boolean;
130
+ isSaving: boolean;
131
+ isIndexing: string | null;
132
+ error: string | null;
133
+ successMsg: string | null;
134
+ save: (data: ConnectorFormData) => Promise<boolean>;
135
+ triggerIndexing: (sourceId: string) => Promise<void>;
136
+ refresh: () => Promise<void>;
137
+ };
138
+
139
+ export { type AzureCredentials, type ChatRequest, type ChatResponse, type ChatSession, ChatWindow, type Connector, type ConnectorCredentials, type ConnectorFormData, CopilotApp, type GoogleDriveCredentials, type Message, type MessageRole, type S3Credentials, type SFTPCredentials, Sidebar, type SourceReference, type StorageType, type SyncResponse, type WebCredentials, type WidgetConfig, WidgetProvider, useChat, useConnectors, useWidgetConfig };
@@ -0,0 +1,139 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1 from 'react';
3
+
4
+ interface WidgetConfig {
5
+ primaryColor: string;
6
+ logoUrl: string;
7
+ botName: string;
8
+ position: "left" | "right";
9
+ apiUrl: string;
10
+ expandedDefault: boolean;
11
+ }
12
+ declare function WidgetProvider({ children, config }: {
13
+ children: React$1.ReactNode;
14
+ config?: Partial<WidgetConfig>;
15
+ }): react_jsx_runtime.JSX.Element;
16
+ declare const useWidgetConfig: () => WidgetConfig;
17
+
18
+ interface CopilotAppProps {
19
+ config: Partial<WidgetConfig>;
20
+ children?: React.ReactNode;
21
+ }
22
+ /**
23
+ * Composant principal à utiliser pour intégrer le Copilot
24
+ * dans une application React/Next.js existante.
25
+ */
26
+ declare function CopilotApp({ config, children }: CopilotAppProps): react_jsx_runtime.JSX.Element;
27
+
28
+ type MessageRole = "user" | "assistant" | "system" | "tool";
29
+ interface SourceReference {
30
+ file_name: string;
31
+ path: string;
32
+ score: number;
33
+ preview?: string;
34
+ }
35
+ interface Message {
36
+ id: string;
37
+ role: MessageRole;
38
+ content: string;
39
+ timestamp: Date;
40
+ sources?: string[];
41
+ isStreaming?: boolean;
42
+ }
43
+ interface ChatSession {
44
+ id: string;
45
+ title: string;
46
+ messages: Message[];
47
+ createdAt: Date;
48
+ updatedAt: Date;
49
+ }
50
+ interface ChatRequest {
51
+ message: string;
52
+ thread_id: string;
53
+ }
54
+ interface ChatResponse {
55
+ response: string;
56
+ thread_id: string;
57
+ sources: string[];
58
+ }
59
+ type StorageType = "SFTP" | "AWS_S3" | "AZURE_BLOB" | "GOOGLE_DRIVE" | "LOCAL" | "WEB";
60
+ interface SFTPCredentials {
61
+ host: string;
62
+ port: string;
63
+ user: string;
64
+ password: string;
65
+ }
66
+ interface S3Credentials {
67
+ aws_access_key_id: string;
68
+ aws_secret_access_key: string;
69
+ region: string;
70
+ bucket_name: string;
71
+ }
72
+ interface AzureCredentials {
73
+ protocol?: string;
74
+ account_name?: string;
75
+ account_key?: string;
76
+ suffix?: string;
77
+ connection_string?: string;
78
+ container: string;
79
+ }
80
+ interface GoogleDriveCredentials {
81
+ service_account_info: Record<string, string | number>;
82
+ folder_id: string;
83
+ }
84
+ interface WebCredentials {
85
+ [key: string]: never;
86
+ }
87
+ type ConnectorCredentials = SFTPCredentials | S3Credentials | AzureCredentials | GoogleDriveCredentials | WebCredentials | Record<string, never>;
88
+ interface ConnectorFormData {
89
+ source_id: string;
90
+ storage_type: StorageType;
91
+ path: string;
92
+ recursive: boolean;
93
+ credentials: ConnectorCredentials;
94
+ }
95
+ interface Connector extends ConnectorFormData {
96
+ status: "active" | "indexing" | "error" | "idle";
97
+ }
98
+ interface SyncResponse {
99
+ status: string;
100
+ details: string;
101
+ }
102
+
103
+ interface ChatWindowProps {
104
+ session: ChatSession;
105
+ isLoading: boolean;
106
+ error: string | null;
107
+ onSend: (message: string) => void;
108
+ onReset: () => void;
109
+ }
110
+ declare function ChatWindow({ session, isLoading, error, onSend, onReset, }: ChatWindowProps): react_jsx_runtime.JSX.Element;
111
+
112
+ interface SidebarProps {
113
+ expanded: boolean;
114
+ setExpanded: (val: boolean) => void;
115
+ isEmbed: boolean;
116
+ }
117
+ declare function Sidebar({ expanded, setExpanded, isEmbed }: SidebarProps): react_jsx_runtime.JSX.Element;
118
+
119
+ declare function useChat(): {
120
+ session: ChatSession;
121
+ isLoading: boolean;
122
+ error: string | null;
123
+ send: (userInput: string, files?: File[]) => Promise<void>;
124
+ reset: () => void;
125
+ };
126
+
127
+ declare function useConnectors(): {
128
+ connectors: Connector[];
129
+ isFetching: boolean;
130
+ isSaving: boolean;
131
+ isIndexing: string | null;
132
+ error: string | null;
133
+ successMsg: string | null;
134
+ save: (data: ConnectorFormData) => Promise<boolean>;
135
+ triggerIndexing: (sourceId: string) => Promise<void>;
136
+ refresh: () => Promise<void>;
137
+ };
138
+
139
+ export { type AzureCredentials, type ChatRequest, type ChatResponse, type ChatSession, ChatWindow, type Connector, type ConnectorCredentials, type ConnectorFormData, CopilotApp, type GoogleDriveCredentials, type Message, type MessageRole, type S3Credentials, type SFTPCredentials, Sidebar, type SourceReference, type StorageType, type SyncResponse, type WebCredentials, type WidgetConfig, WidgetProvider, useChat, useConnectors, useWidgetConfig };
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";var Ge=Object.create;var O=Object.defineProperty,Xe=Object.defineProperties,Ke=Object.getOwnPropertyDescriptor,Ve=Object.getOwnPropertyDescriptors,Qe=Object.getOwnPropertyNames,Q=Object.getOwnPropertySymbols,Je=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty,fe=Object.prototype.propertyIsEnumerable;var pe=(e,t,s)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,b=(e,t)=>{for(var s in t||(t={}))ie.call(t,s)&&pe(e,s,t[s]);if(Q)for(var s of Q(t))fe.call(t,s)&&pe(e,s,t[s]);return e},S=(e,t)=>Xe(e,Ve(t));var q=(e,t)=>{var s={};for(var r in e)ie.call(e,r)&&t.indexOf(r)<0&&(s[r]=e[r]);if(e!=null&&Q)for(var r of Q(e))t.indexOf(r)<0&&fe.call(e,r)&&(s[r]=e[r]);return s};var Ye=(e,t)=>{for(var s in t)O(e,s,{get:t[s],enumerable:!0})},ge=(e,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Qe(t))!ie.call(e,n)&&n!==s&&O(e,n,{get:()=>t[n],enumerable:!(r=Ke(t,n))||r.enumerable});return e};var H=(e,t,s)=>(s=e!=null?Ge(Je(e)):{},ge(t||!e||!e.__esModule?O(s,"default",{value:e,enumerable:!0}):s,e)),Ze=e=>ge(O({},"__esModule",{value:!0}),e);var rt={};Ye(rt,{ChatWindow:()=>je,CopilotApp:()=>Ae,Sidebar:()=>ee,WidgetProvider:()=>J,useChat:()=>Oe,useConnectors:()=>qe,useWidgetConfig:()=>B});module.exports=Ze(rt);var M=require("react");var be=require("react/jsx-runtime"),he=(0,M.createContext)(void 0);function J({children:e,config:t}){let s={primaryColor:process.env.NEXT_PUBLIC_PRIMARY_COLOR||"#2563EB",logoUrl:process.env.NEXT_PUBLIC_WIDGET_LOGO||"/logo.png",botName:process.env.NEXT_PUBLIC_WIDGET_TITLE||"Copilot RH",position:"right",apiUrl:process.env.NEXT_PUBLIC_API_URL||"http://localhost:8000",expandedDefault:!1},r=(0,M.useMemo)(()=>b(b({},s),t),[t]);return(0,M.useEffect)(()=>{let n=document.documentElement;n.style.setProperty("--widget-primary",r.primaryColor),n.style.setProperty("--widget-primary-light",`${r.primaryColor}15`)},[r.primaryColor]),(0,be.jsx)(he.Provider,{value:r,children:e})}var B=()=>{let e=(0,M.useContext)(he);if(!e)throw new Error("useWidgetConfig must be used within WidgetProvider");return e};var me=require("react"),Se=require("next/navigation");var j=require("react"),X=H(require("next/link")),Re=H(require("next/image")),Z=require("next/navigation"),w=require("lucide-react");var xe=require("clsx"),ve=require("tailwind-merge");function c(...e){return(0,ve.twMerge)((0,xe.clsx)(e))}function we(e){return new Intl.DateTimeFormat("fr-FR",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}).format(e)}function le(){return`thread_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}var k=H(require("@radix-ui/react-tooltip"));var F=require("react/jsx-runtime");function Ne(s){var r=s,{delayDuration:e=0}=r,t=q(r,["delayDuration"]);return(0,F.jsx)(k.Provider,b({"data-slot":"tooltip-provider",delayDuration:e},t))}function ye(t){var e=q(t,[]);return(0,F.jsx)(k.Root,b({"data-slot":"tooltip"},e))}function Ce(t){var e=q(t,[]);return(0,F.jsx)(k.Trigger,b({"data-slot":"tooltip-trigger"},e))}function Pe(n){var l=n,{className:e,sideOffset:t=0,children:s}=l,r=q(l,["className","sideOffset","children"]);return(0,F.jsx)(k.Portal,{children:(0,F.jsxs)(k.Content,S(b({"data-slot":"tooltip-content",sideOffset:t,className:c("z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",e)},r),{children:[s,(0,F.jsx)(k.Arrow,{className:"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground"})]}))})}var ce=H(require("axios"));var ke=require("zustand"),Te=(0,ke.create)(e=>({isNetworkError:!1,setNetworkError:t=>e({isNetworkError:t})}));var et=process.env.PUBLIC_API_URL||"http://127.0.0.1:8000",_=ce.default.create({baseURL:et,timeout:6e5,headers:{"Content-Type":"application/json"}});_.interceptors.response.use(e=>e,e=>!e.response||e.code==="ERR_NETWORK"?(Te.getState().setNetworkError(!0),new Promise(()=>{})):Promise.reject(e));var $=e=>{var t,s;if(ce.default.isAxiosError(e)){let r=((s=(t=e.response)==null?void 0:t.data)==null?void 0:s.detail)||e.message||"Erreur de connexion au serveur";throw new Error(r)}throw new Error("Une erreur inattendue est survenue")},G={sendMessage:async e=>{try{return(await _.post("/chat",e)).data}catch(t){return $(t)}},listThreads:async()=>{try{return(await _.get("/chat/threads")).data}catch(e){return $(e)}},getHistory:async e=>{try{return(await _.get(`/chat/history/${e}`)).data.map((s,r)=>({id:`${e}-${r}-${Date.now()}`,role:s.role,content:s.content,timestamp:new Date}))}catch(t){return $(t)}}},Y={save:async e=>{try{return(await _.post("/connectors",e)).data}catch(t){return $(t)}},list:async()=>{try{return(await _.get("/settings/connectors")).data}catch(e){return $(e)}},sync:async e=>{try{return(await _.post(`/documents/sync/${e}`)).data}catch(t){return $(t)}}},Ee={upload:async(e,t="default")=>{try{let s=new FormData;return e.forEach(n=>{s.append("files",n)}),(await _.post(`/upload?tenant_id=${t}`,s,{headers:{"Content-Type":"multipart/form-data"}})).data}catch(s){return $(s)}}};var o=require("react/jsx-runtime");function tt(){return(0,j.useSyncExternalStore)(e=>(window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)),()=>window.innerWidth<768,()=>!1)}function ee({expanded:e,setExpanded:t,isEmbed:s}){let r=(0,Z.usePathname)(),l=(0,Z.useSearchParams)().get("threadId"),[m,T]=(0,j.useState)([]),{botName:C,logoUrl:P}=B(),I=tt();(0,j.useEffect)(()=>{(async()=>{try{let i=await G.listThreads();T(i)}catch(i){T([])}})()},[r]);let u=()=>{(s||I)&&t(!1)};return(0,o.jsxs)(Ne,{delayDuration:500,children:[e&&(s||I)&&(0,o.jsx)("div",{className:"fixed inset-0 bg-slate-900/20 backdrop-blur-sm z-40 transition-opacity duration-300",onClick:()=>t(!1)}),(0,o.jsxs)("aside",{className:c("relative h-screen bg-white border-r border-slate-100 flex flex-col shrink-0 transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] z-50",e?s?"w-full":"w-64":"w-16",(s||I)&&e?"fixed inset-y-0 left-0 shadow-2xl":"relative"),children:[(0,o.jsxs)("div",{className:"flex items-center h-16 px-4 border-b border-slate-50",children:[(0,o.jsxs)("div",{className:"flex items-center gap-3 overflow-hidden",children:[(0,o.jsx)("div",{className:"w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white shrink-0 shadow-lg shadow-blue-200",children:(0,o.jsx)(w.Bot,{size:20,strokeWidth:2.5,className:c("transition-transform duration-500",e&&"rotate-[360deg]")})}),e&&(0,o.jsxs)("div",{className:"flex flex-col animate-in fade-in slide-in-from-left-2 duration-300",children:[(0,o.jsx)("span",{className:"font-bold text-slate-900 leading-tight",children:C}),(0,o.jsxs)("span",{className:"text-[10px] text-emerald-500 font-medium flex items-center gap-1",children:[(0,o.jsx)("span",{className:"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"})," IA Active"]})]})]}),(0,o.jsx)("button",{onClick:()=>t(!e),className:"ml-auto p-2 hover:bg-slate-100 rounded-lg text-slate-400 transition-colors",children:e?(0,o.jsx)(w.PanelLeftClose,{size:18}):(0,o.jsx)(w.PanelLeftOpen,{size:18})})]}),(0,o.jsx)("div",{className:"p-3",children:(0,o.jsx)(de,{label:"Nouveau chat",show:!e,children:(0,o.jsxs)(X.default,{href:"/chat",onClick:u,className:c("flex items-center gap-3 bg-blue-600 text-white rounded-xl font-semibold transition-all shadow-md shadow-blue-100 hover:bg-blue-700 hover:shadow-lg active:scale-95",e?"px-4 py-3 w-full":"w-10 h-10 justify-center mx-auto"),children:[(0,o.jsx)(w.Plus,{size:20,strokeWidth:3}),e&&(0,o.jsx)("span",{className:"text-sm",children:"Nouvelle discussion"})]})})}),(0,o.jsxs)("nav",{className:"flex flex-col gap-1 px-3 mt-2",children:[(0,o.jsx)(de,{label:"Discussions",show:!e,children:(0,o.jsxs)(X.default,{href:"/chat",onClick:u,className:c("flex items-center gap-3 p-2.5 rounded-xl text-sm transition-all group",r.startsWith("/chat")?"bg-slate-100 text-blue-600 font-bold":"text-slate-500 hover:bg-slate-50 hover:text-slate-900"),children:[(0,o.jsx)(w.MessageSquare,{size:18,className:c(r.startsWith("/chat")?"text-blue-600":"text-slate-400 group-hover:text-slate-600")}),e&&(0,o.jsx)("span",{children:"Chat"})]})}),(0,o.jsx)(de,{label:"Param\xE8tres",show:!e,children:(0,o.jsxs)(X.default,{href:"/settings",onClick:u,className:c("flex items-center gap-3 p-2.5 rounded-xl text-sm transition-all group",r==="/settings"?"bg-slate-100 text-blue-600 font-bold":"text-slate-500 hover:bg-slate-50 hover:text-slate-900"),children:[(0,o.jsx)(w.Settings,{size:18,className:c(r==="/settings"?"text-blue-600":"text-slate-400 group-hover:text-slate-600")}),e&&(0,o.jsx)("span",{children:"Param\xE8tres"})]})})]}),e&&(0,o.jsxs)("div",{className:"flex-1 overflow-y-auto mt-6 px-3 custom-scrollbar animate-in fade-in duration-500",children:[(0,o.jsxs)("div",{className:"flex items-center justify-between mb-3 px-2",children:[(0,o.jsx)("span",{className:"text-[10px] font-bold text-slate-400 uppercase tracking-widest",children:"Historique"}),(0,o.jsx)(w.Clock,{size:10,className:"text-slate-300"})]}),(0,o.jsx)("div",{className:"flex flex-col gap-1 pb-4",children:m.length===0?(0,o.jsx)("div",{className:"px-3 py-4 border border-dashed border-slate-100 rounded-xl text-center",children:(0,o.jsx)("p",{className:"text-[10px] text-slate-400 italic",children:"Aucune discussion"})}):m.map(x=>(0,o.jsxs)(X.default,{href:`/chat?threadId=${x.id}`,onClick:u,className:c("group relative flex flex-col gap-0.5 p-2.5 rounded-xl transition-all border border-transparent",l===x.id?"bg-blue-50/50 border-blue-100 text-blue-700 font-semibold":"text-slate-600 hover:bg-slate-50 hover:border-slate-100"),children:[l===x.id&&(0,o.jsx)("div",{className:"absolute left-0 top-2 bottom-2 w-1 bg-blue-600 rounded-r-full"}),(0,o.jsx)("span",{className:"text-[11px] truncate leading-tight",children:x.title}),(0,o.jsxs)("span",{className:"text-[8px] text-slate-400 group-hover:text-blue-400 transition-colors uppercase font-medium",children:["Discussion ID: ",x.id.slice(-4)]})]},x.id))})]}),(0,o.jsx)("div",{className:"mt-auto p-4 border-t border-slate-50 bg-slate-50/30",children:(0,o.jsxs)("div",{className:c("flex items-center gap-3",!e&&"justify-center"),children:[(0,o.jsxs)("div",{className:"relative shrink-0",children:[(0,o.jsx)("div",{className:"w-9 h-9 rounded-full overflow-hidden border-2 border-white shadow-sm bg-slate-100 flex items-center justify-center",children:(0,o.jsx)(Re.default,{src:P,alt:"User Profile",width:36,height:36,className:"object-contain"})}),(0,o.jsx)("div",{className:"absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-emerald-500 border-2 border-white rounded-full"})]}),e&&(0,o.jsxs)("div",{className:"min-w-0 flex flex-col animate-in slide-in-from-bottom-1 duration-300",children:[(0,o.jsx)("p",{className:"text-xs font-bold text-slate-800 truncate",children:"Administrateur DHI"}),(0,o.jsx)("p",{className:"text-[10px] text-slate-400 font-medium truncate",children:"Console de Gestion"})]})]})})]})]})}function de({children:e,label:t,show:s}){return s?(0,o.jsxs)(ye,{children:[(0,o.jsx)(Ce,{asChild:!0,children:e}),(0,o.jsx)(Pe,{side:"right",sideOffset:10,className:"bg-slate-900 text-white border-none text-[10px] px-2 py-1 shadow-xl",children:t})]}):(0,o.jsx)(o.Fragment,{children:e})}var K=require("react/jsx-runtime");function We({children:e}){let s=(0,Se.useSearchParams)().get("embed")==="true",[r,n]=(0,me.useState)(s),[l,m]=(0,me.useState)(!s);return s!==r&&(n(s),m(!s)),(0,K.jsxs)("div",{className:"flex h-screen overflow-hidden",children:[(0,K.jsx)(ee,{expanded:l,setExpanded:m,isEmbed:s}),(0,K.jsx)("main",{className:c("flex-1 overflow-hidden transition-all duration-300",s&&l?"hidden":"block"),children:e})]})}var Ie=require("react"),V=require("react/jsx-runtime");function Ae({config:e,children:t}){return(0,V.jsx)(J,{config:e,children:(0,V.jsx)(Ie.Suspense,{fallback:(0,V.jsx)("div",{className:"h-screen bg-slate-50 animate-pulse"}),children:(0,V.jsx)(We,{children:t})})})}var oe=require("react"),ae=require("lucide-react");var te=require("lucide-react"),Me=H(require("react-markdown")),Fe=H(require("remark-gfm"));var Le=require("lucide-react"),W=require("react/jsx-runtime");function De(){return(0,W.jsxs)("div",{className:"flex items-start gap-3 message-enter",children:[(0,W.jsx)("div",{className:"w-7 h-7 rounded-lg bg-blue-600 flex items-center justify-center shrink-0 mt-0.5 shadow-sm",children:(0,W.jsx)(Le.Bot,{className:"w-3.5 h-3.5 text-white",strokeWidth:2.5})}),(0,W.jsxs)("div",{className:"bg-[#F3F4F6] rounded-2xl rounded-tl-sm px-4 py-3 flex items-center gap-1.5",children:[(0,W.jsx)("span",{className:"text-xs text-slate-400 mr-1 select-none",children:"L'assistant r\xE9fl\xE9chit"}),(0,W.jsx)("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"}),(0,W.jsx)("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"}),(0,W.jsx)("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"})]})]})}var f=require("react/jsx-runtime");function _e({message:e}){let t=e.role==="user";return e.isStreaming?(0,f.jsx)(De,{}):(0,f.jsxs)("div",{className:c("flex items-start gap-3 w-full message-enter",t?"flex-row-reverse":"flex-row"),children:[(0,f.jsx)("div",{className:c("w-8 h-8 rounded-lg flex items-center justify-center shrink-0 mt-0.5 shadow-sm",t?"bg-slate-100":"bg-blue-600"),children:t?(0,f.jsx)(te.User,{size:16,className:"text-slate-500"}):(0,f.jsx)(te.Bot,{size:16,className:"text-white"})}),(0,f.jsxs)("div",{className:c("flex flex-col gap-2 max-w-[85%]",t?"items-end":"items-start"),children:[(0,f.jsx)("div",{className:c("rounded-2xl px-4 py-3 text-sm leading-relaxed shadow-sm",t?"bg-white border border-slate-200 text-slate-800 rounded-tr-sm":"bg-[#F3F4F6] text-slate-700 rounded-tl-sm"),children:(0,f.jsx)("div",{className:"prose-hr-chat max-w-none",children:(0,f.jsx)(Me.default,{remarkPlugins:[Fe.default],children:e.content})})}),!t&&e.sources&&e.sources.length>0&&(0,f.jsxs)("div",{className:"mt-3 pt-3 border-t border-slate-100 w-full",children:[(0,f.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,f.jsx)("div",{className:"w-1 h-3 bg-blue-500 rounded-full"}),(0,f.jsx)("span",{className:"text-[10px] font-bold text-slate-400 uppercase tracking-widest",children:"Sources & Citations"})]}),(0,f.jsx)("div",{className:"flex flex-wrap gap-2",children:e.sources.map((s,r)=>(0,f.jsxs)("div",{className:"group relative flex items-center gap-1.5 px-2 py-1 bg-white border border-slate-200 rounded-lg text-[10px] text-slate-600 shadow-sm hover:border-blue-300 hover:text-blue-600 transition-all cursor-default",children:[(0,f.jsx)("span",{className:"w-1 h-1 bg-slate-300 rounded-full group-hover:bg-blue-400"}),s]},r))})]}),(0,f.jsx)("span",{className:"text-[10px] text-slate-300 px-1",children:we(new Date(e.timestamp))})]})]})}var z=require("lucide-react"),ze=H(require("next/image"));var N=require("react/jsx-runtime"),st=[{icon:z.Coins,label:"Grilles de salaires",prompt:"Montre-moi les grilles de salaires pour les ing\xE9nieurs seniors."},{icon:z.ClipboardList,label:"Proc\xE9dures RH",prompt:"Quelle est la proc\xE9dure pour poser des cong\xE9s pay\xE9s ?"},{icon:z.Users,label:"Onboarding",prompt:"Quelles sont les \xE9tapes d'onboarding pour un nouvel employ\xE9 ?"},{icon:z.FileSearch,label:"R\xE8glement int\xE9rieur",prompt:"R\xE9sume les points cl\xE9s du r\xE8glement int\xE9rieur."}];function Ue({onSuggestion:e}){let{botName:t,logoUrl:s}=B();return(0,N.jsxs)("div",{className:"flex flex-col items-center justify-center h-full gap-8 px-4 select-none",children:[(0,N.jsxs)("div",{className:"flex flex-col items-center gap-3",children:[(0,N.jsx)("div",{className:"relative w-14 h-14 rounded-2xl bg-white border border-slate-100 flex items-center justify-center shadow-sm overflow-hidden p-2",children:(0,N.jsx)(ze.default,{src:s,alt:`${t} Logo`,width:40,height:40,priority:!0,className:"object-contain"})}),(0,N.jsxs)("div",{className:"text-center",children:[(0,N.jsxs)("h1",{className:"text-lg font-semibold text-slate-800",children:["Bonjour, je suis votre Copilot ",t]}),(0,N.jsx)("p",{className:"text-sm text-slate-400 mt-1",children:"Posez vos questions sur vos documents RH internes."})]})]}),(0,N.jsx)("div",{className:"grid grid-cols-2 gap-2 w-full max-w-md",children:st.map(r=>{let n=r.icon;return(0,N.jsxs)("button",{onClick:()=>e(r.prompt),className:"flex items-start gap-2.5 p-3 rounded-xl bg-white border border-slate-100 hover:border-blue-200 hover:bg-blue-50/50 text-left transition-all duration-200 shadow-sm group",children:[(0,N.jsx)("div",{className:"mt-0.5 w-6 h-6 rounded-lg bg-blue-50 group-hover:bg-blue-100 flex items-center justify-center shrink-0 transition-colors",children:(0,N.jsx)(n,{className:"w-3.5 h-3.5 text-blue-500",strokeWidth:1.8})}),(0,N.jsx)("span",{className:"text-xs font-medium text-slate-600 group-hover:text-slate-800 leading-snug transition-colors",children:r.label})]},r.label)})})]})}var A=require("react"),U=require("lucide-react");var g=require("react/jsx-runtime");function He({onSend:e,isLoading:t,disabled:s}){let[r,n]=(0,A.useState)(""),[l,m]=(0,A.useState)([]),T=(0,A.useRef)(null),C=(0,A.useRef)(null),P=i=>{if(i.target.files){let a=Array.from(i.target.files);m(d=>[...d,...a])}},I=i=>{m(a=>a.filter((d,v)=>v!==i))},u=(0,A.useCallback)(()=>{let i=r.trim();!i&&l.length===0||t||s||(e(i,l),n(""),m([]))},[r,l,t,s,e]),h=i=>{i.key==="Enter"&&!i.shiftKey&&(i.preventDefault(),u())},E=(0,A.useCallback)(i=>{n(i.target.value);let a=i.target;a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,160)}px`},[]),x=r.trim().length>0&&!t&&!s;return(0,g.jsxs)("div",{className:"px-4 pb-4 pt-2",children:[(0,g.jsx)("div",{className:"flex flex-wrap gap-2 mb-2",children:l.map((i,a)=>(0,g.jsxs)("div",{className:"flex items-center gap-2 px-2 py-1 bg-blue-50 border border-blue-100 rounded-lg text-[10px] text-blue-600",children:[(0,g.jsx)(U.FileText,{className:"w-3 h-3"}),(0,g.jsx)("span",{className:"truncate max-w-[100px]",children:i.name}),(0,g.jsx)("button",{onClick:()=>I(a),className:"hover:text-red-500",children:(0,g.jsx)(U.X,{className:"w-3 h-3"})})]},a))}),(0,g.jsxs)("div",{className:c("flex items-end gap-2 bg-white border rounded-2xl px-3 py-2.5 shadow-sm transition-all duration-200","border-slate-200 focus-within:border-blue-300 focus-within:shadow-[0_0_0_3px_rgba(59,130,246,0.08)]"),children:[(0,g.jsx)("input",{type:"file",ref:T,onChange:P,className:"hidden",multiple:!0,accept:".pdf,.docx,.txt,.mp3,.wav,.png,.jpg"}),(0,g.jsx)("button",{type:"button",onClick:()=>{var i;return(i=T.current)==null?void 0:i.click()},className:"p-1.5 rounded-lg text-slate-300 hover:text-slate-500 hover:bg-slate-50 transition-colors shrink-0 mb-0.5","aria-label":"Joindre un fichier",tabIndex:-1,children:(0,g.jsx)(U.Paperclip,{className:"w-4 h-4",strokeWidth:1.8})}),(0,g.jsx)("textarea",{ref:C,value:r,onChange:E,onKeyDown:h,placeholder:l.length>0?"Ajouter un message au fichier...":"Posez votre question RH\u2026",rows:1,disabled:s,className:c("flex-1 resize-none bg-transparent text-sm text-slate-800 placeholder:text-slate-300","outline-none leading-relaxed py-0.5 max-h-40 min-h-[22px]","disabled:opacity-50 disabled:cursor-not-allowed"),"aria-label":"Message"}),(0,g.jsx)("button",{type:"button",onClick:u,disabled:!x,"aria-label":"Envoyer",className:c("w-8 h-8 rounded-xl flex items-center justify-center shrink-0 transition-all duration-200 mb-0.5",x?"bg-blue-600 text-white hover:bg-blue-700 shadow-sm hover:shadow":"bg-slate-100 text-slate-300 cursor-not-allowed"),children:(0,g.jsx)(U.ArrowUp,{className:"w-4 h-4",strokeWidth:2.5})})]}),(0,g.jsx)("p",{className:"text-center text-[10px] text-slate-300 mt-2",children:"Entr\xE9e pour envoyer \xB7 Maj+Entr\xE9e pour sauter une ligne"})]})}var Be=require("next/navigation");var se=require("lucide-react"),re=require("next/navigation"),L=require("react/jsx-runtime");function $e({title:e="Copilot RH"}){let t=(0,re.useRouter)(),s=(0,re.usePathname)();return(0,L.jsxs)("header",{className:"flex items-center justify-between px-4 py-3 border-b border-slate-100 bg-white",children:[(0,L.jsxs)("div",{className:"flex items-center gap-3",children:[s!=="/chat"&&(0,L.jsx)("button",{onClick:()=>t.back(),className:"p-1 hover:bg-slate-100 rounded-full transition-colors",children:(0,L.jsx)(se.ChevronLeft,{size:20,className:"text-slate-600"})}),(0,L.jsx)("h2",{className:"text-sm font-bold text-slate-800",children:e})]}),(0,L.jsx)("button",{onClick:()=>window.parent.postMessage("close-dhi-copilot","*"),children:(0,L.jsx)(se.X,{size:20,className:"text-slate-400 hover:text-red-500"})})]})}var p=require("react/jsx-runtime");function je({session:e,isLoading:t,error:s,onSend:r,onReset:n}){let l=(0,oe.useRef)(null),m=e.messages.length>0,C=(0,Be.useSearchParams)().get("embed")==="true";return(0,oe.useEffect)(()=>{l.current&&l.current.scrollTo({top:l.current.scrollHeight,behavior:"smooth"})},[e.messages]),(0,p.jsxs)("div",{className:"flex flex-col h-full bg-[#F9FAFB]",children:[C?(0,p.jsx)($e,{}):(0,p.jsxs)("header",{className:"flex items-center justify-between px-5 py-3 border-b border-slate-100 bg-white shrink-0",children:[(0,p.jsxs)("div",{className:"flex items-center gap-2",children:[(0,p.jsx)("div",{className:"w-2 h-2 rounded-full bg-emerald-400"}),(0,p.jsx)("span",{className:"text-sm font-medium text-slate-700",children:m?e.title:"Copilot RH"})]}),m&&(0,p.jsxs)("button",{onClick:n,className:"flex items-center gap-1.5 text-xs text-slate-400 hover:text-slate-600 transition-colors px-2 py-1 rounded-lg hover:bg-slate-50",title:"Nouvelle conversation",children:[(0,p.jsx)(ae.RotateCcw,{className:"w-3 h-3",strokeWidth:2}),"Nouvelle conversation"]})]}),(0,p.jsx)("div",{ref:l,className:c("flex-1 overflow-y-auto px-4 py-4",m?"flex flex-col gap-4":""),children:m?(0,p.jsx)(p.Fragment,{children:e.messages.map(P=>(0,p.jsx)(_e,{message:P},P.id))}):(0,p.jsx)(Ue,{onSuggestion:r})}),s&&(0,p.jsxs)("div",{className:"mx-4 mb-2 px-3 py-2 bg-red-50 border border-red-100 rounded-xl flex items-start gap-2",children:[(0,p.jsx)(ae.AlertCircle,{className:"w-3.5 h-3.5 text-red-400 mt-0.5 shrink-0"}),(0,p.jsx)("p",{className:"text-xs text-red-600 leading-relaxed",children:s})]}),(0,p.jsx)(He,{onSend:r,isLoading:t})]})}var D=require("react"),ne=require("next/navigation"),ue=require("uuid");function Oe(){let e=(0,ne.useSearchParams)(),t=(0,ne.useRouter)(),s=e.get("threadId"),[r,n]=(0,D.useState)(()=>({id:s||le(),title:"Nouvelle conversation",messages:[],createdAt:new Date,updatedAt:new Date})),[l,m]=(0,D.useState)(!1),[T,C]=(0,D.useState)(null);(0,D.useEffect)(()=>{s&&s!==r.id&&(async()=>{m(!0),C(null);try{let h=await G.getHistory(s);n({id:s,title:"Conversation charg\xE9e",messages:h,createdAt:new Date,updatedAt:new Date})}catch(h){C("Impossible de charger l'historique de cette discussion.")}finally{m(!1)}})()},[s]);let P=(0,D.useCallback)(async(u,h=[])=>{if(!u.trim()&&h.length===0||l)return;C(null),m(!0);let E=u.trim();if(h.length>0){let a=h.map(d=>`\u{1F4C4} ${d.name}`).join(`
2
+ `);E+=`
3
+
4
+ *Fichiers joints :*
5
+ ${a}`}let x={id:(0,ue.v4)(),role:"user",content:E,timestamp:new Date},i="loading-ai-message";n(a=>S(b({},a),{messages:[...a.messages,x,{id:i,role:"assistant",content:"",timestamp:new Date,isStreaming:!0}]}));try{h.length>0&&await Ee.upload(h);let a=u.trim()||`Analyse les ${h.length} fichiers que je viens d'envoyer.`,d=await G.sendMessage({message:a,thread_id:r.id});n(v=>S(b({},v),{messages:v.messages.map(R=>R.id===i?{id:(0,ue.v4)(),role:"assistant",content:d.response,sources:d.sources,timestamp:new Date,isStreaming:!1}:R)})),r.messages.length===0&&t.replace(`/chat?threadId=${r.id}`)}catch(a){C(a instanceof Error?a.message:"Erreur."),n(d=>S(b({},d),{messages:d.messages.filter(v=>v.id!==i)}))}finally{m(!1)}},[l,r.id,r.messages.length,t]),I=(0,D.useCallback)(()=>{let u=le();n({id:u,title:"Nouvelle conversation",messages:[],createdAt:new Date,updatedAt:new Date}),t.push("/chat"),C(null)},[t]);return{session:r,isLoading:l,error:T,send:P,reset:I}}var y=require("react");function qe(){let[e,t]=(0,y.useState)([]),[s,r]=(0,y.useState)(!0),[n,l]=(0,y.useState)(!1),[m,T]=(0,y.useState)(null),[C,P]=(0,y.useState)(null),[I,u]=(0,y.useState)(null),h=(0,y.useRef)(!1),E=(0,y.useCallback)(async(a=!1)=>{if(!(!a&&h.current)){a||(h.current=!0),r(!0);try{let d=await Y.list();t(d)}catch(d){console.error("Erreur fetchConnectors:",d),t([])}finally{r(!1),a||setTimeout(()=>{h.current=!1},1e3)}}},[]);(0,y.useEffect)(()=>{E()},[E]);let x=async a=>{l(!0),P(null),u(null);try{return await Y.save(a),await E(!0),u("Connecteur enregistr\xE9 avec succ\xE8s."),setTimeout(()=>u(null),3e3),!0}catch(d){return P(d.message||"Erreur lors de l'enregistrement du connecteur."),!1}finally{l(!1)}},i=(0,y.useCallback)(async a=>{P(null),u(null),T(a),t(d=>d.map(v=>v.source_id===a?S(b({},v),{status:"indexing"}):v));try{let d=await Y.sync(a);t(v=>v.map(R=>R.source_id===a?S(b({},R),{status:"active"}):R)),u(d.details||`Indexation lanc\xE9e pour ${a}`),setTimeout(()=>u(null),4e3)}catch(d){t(v=>v.map(R=>R.source_id===a?S(b({},R),{status:"error"}):R)),P(d.message||`L'indexation de ${a} a \xE9chou\xE9.`)}finally{T(null)}},[]);return{connectors:e,isFetching:s,isSaving:n,isIndexing:m,error:C,successMsg:I,save:x,triggerIndexing:i,refresh:()=>E(!0)}}0&&(module.exports={ChatWindow,CopilotApp,Sidebar,WidgetProvider,useChat,useConnectors,useWidgetConfig});
package/dist/index.mjs ADDED
@@ -0,0 +1,5 @@
1
+ var Te=Object.defineProperty,Ee=Object.defineProperties;var Re=Object.getOwnPropertyDescriptors;var B=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var Y=(e,t,s)=>t in e?Te(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,g=(e,t)=>{for(var s in t||(t={}))Z.call(t,s)&&Y(e,s,t[s]);if(B)for(var s of B(t))ee.call(t,s)&&Y(e,s,t[s]);return e},E=(e,t)=>Ee(e,Re(t));var D=(e,t)=>{var s={};for(var r in e)Z.call(e,r)&&t.indexOf(r)<0&&(s[r]=e[r]);if(e!=null&&B)for(var r of B(e))t.indexOf(r)<0&&ee.call(e,r)&&(s[r]=e[r]);return s};import{createContext as Se,useContext as We,useEffect as Ie,useMemo as Ae}from"react";import{jsx as Le}from"react/jsx-runtime";var te=Se(void 0);function G({children:e,config:t}){let s={primaryColor:process.env.NEXT_PUBLIC_PRIMARY_COLOR||"#2563EB",logoUrl:process.env.NEXT_PUBLIC_WIDGET_LOGO||"/logo.png",botName:process.env.NEXT_PUBLIC_WIDGET_TITLE||"Copilot RH",position:"right",apiUrl:process.env.NEXT_PUBLIC_API_URL||"http://localhost:8000",expandedDefault:!1},r=Ae(()=>g(g({},s),t),[t]);return Ie(()=>{let c=document.documentElement;c.style.setProperty("--widget-primary",r.primaryColor),c.style.setProperty("--widget-primary-light",`${r.primaryColor}15`)},[r.primaryColor]),Le(te.Provider,{value:r,children:e})}var M=()=>{let e=We(te);if(!e)throw new Error("useWidgetConfig must be used within WidgetProvider");return e};import{useState as de}from"react";import{useSearchParams as et}from"next/navigation";import{useState as Ue,useEffect as He,useSyncExternalStore as $e}from"react";import O from"next/link";import Be from"next/image";import{usePathname as je,useSearchParams as Oe}from"next/navigation";import{MessageSquare as qe,Settings as Ge,Bot as Xe,Plus as Ke,PanelLeftClose as Ve,PanelLeftOpen as Qe,Clock as Je}from"lucide-react";import{clsx as De}from"clsx";import{twMerge as Me}from"tailwind-merge";function l(...e){return Me(De(e))}function se(e){return new Intl.DateTimeFormat("fr-FR",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"}).format(e)}function X(){return`thread_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}import*as w from"@radix-ui/react-tooltip";import{jsx as F,jsxs as Fe}from"react/jsx-runtime";function re(s){var r=s,{delayDuration:e=0}=r,t=D(r,["delayDuration"]);return F(w.Provider,g({"data-slot":"tooltip-provider",delayDuration:e},t))}function oe(t){var e=D(t,[]);return F(w.Root,g({"data-slot":"tooltip"},e))}function ae(t){var e=D(t,[]);return F(w.Trigger,g({"data-slot":"tooltip-trigger"},e))}function ne(c){var i=c,{className:e,sideOffset:t=0,children:s}=i,r=D(i,["className","sideOffset","children"]);return F(w.Portal,{children:Fe(w.Content,E(g({"data-slot":"tooltip-content",sideOffset:t,className:l("z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",e)},r),{children:[s,F(w.Arrow,{className:"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground"})]}))})}import le from"axios";import{create as _e}from"zustand";var ie=_e(e=>({isNetworkError:!1,setNetworkError:t=>e({isNetworkError:t})}));var ze=process.env.PUBLIC_API_URL||"http://127.0.0.1:8000",S=le.create({baseURL:ze,timeout:6e5,headers:{"Content-Type":"application/json"}});S.interceptors.response.use(e=>e,e=>!e.response||e.code==="ERR_NETWORK"?(ie.getState().setNetworkError(!0),new Promise(()=>{})):Promise.reject(e));var W=e=>{var t,s;if(le.isAxiosError(e)){let r=((s=(t=e.response)==null?void 0:t.data)==null?void 0:s.detail)||e.message||"Erreur de connexion au serveur";throw new Error(r)}throw new Error("Une erreur inattendue est survenue")},_={sendMessage:async e=>{try{return(await S.post("/chat",e)).data}catch(t){return W(t)}},listThreads:async()=>{try{return(await S.get("/chat/threads")).data}catch(e){return W(e)}},getHistory:async e=>{try{return(await S.get(`/chat/history/${e}`)).data.map((s,r)=>({id:`${e}-${r}-${Date.now()}`,role:s.role,content:s.content,timestamp:new Date}))}catch(t){return W(t)}}},j={save:async e=>{try{return(await S.post("/connectors",e)).data}catch(t){return W(t)}},list:async()=>{try{return(await S.get("/settings/connectors")).data}catch(e){return W(e)}},sync:async e=>{try{return(await S.post(`/documents/sync/${e}`)).data}catch(t){return W(t)}}},ce={upload:async(e,t="default")=>{try{let s=new FormData;return e.forEach(c=>{s.append("files",c)}),(await S.post(`/upload?tenant_id=${t}`,s,{headers:{"Content-Type":"multipart/form-data"}})).data}catch(s){return W(s)}}};import{Fragment as Ze,jsx as a,jsxs as p}from"react/jsx-runtime";function Ye(){return $e(e=>(window.addEventListener("resize",e),()=>window.removeEventListener("resize",e)),()=>window.innerWidth<768,()=>!1)}function V({expanded:e,setExpanded:t,isEmbed:s}){let r=je(),i=Oe().get("threadId"),[m,C]=Ue([]),{botName:x,logoUrl:v}=M(),R=Ye();He(()=>{(async()=>{try{let n=await _.listThreads();C(n)}catch(n){C([])}})()},[r]);let u=()=>{(s||R)&&t(!1)};return p(re,{delayDuration:500,children:[e&&(s||R)&&a("div",{className:"fixed inset-0 bg-slate-900/20 backdrop-blur-sm z-40 transition-opacity duration-300",onClick:()=>t(!1)}),p("aside",{className:l("relative h-screen bg-white border-r border-slate-100 flex flex-col shrink-0 transition-all duration-300 ease-[cubic-bezier(0.4,0,0.2,1)] z-50",e?s?"w-full":"w-64":"w-16",(s||R)&&e?"fixed inset-y-0 left-0 shadow-2xl":"relative"),children:[p("div",{className:"flex items-center h-16 px-4 border-b border-slate-50",children:[p("div",{className:"flex items-center gap-3 overflow-hidden",children:[a("div",{className:"w-9 h-9 rounded-xl bg-blue-600 flex items-center justify-center text-white shrink-0 shadow-lg shadow-blue-200",children:a(Xe,{size:20,strokeWidth:2.5,className:l("transition-transform duration-500",e&&"rotate-[360deg]")})}),e&&p("div",{className:"flex flex-col animate-in fade-in slide-in-from-left-2 duration-300",children:[a("span",{className:"font-bold text-slate-900 leading-tight",children:x}),p("span",{className:"text-[10px] text-emerald-500 font-medium flex items-center gap-1",children:[a("span",{className:"w-1.5 h-1.5 rounded-full bg-emerald-500 animate-pulse"})," IA Active"]})]})]}),a("button",{onClick:()=>t(!e),className:"ml-auto p-2 hover:bg-slate-100 rounded-lg text-slate-400 transition-colors",children:e?a(Ve,{size:18}):a(Qe,{size:18})})]}),a("div",{className:"p-3",children:a(K,{label:"Nouveau chat",show:!e,children:p(O,{href:"/chat",onClick:u,className:l("flex items-center gap-3 bg-blue-600 text-white rounded-xl font-semibold transition-all shadow-md shadow-blue-100 hover:bg-blue-700 hover:shadow-lg active:scale-95",e?"px-4 py-3 w-full":"w-10 h-10 justify-center mx-auto"),children:[a(Ke,{size:20,strokeWidth:3}),e&&a("span",{className:"text-sm",children:"Nouvelle discussion"})]})})}),p("nav",{className:"flex flex-col gap-1 px-3 mt-2",children:[a(K,{label:"Discussions",show:!e,children:p(O,{href:"/chat",onClick:u,className:l("flex items-center gap-3 p-2.5 rounded-xl text-sm transition-all group",r.startsWith("/chat")?"bg-slate-100 text-blue-600 font-bold":"text-slate-500 hover:bg-slate-50 hover:text-slate-900"),children:[a(qe,{size:18,className:l(r.startsWith("/chat")?"text-blue-600":"text-slate-400 group-hover:text-slate-600")}),e&&a("span",{children:"Chat"})]})}),a(K,{label:"Param\xE8tres",show:!e,children:p(O,{href:"/settings",onClick:u,className:l("flex items-center gap-3 p-2.5 rounded-xl text-sm transition-all group",r==="/settings"?"bg-slate-100 text-blue-600 font-bold":"text-slate-500 hover:bg-slate-50 hover:text-slate-900"),children:[a(Ge,{size:18,className:l(r==="/settings"?"text-blue-600":"text-slate-400 group-hover:text-slate-600")}),e&&a("span",{children:"Param\xE8tres"})]})})]}),e&&p("div",{className:"flex-1 overflow-y-auto mt-6 px-3 custom-scrollbar animate-in fade-in duration-500",children:[p("div",{className:"flex items-center justify-between mb-3 px-2",children:[a("span",{className:"text-[10px] font-bold text-slate-400 uppercase tracking-widest",children:"Historique"}),a(Je,{size:10,className:"text-slate-300"})]}),a("div",{className:"flex flex-col gap-1 pb-4",children:m.length===0?a("div",{className:"px-3 py-4 border border-dashed border-slate-100 rounded-xl text-center",children:a("p",{className:"text-[10px] text-slate-400 italic",children:"Aucune discussion"})}):m.map(h=>p(O,{href:`/chat?threadId=${h.id}`,onClick:u,className:l("group relative flex flex-col gap-0.5 p-2.5 rounded-xl transition-all border border-transparent",i===h.id?"bg-blue-50/50 border-blue-100 text-blue-700 font-semibold":"text-slate-600 hover:bg-slate-50 hover:border-slate-100"),children:[i===h.id&&a("div",{className:"absolute left-0 top-2 bottom-2 w-1 bg-blue-600 rounded-r-full"}),a("span",{className:"text-[11px] truncate leading-tight",children:h.title}),p("span",{className:"text-[8px] text-slate-400 group-hover:text-blue-400 transition-colors uppercase font-medium",children:["Discussion ID: ",h.id.slice(-4)]})]},h.id))})]}),a("div",{className:"mt-auto p-4 border-t border-slate-50 bg-slate-50/30",children:p("div",{className:l("flex items-center gap-3",!e&&"justify-center"),children:[p("div",{className:"relative shrink-0",children:[a("div",{className:"w-9 h-9 rounded-full overflow-hidden border-2 border-white shadow-sm bg-slate-100 flex items-center justify-center",children:a(Be,{src:v,alt:"User Profile",width:36,height:36,className:"object-contain"})}),a("div",{className:"absolute -bottom-0.5 -right-0.5 w-3 h-3 bg-emerald-500 border-2 border-white rounded-full"})]}),e&&p("div",{className:"min-w-0 flex flex-col animate-in slide-in-from-bottom-1 duration-300",children:[a("p",{className:"text-xs font-bold text-slate-800 truncate",children:"Administrateur DHI"}),a("p",{className:"text-[10px] text-slate-400 font-medium truncate",children:"Console de Gestion"})]})]})})]})]})}function K({children:e,label:t,show:s}){return s?p(oe,{children:[a(ae,{asChild:!0,children:e}),a(ne,{side:"right",sideOffset:10,className:"bg-slate-900 text-white border-none text-[10px] px-2 py-1 shadow-xl",children:t})]}):a(Ze,{children:e})}import{jsx as me,jsxs as tt}from"react/jsx-runtime";function ue({children:e}){let s=et().get("embed")==="true",[r,c]=de(s),[i,m]=de(!s);return s!==r&&(c(s),m(!s)),tt("div",{className:"flex h-screen overflow-hidden",children:[me(V,{expanded:i,setExpanded:m,isEmbed:s}),me("main",{className:l("flex-1 overflow-hidden transition-all duration-300",s&&i?"hidden":"block"),children:e})]})}import{Suspense as st}from"react";import{jsx as q}from"react/jsx-runtime";function rt({config:e,children:t}){return q(G,{config:e,children:q(st,{fallback:q("div",{className:"h-screen bg-slate-50 animate-pulse"}),children:q(ue,{children:t})})})}import{useEffect as Ct,useRef as Pt}from"react";import{AlertCircle as kt,RotateCcw as Tt}from"lucide-react";import{Bot as at,User as nt}from"lucide-react";import it from"react-markdown";import lt from"remark-gfm";import{Bot as ot}from"lucide-react";import{jsx as A,jsxs as pe}from"react/jsx-runtime";function fe(){return pe("div",{className:"flex items-start gap-3 message-enter",children:[A("div",{className:"w-7 h-7 rounded-lg bg-blue-600 flex items-center justify-center shrink-0 mt-0.5 shadow-sm",children:A(ot,{className:"w-3.5 h-3.5 text-white",strokeWidth:2.5})}),pe("div",{className:"bg-[#F3F4F6] rounded-2xl rounded-tl-sm px-4 py-3 flex items-center gap-1.5",children:[A("span",{className:"text-xs text-slate-400 mr-1 select-none",children:"L'assistant r\xE9fl\xE9chit"}),A("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"}),A("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"}),A("span",{className:"thinking-dot w-1.5 h-1.5 bg-slate-400 rounded-full inline-block"})]})]})}import{jsx as N,jsxs as z}from"react/jsx-runtime";function ge({message:e}){let t=e.role==="user";return e.isStreaming?N(fe,{}):z("div",{className:l("flex items-start gap-3 w-full message-enter",t?"flex-row-reverse":"flex-row"),children:[N("div",{className:l("w-8 h-8 rounded-lg flex items-center justify-center shrink-0 mt-0.5 shadow-sm",t?"bg-slate-100":"bg-blue-600"),children:t?N(nt,{size:16,className:"text-slate-500"}):N(at,{size:16,className:"text-white"})}),z("div",{className:l("flex flex-col gap-2 max-w-[85%]",t?"items-end":"items-start"),children:[N("div",{className:l("rounded-2xl px-4 py-3 text-sm leading-relaxed shadow-sm",t?"bg-white border border-slate-200 text-slate-800 rounded-tr-sm":"bg-[#F3F4F6] text-slate-700 rounded-tl-sm"),children:N("div",{className:"prose-hr-chat max-w-none",children:N(it,{remarkPlugins:[lt],children:e.content})})}),!t&&e.sources&&e.sources.length>0&&z("div",{className:"mt-3 pt-3 border-t border-slate-100 w-full",children:[z("div",{className:"flex items-center gap-2 mb-2",children:[N("div",{className:"w-1 h-3 bg-blue-500 rounded-full"}),N("span",{className:"text-[10px] font-bold text-slate-400 uppercase tracking-widest",children:"Sources & Citations"})]}),N("div",{className:"flex flex-wrap gap-2",children:e.sources.map((s,r)=>z("div",{className:"group relative flex items-center gap-1.5 px-2 py-1 bg-white border border-slate-200 rounded-lg text-[10px] text-slate-600 shadow-sm hover:border-blue-300 hover:text-blue-600 transition-all cursor-default",children:[N("span",{className:"w-1 h-1 bg-slate-300 rounded-full group-hover:bg-blue-400"}),s]},r))})]}),N("span",{className:"text-[10px] text-slate-300 px-1",children:se(new Date(e.timestamp))})]})]})}import{FileSearch as ct,ClipboardList as dt,Users as mt,Coins as ut}from"lucide-react";import pt from"next/image";import{jsx as I,jsxs as U}from"react/jsx-runtime";var ft=[{icon:ut,label:"Grilles de salaires",prompt:"Montre-moi les grilles de salaires pour les ing\xE9nieurs seniors."},{icon:dt,label:"Proc\xE9dures RH",prompt:"Quelle est la proc\xE9dure pour poser des cong\xE9s pay\xE9s ?"},{icon:mt,label:"Onboarding",prompt:"Quelles sont les \xE9tapes d'onboarding pour un nouvel employ\xE9 ?"},{icon:ct,label:"R\xE8glement int\xE9rieur",prompt:"R\xE9sume les points cl\xE9s du r\xE8glement int\xE9rieur."}];function he({onSuggestion:e}){let{botName:t,logoUrl:s}=M();return U("div",{className:"flex flex-col items-center justify-center h-full gap-8 px-4 select-none",children:[U("div",{className:"flex flex-col items-center gap-3",children:[I("div",{className:"relative w-14 h-14 rounded-2xl bg-white border border-slate-100 flex items-center justify-center shadow-sm overflow-hidden p-2",children:I(pt,{src:s,alt:`${t} Logo`,width:40,height:40,priority:!0,className:"object-contain"})}),U("div",{className:"text-center",children:[U("h1",{className:"text-lg font-semibold text-slate-800",children:["Bonjour, je suis votre Copilot ",t]}),I("p",{className:"text-sm text-slate-400 mt-1",children:"Posez vos questions sur vos documents RH internes."})]})]}),I("div",{className:"grid grid-cols-2 gap-2 w-full max-w-md",children:ft.map(r=>{let c=r.icon;return U("button",{onClick:()=>e(r.prompt),className:"flex items-start gap-2.5 p-3 rounded-xl bg-white border border-slate-100 hover:border-blue-200 hover:bg-blue-50/50 text-left transition-all duration-200 shadow-sm group",children:[I("div",{className:"mt-0.5 w-6 h-6 rounded-lg bg-blue-50 group-hover:bg-blue-100 flex items-center justify-center shrink-0 transition-colors",children:I(c,{className:"w-3.5 h-3.5 text-blue-500",strokeWidth:1.8})}),I("span",{className:"text-xs font-medium text-slate-600 group-hover:text-slate-800 leading-snug transition-colors",children:r.label})]},r.label)})})]})}import{useState as be,useRef as xe,useCallback as ve}from"react";import{ArrowUp as gt,Paperclip as ht,X as bt,FileText as xt}from"lucide-react";import{jsx as y,jsxs as Q}from"react/jsx-runtime";function we({onSend:e,isLoading:t,disabled:s}){let[r,c]=be(""),[i,m]=be([]),C=xe(null),x=xe(null),v=n=>{if(n.target.files){let o=Array.from(n.target.files);m(d=>[...d,...o])}},R=n=>{m(o=>o.filter((d,b)=>b!==n))},u=ve(()=>{let n=r.trim();!n&&i.length===0||t||s||(e(n,i),c(""),m([]))},[r,i,t,s,e]),f=n=>{n.key==="Enter"&&!n.shiftKey&&(n.preventDefault(),u())},k=ve(n=>{c(n.target.value);let o=n.target;o.style.height="auto",o.style.height=`${Math.min(o.scrollHeight,160)}px`},[]),h=r.trim().length>0&&!t&&!s;return Q("div",{className:"px-4 pb-4 pt-2",children:[y("div",{className:"flex flex-wrap gap-2 mb-2",children:i.map((n,o)=>Q("div",{className:"flex items-center gap-2 px-2 py-1 bg-blue-50 border border-blue-100 rounded-lg text-[10px] text-blue-600",children:[y(xt,{className:"w-3 h-3"}),y("span",{className:"truncate max-w-[100px]",children:n.name}),y("button",{onClick:()=>R(o),className:"hover:text-red-500",children:y(bt,{className:"w-3 h-3"})})]},o))}),Q("div",{className:l("flex items-end gap-2 bg-white border rounded-2xl px-3 py-2.5 shadow-sm transition-all duration-200","border-slate-200 focus-within:border-blue-300 focus-within:shadow-[0_0_0_3px_rgba(59,130,246,0.08)]"),children:[y("input",{type:"file",ref:C,onChange:v,className:"hidden",multiple:!0,accept:".pdf,.docx,.txt,.mp3,.wav,.png,.jpg"}),y("button",{type:"button",onClick:()=>{var n;return(n=C.current)==null?void 0:n.click()},className:"p-1.5 rounded-lg text-slate-300 hover:text-slate-500 hover:bg-slate-50 transition-colors shrink-0 mb-0.5","aria-label":"Joindre un fichier",tabIndex:-1,children:y(ht,{className:"w-4 h-4",strokeWidth:1.8})}),y("textarea",{ref:x,value:r,onChange:k,onKeyDown:f,placeholder:i.length>0?"Ajouter un message au fichier...":"Posez votre question RH\u2026",rows:1,disabled:s,className:l("flex-1 resize-none bg-transparent text-sm text-slate-800 placeholder:text-slate-300","outline-none leading-relaxed py-0.5 max-h-40 min-h-[22px]","disabled:opacity-50 disabled:cursor-not-allowed"),"aria-label":"Message"}),y("button",{type:"button",onClick:u,disabled:!h,"aria-label":"Envoyer",className:l("w-8 h-8 rounded-xl flex items-center justify-center shrink-0 transition-all duration-200 mb-0.5",h?"bg-blue-600 text-white hover:bg-blue-700 shadow-sm hover:shadow":"bg-slate-100 text-slate-300 cursor-not-allowed"),children:y(gt,{className:"w-4 h-4",strokeWidth:2.5})})]}),y("p",{className:"text-center text-[10px] text-slate-300 mt-2",children:"Entr\xE9e pour envoyer \xB7 Maj+Entr\xE9e pour sauter une ligne"})]})}import{useSearchParams as Et}from"next/navigation";import{X as vt,ChevronLeft as wt}from"lucide-react";import{usePathname as Nt,useRouter as yt}from"next/navigation";import{jsx as H,jsxs as Ne}from"react/jsx-runtime";function ye({title:e="Copilot RH"}){let t=yt(),s=Nt();return Ne("header",{className:"flex items-center justify-between px-4 py-3 border-b border-slate-100 bg-white",children:[Ne("div",{className:"flex items-center gap-3",children:[s!=="/chat"&&H("button",{onClick:()=>t.back(),className:"p-1 hover:bg-slate-100 rounded-full transition-colors",children:H(wt,{size:20,className:"text-slate-600"})}),H("h2",{className:"text-sm font-bold text-slate-800",children:e})]}),H("button",{onClick:()=>window.parent.postMessage("close-dhi-copilot","*"),children:H(vt,{size:20,className:"text-slate-400 hover:text-red-500"})})]})}import{Fragment as St,jsx as P,jsxs as $}from"react/jsx-runtime";function Rt({session:e,isLoading:t,error:s,onSend:r,onReset:c}){let i=Pt(null),m=e.messages.length>0,x=Et().get("embed")==="true";return Ct(()=>{i.current&&i.current.scrollTo({top:i.current.scrollHeight,behavior:"smooth"})},[e.messages]),$("div",{className:"flex flex-col h-full bg-[#F9FAFB]",children:[x?P(ye,{}):$("header",{className:"flex items-center justify-between px-5 py-3 border-b border-slate-100 bg-white shrink-0",children:[$("div",{className:"flex items-center gap-2",children:[P("div",{className:"w-2 h-2 rounded-full bg-emerald-400"}),P("span",{className:"text-sm font-medium text-slate-700",children:m?e.title:"Copilot RH"})]}),m&&$("button",{onClick:c,className:"flex items-center gap-1.5 text-xs text-slate-400 hover:text-slate-600 transition-colors px-2 py-1 rounded-lg hover:bg-slate-50",title:"Nouvelle conversation",children:[P(Tt,{className:"w-3 h-3",strokeWidth:2}),"Nouvelle conversation"]})]}),P("div",{ref:i,className:l("flex-1 overflow-y-auto px-4 py-4",m?"flex flex-col gap-4":""),children:m?P(St,{children:e.messages.map(v=>P(ge,{message:v},v.id))}):P(he,{onSuggestion:r})}),s&&$("div",{className:"mx-4 mb-2 px-3 py-2 bg-red-50 border border-red-100 rounded-xl flex items-start gap-2",children:[P(kt,{className:"w-3.5 h-3.5 text-red-400 mt-0.5 shrink-0"}),P("p",{className:"text-xs text-red-600 leading-relaxed",children:s})]}),P(we,{onSend:r,isLoading:t})]})}import{useState as J,useCallback as Ce,useEffect as Wt}from"react";import{useSearchParams as It,useRouter as At}from"next/navigation";import{v4 as Pe}from"uuid";function Lt(){let e=It(),t=At(),s=e.get("threadId"),[r,c]=J(()=>({id:s||X(),title:"Nouvelle conversation",messages:[],createdAt:new Date,updatedAt:new Date})),[i,m]=J(!1),[C,x]=J(null);Wt(()=>{s&&s!==r.id&&(async()=>{m(!0),x(null);try{let f=await _.getHistory(s);c({id:s,title:"Conversation charg\xE9e",messages:f,createdAt:new Date,updatedAt:new Date})}catch(f){x("Impossible de charger l'historique de cette discussion.")}finally{m(!1)}})()},[s]);let v=Ce(async(u,f=[])=>{if(!u.trim()&&f.length===0||i)return;x(null),m(!0);let k=u.trim();if(f.length>0){let o=f.map(d=>`\u{1F4C4} ${d.name}`).join(`
2
+ `);k+=`
3
+
4
+ *Fichiers joints :*
5
+ ${o}`}let h={id:Pe(),role:"user",content:k,timestamp:new Date},n="loading-ai-message";c(o=>E(g({},o),{messages:[...o.messages,h,{id:n,role:"assistant",content:"",timestamp:new Date,isStreaming:!0}]}));try{f.length>0&&await ce.upload(f);let o=u.trim()||`Analyse les ${f.length} fichiers que je viens d'envoyer.`,d=await _.sendMessage({message:o,thread_id:r.id});c(b=>E(g({},b),{messages:b.messages.map(T=>T.id===n?{id:Pe(),role:"assistant",content:d.response,sources:d.sources,timestamp:new Date,isStreaming:!1}:T)})),r.messages.length===0&&t.replace(`/chat?threadId=${r.id}`)}catch(o){x(o instanceof Error?o.message:"Erreur."),c(d=>E(g({},d),{messages:d.messages.filter(b=>b.id!==n)}))}finally{m(!1)}},[i,r.id,r.messages.length,t]),R=Ce(()=>{let u=X();c({id:u,title:"Nouvelle conversation",messages:[],createdAt:new Date,updatedAt:new Date}),t.push("/chat"),x(null)},[t]);return{session:r,isLoading:i,error:C,send:v,reset:R}}import{useState as L,useCallback as ke,useEffect as Dt,useRef as Mt}from"react";function Ft(){let[e,t]=L([]),[s,r]=L(!0),[c,i]=L(!1),[m,C]=L(null),[x,v]=L(null),[R,u]=L(null),f=Mt(!1),k=ke(async(o=!1)=>{if(!(!o&&f.current)){o||(f.current=!0),r(!0);try{let d=await j.list();t(d)}catch(d){console.error("Erreur fetchConnectors:",d),t([])}finally{r(!1),o||setTimeout(()=>{f.current=!1},1e3)}}},[]);Dt(()=>{k()},[k]);let h=async o=>{i(!0),v(null),u(null);try{return await j.save(o),await k(!0),u("Connecteur enregistr\xE9 avec succ\xE8s."),setTimeout(()=>u(null),3e3),!0}catch(d){return v(d.message||"Erreur lors de l'enregistrement du connecteur."),!1}finally{i(!1)}},n=ke(async o=>{v(null),u(null),C(o),t(d=>d.map(b=>b.source_id===o?E(g({},b),{status:"indexing"}):b));try{let d=await j.sync(o);t(b=>b.map(T=>T.source_id===o?E(g({},T),{status:"active"}):T)),u(d.details||`Indexation lanc\xE9e pour ${o}`),setTimeout(()=>u(null),4e3)}catch(d){t(b=>b.map(T=>T.source_id===o?E(g({},T),{status:"error"}):T)),v(d.message||`L'indexation de ${o} a \xE9chou\xE9.`)}finally{C(null)}},[]);return{connectors:e,isFetching:s,isSaving:c,isIndexing:m,error:x,successMsg:R,save:h,triggerIndexing:n,refresh:()=>k(!0)}}export{Rt as ChatWindow,rt as CopilotApp,V as Sidebar,G as WidgetProvider,Lt as useChat,Ft as useConnectors,M as useWidgetConfig};
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "dhi-copilot-ai",
3
+ "version": "1.0.0",
4
+ "description": "Assistant RH intelligent & RAG universel",
5
+ "private": false,
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "public/widget-loader.js"
19
+ ],
20
+ "scripts": {
21
+ "dev": "next dev",
22
+ "build": "next build",
23
+ "build:lib": "tsup src/index.ts --format cjs,esm --dts --minify --clean --tsconfig tsconfig.lib.json",
24
+ "start": "next start",
25
+ "lint": "eslint"
26
+ },
27
+ "dependencies": {
28
+ "@radix-ui/react-label": "^2.1.8",
29
+ "@radix-ui/react-scroll-area": "^1.2.10",
30
+ "@radix-ui/react-select": "^2.2.6",
31
+ "@radix-ui/react-separator": "^1.1.8",
32
+ "@radix-ui/react-slot": "^1.2.4",
33
+ "@radix-ui/react-tooltip": "^1.2.8",
34
+ "@tailwindcss/typography": "^0.5.19",
35
+ "axios": "^1.13.6",
36
+ "class-variance-authority": "^0.7.1",
37
+ "clsx": "^2.1.1",
38
+ "geist": "^1.7.0",
39
+ "lucide-react": "^0.577.0",
40
+ "react-markdown": "^10.1.0",
41
+ "remark-gfm": "^4.0.1",
42
+ "tailwind-merge": "^3.5.0",
43
+ "tailwindcss-animate": "^1.0.7",
44
+ "uuid": "^13.0.0",
45
+ "zustand": "^5.0.12"
46
+ },
47
+ "peerDependencies": {
48
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0",
49
+ "react": "^18.0.0 || ^19.0.0",
50
+ "react-dom": "^18.0.0 || ^19.0.0"
51
+ },
52
+ "devDependencies": {
53
+ "@tailwindcss/postcss": "^4",
54
+ "@types/node": "^20",
55
+ "@types/react": "^19",
56
+ "@types/react-dom": "^19",
57
+ "@types/uuid": "^10.0.0",
58
+ "eslint": "^9",
59
+ "eslint-config-next": "16.1.6",
60
+ "tailwindcss": "^4",
61
+ "tsup": "^8.3.5",
62
+ "typescript": "^5"
63
+ }
64
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * DHI Copilot - Universal Widget Loader
3
+ * Version: 1.0.0
4
+ */
5
+ (function () {
6
+ const WIDGET_URL = "http://localhost:3000/chat?embed=true"; // À changer en prod
7
+ const PRIMARY_COLOR = "#2563EB";
8
+ const DEFAULT_LOGO = "https://cdn-icons-png.flaticon.com/512/4712/4712035.png";
9
+
10
+ class DHICopilot {
11
+ constructor(config = {}) {
12
+ this.config = {
13
+ userId: config.userId || null,
14
+ userToken: config.userToken || null,
15
+ userName: config.userName || "Utilisateur",
16
+ position: config.position || "right",
17
+ logoUrl: config.logoUrl || DEFAULT_LOGO,
18
+ ...config
19
+ };
20
+ this.isOpen = false;
21
+ this.init();
22
+ }
23
+
24
+ init() {
25
+ this.createStyles();
26
+ this.createWidget();
27
+ this.setupEventListeners();
28
+ }
29
+
30
+ createStyles() {
31
+ const style = document.createElement('style');
32
+ style.innerHTML = `
33
+ #dhi-widget-container { position: fixed; bottom: 20px; right: 20px; z-index: 999999; }
34
+
35
+ #dhi-bubble {
36
+ width: 64px; height: 64px; border-radius: 20px;
37
+ background: white; box-shadow: 0 8px 24px rgba(0,0,0,0.15);
38
+ cursor: pointer; position: relative;
39
+ display: flex; align-items: center; justify-content: center;
40
+ transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
41
+ border: 2px solid #f1f5f9;
42
+ }
43
+
44
+ /* Le Logo de l'entreprise */
45
+ .dhi-company-logo {
46
+ width: 80%; height: 80%; object-fit: contain; border-radius: 12px;
47
+ }
48
+
49
+ /* Le Badge Robot en haut à droite */
50
+ .dhi-robot-badge {
51
+ position: absolute; top: -8px; right: -8px;
52
+ width: 24px; height: 24px; background: #2563EB;
53
+ border-radius: 8px; border: 2px solid white;
54
+ display: flex; align-items: center; justify-content: center;
55
+ box-shadow: 0 2px 8px rgba(37, 99, 235, 0.4);
56
+ }
57
+ .dhi-robot-badge svg { width: 14px; height: 14px; fill: white; }
58
+
59
+ #dhi-sidebar {
60
+ position: fixed; top: 0; right: -420px;
61
+ width: 400px; height: 100vh; background: white;
62
+ box-shadow: -10px 0 40px rgba(0,0,0,0.1);
63
+ transition: right 0.4s cubic-bezier(0.05, 0.7, 0.1, 1);
64
+ z-index: 999998;
65
+ }
66
+ #dhi-sidebar.open { right: 0; }
67
+ #dhi-iframe { border: none; width: 100%; height: 100%; }
68
+ `;
69
+ document.head.appendChild(style);
70
+ }
71
+
72
+ createWidget() {
73
+ const logoHtml = this.config.logoUrl
74
+ ? `<img src="${this.config.logoUrl}" class="dhi-company-logo" />`
75
+ : `<svg viewBox="0 0 24 24" class="dhi-company-logo" style="fill:#2563EB"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>`;
76
+
77
+ this.container = document.createElement('div');
78
+ this.container.id = 'dhi-widget-container';
79
+ this.container.innerHTML = `
80
+ <div id="dhi-bubble">
81
+ ${logoHtml}
82
+ <div class="dhi-robot-badge">
83
+ <svg viewBox="0 0 24 24"><path d="M19 8h-1V7c0-1.1-.9-2-2-2h-3V3h-2v2H8c-1.1 0-2 .9-2 2v1H5c-1.1 0-2 .9-2 2v2h2v1h-2v2h2v1c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2v-1h2v-2h-2v-1h2v-2c0-1.1-.9-2-2-2zM9 9h2v2H9V9zm4 4H7v-2h6v2zm2-2h-2V9h2v2z"/></svg>
84
+ </div>
85
+ </div>
86
+ `;
87
+
88
+ // Sidebar Iframe
89
+ this.sidebar = document.createElement('div');
90
+ this.sidebar.id = 'dhi-sidebar';
91
+ this.sidebar.innerHTML = `
92
+ <iframe id="dhi-iframe" src="${WIDGET_URL}"></iframe>
93
+ `;
94
+
95
+ document.body.appendChild(this.container);
96
+ document.body.appendChild(this.sidebar);
97
+ }
98
+
99
+ setupEventListeners() {
100
+ // Toggle au clic sur la bulle
101
+ document.getElementById('dhi-bubble').addEventListener('click', () => this.toggle());
102
+
103
+ // Écouter les messages venant de l'Iframe (ex: fermeture, login requis)
104
+ window.addEventListener('message', (event) => {
105
+ if (event.data === 'close-dhi-copilot') {
106
+ this.close();
107
+ }
108
+ if (event.data.type === 'GET_IDENTITY_READY') {
109
+ this.sendIdentity();
110
+ }
111
+ });
112
+ }
113
+
114
+ toggle() {
115
+ this.isOpen ? this.close() : this.open();
116
+ }
117
+
118
+ open() {
119
+ this.isOpen = true;
120
+ this.sidebar.classList.add('open');
121
+
122
+ // 1. On injecte la config visuelle via l'URL (instantané)
123
+ const params = new URLSearchParams({
124
+ embed: "true",
125
+ primaryColor: this.config.primaryColor,
126
+ botName: this.config.botName,
127
+ logoUrl: this.config.logoUrl
128
+ }).toString();
129
+
130
+ const iframe = document.getElementById('dhi-iframe');
131
+
132
+ // On ne change la source que si elle n'est pas déjà chargée
133
+ if (!iframe.src || iframe.src === 'about:blank') {
134
+ iframe.src = `${WIDGET_URL}&${params}`;
135
+ }
136
+
137
+ // 2. L'identité est envoyée via postMessage, mais on attend que l'iframe dise "Je suis prêt"
138
+ // Note: Votre composant LayoutClientWrapper ou useIdentity doit envoyer 'GET_IDENTITY_READY'
139
+ }
140
+
141
+ close() {
142
+ this.isOpen = false;
143
+ this.sidebar.classList.remove('open');
144
+ }
145
+
146
+ sendIdentity() {
147
+ const iframe = document.getElementById('dhi-iframe');
148
+ if (iframe && iframe.contentWindow) {
149
+ console.log("📤 Envoi de l'identité au widget...");
150
+ iframe.contentWindow.postMessage({
151
+ type: 'SET_IDENTITY',
152
+ userId: this.config.userId,
153
+ userName: this.config.userName,
154
+ token: this.config.userToken
155
+ }, '*');
156
+ }
157
+ }
158
+ }
159
+
160
+ // Exposer l'objet globalement
161
+ window.DHICopilot = {
162
+ init: (config) => new DHICopilot(config)
163
+ };
164
+ })();