@dilipod/ui 0.4.24 → 0.4.25
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/dist/components/support-chat.d.ts +28 -0
- package/dist/components/support-chat.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/support-chat.tsx +236 -0
- package/src/index.ts +4 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import * as React51 from 'react';
|
|
3
|
-
import { lazy, useMemo, useState, useRef, Suspense } from 'react';
|
|
3
|
+
import { lazy, useMemo, useState, useRef, useCallback, useEffect, Suspense } from 'react';
|
|
4
4
|
import { MarkerType, useNodesState, useEdgesState, ReactFlow, Background, Handle, Position } from '@xyflow/react';
|
|
5
5
|
import '@xyflow/react/dist/style.css';
|
|
6
6
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -451,6 +451,7 @@ __export(index_exports, {
|
|
|
451
451
|
Stat: () => Stat,
|
|
452
452
|
StepDots: () => StepDots,
|
|
453
453
|
StepProgress: () => StepProgress,
|
|
454
|
+
SupportChat: () => SupportChat,
|
|
454
455
|
Switch: () => Switch,
|
|
455
456
|
Table: () => Table,
|
|
456
457
|
TableBody: () => TableBody,
|
|
@@ -4867,6 +4868,135 @@ function ActivityTimeline({
|
|
|
4867
4868
|
] })
|
|
4868
4869
|
] });
|
|
4869
4870
|
}
|
|
4871
|
+
function formatMessageTime(dateStr) {
|
|
4872
|
+
const d = new Date(dateStr);
|
|
4873
|
+
const now = /* @__PURE__ */ new Date();
|
|
4874
|
+
const diffMs = now.getTime() - d.getTime();
|
|
4875
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
4876
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
4877
|
+
if (diffMins < 1) return "just now";
|
|
4878
|
+
if (diffMins < 60) return `${diffMins}m ago`;
|
|
4879
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
4880
|
+
return d.toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
4881
|
+
}
|
|
4882
|
+
function SupportChat({
|
|
4883
|
+
messagesEndpoint,
|
|
4884
|
+
sendEndpoint,
|
|
4885
|
+
currentRole,
|
|
4886
|
+
pollInterval = 5e3,
|
|
4887
|
+
placeholder = "Type a message...",
|
|
4888
|
+
emptyMessage = "No messages yet. Start the conversation!",
|
|
4889
|
+
className = ""
|
|
4890
|
+
}) {
|
|
4891
|
+
const [messages, setMessages] = useState([]);
|
|
4892
|
+
const [loading, setLoading] = useState(true);
|
|
4893
|
+
const [sending, setSending] = useState(false);
|
|
4894
|
+
const [inputValue, setInputValue] = useState("");
|
|
4895
|
+
const scrollRef = useRef(null);
|
|
4896
|
+
const prevMessageCountRef = useRef(0);
|
|
4897
|
+
const fetchMessages = useCallback(async () => {
|
|
4898
|
+
try {
|
|
4899
|
+
const res = await fetch(messagesEndpoint);
|
|
4900
|
+
if (!res.ok) return;
|
|
4901
|
+
const data = await res.json();
|
|
4902
|
+
setMessages(data.messages || []);
|
|
4903
|
+
} catch {
|
|
4904
|
+
} finally {
|
|
4905
|
+
setLoading(false);
|
|
4906
|
+
}
|
|
4907
|
+
}, [messagesEndpoint]);
|
|
4908
|
+
useEffect(() => {
|
|
4909
|
+
fetchMessages();
|
|
4910
|
+
if (pollInterval > 0) {
|
|
4911
|
+
const interval = setInterval(fetchMessages, pollInterval);
|
|
4912
|
+
return () => clearInterval(interval);
|
|
4913
|
+
}
|
|
4914
|
+
}, [fetchMessages, pollInterval]);
|
|
4915
|
+
useEffect(() => {
|
|
4916
|
+
if (messages.length > prevMessageCountRef.current) {
|
|
4917
|
+
scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth" });
|
|
4918
|
+
}
|
|
4919
|
+
prevMessageCountRef.current = messages.length;
|
|
4920
|
+
}, [messages.length]);
|
|
4921
|
+
const handleSend = async () => {
|
|
4922
|
+
const content = inputValue.trim();
|
|
4923
|
+
if (!content || sending) return;
|
|
4924
|
+
setSending(true);
|
|
4925
|
+
setInputValue("");
|
|
4926
|
+
const optimisticMsg = {
|
|
4927
|
+
id: `temp-${Date.now()}`,
|
|
4928
|
+
role: currentRole,
|
|
4929
|
+
content,
|
|
4930
|
+
type: "message",
|
|
4931
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
4932
|
+
};
|
|
4933
|
+
setMessages((prev) => [...prev, optimisticMsg]);
|
|
4934
|
+
try {
|
|
4935
|
+
const res = await fetch(sendEndpoint, {
|
|
4936
|
+
method: "POST",
|
|
4937
|
+
headers: { "Content-Type": "application/json" },
|
|
4938
|
+
body: JSON.stringify({ content })
|
|
4939
|
+
});
|
|
4940
|
+
if (res.ok) {
|
|
4941
|
+
await fetchMessages();
|
|
4942
|
+
} else {
|
|
4943
|
+
setMessages((prev) => prev.filter((m) => m.id !== optimisticMsg.id));
|
|
4944
|
+
}
|
|
4945
|
+
} catch {
|
|
4946
|
+
setMessages((prev) => prev.filter((m) => m.id !== optimisticMsg.id));
|
|
4947
|
+
} finally {
|
|
4948
|
+
setSending(false);
|
|
4949
|
+
}
|
|
4950
|
+
};
|
|
4951
|
+
const handleKeyDown = (e) => {
|
|
4952
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
4953
|
+
e.preventDefault();
|
|
4954
|
+
handleSend();
|
|
4955
|
+
}
|
|
4956
|
+
};
|
|
4957
|
+
if (loading) {
|
|
4958
|
+
return /* @__PURE__ */ jsx("div", { className: `flex items-center justify-center py-8 ${className}`, children: /* @__PURE__ */ jsx(CircleNotch, { className: "w-5 h-5 animate-spin text-muted-foreground" }) });
|
|
4959
|
+
}
|
|
4960
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex flex-col ${className}`, children: [
|
|
4961
|
+
/* @__PURE__ */ jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto space-y-3 mb-4 max-h-[400px] min-h-[200px] px-1", children: messages.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full text-sm text-muted-foreground py-8", children: typeof emptyMessage === "string" ? /* @__PURE__ */ jsx("p", { children: emptyMessage }) : emptyMessage }) : messages.map((msg) => {
|
|
4962
|
+
if (msg.type === "event" || msg.role === "system") {
|
|
4963
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxs("div", { className: "bg-gray-50 border border-gray-100 rounded-full px-3 py-1 text-xs text-muted-foreground max-w-[90%] text-center", children: [
|
|
4964
|
+
msg.content,
|
|
4965
|
+
/* @__PURE__ */ jsx("span", { className: "ml-2 opacity-60", children: formatMessageTime(msg.created_at) })
|
|
4966
|
+
] }) }, msg.id);
|
|
4967
|
+
}
|
|
4968
|
+
const isCurrentUser = msg.role === currentRole;
|
|
4969
|
+
return /* @__PURE__ */ jsx("div", { className: `flex ${isCurrentUser ? "justify-end" : "justify-start"}`, children: /* @__PURE__ */ jsxs("div", { className: `max-w-[80%] rounded-lg px-3 py-2 ${isCurrentUser ? "bg-[var(--cyan)] text-white" : "bg-gray-100 text-[var(--black)]"}`, children: [
|
|
4970
|
+
!isCurrentUser && /* @__PURE__ */ jsx("p", { className: "text-xs font-medium mb-0.5 opacity-70", children: msg.role === "admin" ? "Dilipod Team" : "You" }),
|
|
4971
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm whitespace-pre-wrap", children: msg.content }),
|
|
4972
|
+
/* @__PURE__ */ jsx("p", { className: `text-[10px] mt-1 ${isCurrentUser ? "text-white/60" : "text-muted-foreground"}`, children: formatMessageTime(msg.created_at) })
|
|
4973
|
+
] }) }, msg.id);
|
|
4974
|
+
}) }),
|
|
4975
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 border-t border-gray-100 pt-3", children: [
|
|
4976
|
+
/* @__PURE__ */ jsx(
|
|
4977
|
+
Textarea,
|
|
4978
|
+
{
|
|
4979
|
+
value: inputValue,
|
|
4980
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
4981
|
+
onKeyDown: handleKeyDown,
|
|
4982
|
+
placeholder,
|
|
4983
|
+
rows: 1,
|
|
4984
|
+
className: "resize-none min-h-[36px] py-2 flex-1"
|
|
4985
|
+
}
|
|
4986
|
+
),
|
|
4987
|
+
/* @__PURE__ */ jsx(
|
|
4988
|
+
Button,
|
|
4989
|
+
{
|
|
4990
|
+
onClick: handleSend,
|
|
4991
|
+
disabled: sending || !inputValue.trim(),
|
|
4992
|
+
size: "sm",
|
|
4993
|
+
className: "flex-shrink-0 h-9",
|
|
4994
|
+
children: sending ? /* @__PURE__ */ jsx(CircleNotch, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsx(PaperPlaneTilt, { className: "w-4 h-4", weight: "bold" })
|
|
4995
|
+
}
|
|
4996
|
+
)
|
|
4997
|
+
] })
|
|
4998
|
+
] });
|
|
4999
|
+
}
|
|
4870
5000
|
|
|
4871
5001
|
// src/index.ts
|
|
4872
5002
|
init_workflow_flow();
|
|
@@ -6610,6 +6740,6 @@ function WorkerSpec({ documentation, className }) {
|
|
|
6610
6740
|
// src/index.ts
|
|
6611
6741
|
__reExport(index_exports, icons_exports);
|
|
6612
6742
|
|
|
6613
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityTimeline, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarFallback, AvatarImage, Badge, BreadcrumbLink, Breadcrumbs, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CodeBlock, ConfirmDialog, DateRangePicker, DateRangeSelect, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Divider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorState, FilePreview, FlowchartDiagram, FormField, IconBox, ImpactMetricsForm, Input, Label2 as Label, LabeledSlider, LabeledSwitch, Logo, Metric, MetricCard, MetricLabel, MetricSubtext, MetricValue, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupCard, RadioGroupItem, RadioGroupOption, ScenariosManager, Select, Separator2 as Separator, SettingsNav, SettingsNavLink, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SimplePagination, SimpleTooltip, Skeleton, SkeletonCard, SkeletonText, Slider, Stat, StepDots, StepProgress, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsListUnderline, TabsTrigger, TabsTriggerUnderline, Tag, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastIcon, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger, UsageBar, UsageChart, WorkerSpec, WorkflowFlow, WorkflowViewer, alertVariants, badgeVariants, buttonVariants, cn, getDateRangeFromPreset, iconBoxVariants, metricCardVariants, navigationMenuTriggerStyle, progressVariants, statVariants, tagVariants, toast, usageBarVariants, useToast, valueVariants };
|
|
6743
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityTimeline, Alert, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Avatar, AvatarFallback, AvatarImage, Badge, BreadcrumbLink, Breadcrumbs, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CodeBlock, ConfirmDialog, DateRangePicker, DateRangeSelect, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Divider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, ErrorState, FilePreview, FlowchartDiagram, FormField, IconBox, ImpactMetricsForm, Input, Label2 as Label, LabeledSlider, LabeledSwitch, Logo, Metric, MetricCard, MetricLabel, MetricSubtext, MetricValue, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupCard, RadioGroupItem, RadioGroupOption, ScenariosManager, Select, Separator2 as Separator, SettingsNav, SettingsNavLink, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SimplePagination, SimpleTooltip, Skeleton, SkeletonCard, SkeletonText, Slider, Stat, StepDots, StepProgress, SupportChat, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsListUnderline, TabsTrigger, TabsTriggerUnderline, Tag, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastIcon, ToastProvider, ToastTitle, ToastViewport, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipProvider, TooltipTrigger, UsageBar, UsageChart, WorkerSpec, WorkflowFlow, WorkflowViewer, alertVariants, badgeVariants, buttonVariants, cn, getDateRangeFromPreset, iconBoxVariants, metricCardVariants, navigationMenuTriggerStyle, progressVariants, statVariants, tagVariants, toast, usageBarVariants, useToast, valueVariants };
|
|
6614
6744
|
//# sourceMappingURL=index.mjs.map
|
|
6615
6745
|
//# sourceMappingURL=index.mjs.map
|