@banbox/chat 1.0.8 → 1.0.9

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 (42) hide show
  1. package/dist/index.cjs +1166 -202
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +11 -1
  4. package/dist/index.d.ts +11 -1
  5. package/dist/index.js +1090 -127
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/chat/InboxPopup.tsx +30 -19
  9. package/src/chat/SinglePopup.tsx +59 -14
  10. package/src/icons/index.tsx +55 -0
  11. package/src/index.ts +14 -12
  12. package/src/modals/ChatAddressModal.tsx +844 -0
  13. package/src/modals/{chat/ChatConfirmModal.tsx → ChatConfirmModal.tsx} +2 -2
  14. package/src/modals/ChatTranslateSettingsModal.tsx +182 -0
  15. package/src/styles/index.build.css +15 -0
  16. package/src/styles/index.css +10 -2
  17. package/src/ui/{chat/AttachmentPreviewStrip.tsx → AttachmentPreviewStrip.tsx} +2 -2
  18. package/src/ui/{chat/ChatComposerBar.tsx → ChatComposerBar.tsx} +2 -2
  19. package/src/ui/{chat/ChatFooter.tsx → ChatFooter.tsx} +102 -8
  20. package/src/ui/{chat/ChatIdentity.tsx → ChatIdentity.tsx} +2 -2
  21. package/src/ui/{chat/ChatInquiryBar.tsx → ChatInquiryBar.tsx} +1 -1
  22. package/src/ui/ChatKebabMenu.tsx +125 -0
  23. package/src/ui/{chat/ChatListHeader.tsx → ChatListHeader.tsx} +1 -1
  24. package/src/ui/{chat/ChatMessageItem.tsx → ChatMessageItem.tsx} +1 -1
  25. package/src/ui/{chat/ChatScroll.tsx → ChatScroll.tsx} +1 -1
  26. package/src/ui/{chat/ChatSpinner.tsx → ChatSpinner.tsx} +1 -1
  27. package/src/ui/{chat/ChatThreadItem.tsx → ChatThreadItem.tsx} +1 -1
  28. package/src/ui/{chat/MessageHoverActions.tsx → MessageHoverActions.tsx} +2 -2
  29. package/src/ui/{chat/ReplyCard.tsx → ReplyCard.tsx} +2 -2
  30. package/src/ui/{chat/TypingIndicator.tsx → TypingIndicator.tsx} +1 -1
  31. package/src/ui/{chat/drop-up → drop-up}/BusinessCardDropup.tsx +15 -3
  32. package/src/ui/{chat/drop-up → drop-up}/EmojiDropup.tsx +1 -1
  33. package/src/ui/{chat/message-items → message-items}/ChatAddressCard.tsx +4 -4
  34. package/src/ui/{chat/message-items → message-items}/ChatBubbleFiles.tsx +1 -1
  35. package/src/ui/{chat/message-items → message-items}/ChatBubbleImages.tsx +2 -2
  36. package/src/ui/{chat/message-items → message-items}/ChatBusinessCard.tsx +1 -1
  37. package/src/ui/{chat/scrollToMessage.ts → scrollToMessage.ts} +1 -1
  38. package/src/ui/{chat/types.ts → types.ts} +2 -2
  39. package/src/modals/chat/ChatTranslateSettingsModal.tsx +0 -180
  40. /package/src/ui/{chat/ChatHeader.tsx → ChatHeader.tsx} +0 -0
  41. /package/src/ui/{chat/message-items → message-items}/ChatBubbleAudio.tsx +0 -0
  42. /package/src/ui/{chat/message-items → message-items}/ChatBubbleText.tsx +0 -0
@@ -3,9 +3,9 @@
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { createPortal } from "react-dom";
5
5
 
6
- import { BusinessInfoIcon, ChatMailIcon, ChatPhoneCallIcon, ChatXIcon } from "../../../icons";
6
+ import { BusinessInfoIcon, ChatMailIcon, ChatPhoneCallIcon, ChatXIcon } from "../../icons";
7
7
 
8
- import { cn } from "../../../utils/cn";
8
+ import { cn } from "../../utils/cn";
9
9
  import type { BusinessCard } from "../types";
10
10
 
11
11
  /* =======================
@@ -19,6 +19,8 @@ type BusinessCardDropupProps = {
19
19
  /** Position against this button (like EmojiDropup) */
20
20
  anchorRef?: React.RefObject<HTMLElement | null>;
21
21
  className?: string;
22
+ /** Called when the Edit button is clicked — opens business info modal */
23
+ onEdit?: () => void;
22
24
  };
23
25
 
24
26
  /* =======================
@@ -49,6 +51,7 @@ const BusinessCardDropup = ({
49
51
  onSend,
50
52
  anchorRef,
51
53
  className,
54
+ onEdit,
52
55
  }: BusinessCardDropupProps) => {
53
56
  const panelRef = useRef<HTMLDivElement | null>(null);
54
57
  const [pos, setPos] = useState<{ left: number; top: number } | null>(null);
@@ -233,7 +236,16 @@ const BusinessCardDropup = ({
233
236
 
234
237
  {/* Footer actions */}
235
238
  <div className="mt-3 flex justify-end gap-2">
236
-
239
+ <button
240
+ type="button"
241
+ onClick={() => {
242
+ onClose();
243
+ onEdit?.();
244
+ }}
245
+ className="h-[34px] cursor-pointer rounded-[4px] border border-[#d1d5db] bg-white px-4 text-[13px] font-medium text-black hover:bg-[#f9fafb]"
246
+ >
247
+ Edit
248
+ </button>
237
249
  <button
238
250
  type="button"
239
251
  disabled={disabled}
@@ -98,7 +98,7 @@ const EmojiDropup: React.FC<Props> = ({ open, onClose, onSelect, anchorRef, clas
98
98
  aria-label="Emoji picker"
99
99
  className={clsx("emoji-dropup", className)}
100
100
  style={{
101
- zIndex: "9999",
101
+ zIndex: 99999, // Must be above chat panel z-index (10002)
102
102
  width: WIDTH,
103
103
  left: pos?.left ?? -9999,
104
104
  top: pos?.top ?? -9999,
@@ -1,12 +1,12 @@
1
- // components/ui/chat/message-items/ChatAddressCard.tsx
1
+ // ui/message-items/ChatAddressCard.tsx
2
2
  "use client";
3
3
 
4
4
  import clsx from "clsx";
5
5
  import React from "react";
6
6
 
7
- import { ChatPhoneCallIcon, BadgeHomeIcon, MapPinIcon } from "../../../icons";
8
- import { BadgeOfficeIcon } from "../../../icons";
9
- import { cn } from "../../../utils/cn";
7
+ import { ChatPhoneCallIcon, BadgeHomeIcon, MapPinIcon } from "../../icons";
8
+ import { BadgeOfficeIcon } from "../../icons";
9
+ import { cn } from "../../utils/cn";
10
10
  import type { AddressCard } from "../types";
11
11
 
12
12
  type Props = {
@@ -1,6 +1,6 @@
1
1
  import clsx from "clsx";
2
2
  import React from "react";
3
- import { FileDownloadIcon, FileIcon } from "../../../icons";
3
+ import { FileDownloadIcon, FileIcon } from "../../icons";
4
4
 
5
5
  export type ChatFile = {
6
6
  /** Visible filename */
@@ -1,9 +1,9 @@
1
- // components/ui/chat/message-items/ChatBubbleImages.tsx
1
+ // ui/message-items/ChatBubbleImages.tsx
2
2
  "use client";
3
3
 
4
4
  import React from "react";
5
5
 
6
- import { useGallery } from "../../../contexts/GalleryContext";
6
+ import { useGallery } from "../../contexts/GalleryContext";
7
7
 
8
8
  type ImgTileProps = {
9
9
  src: string;
@@ -3,7 +3,7 @@
3
3
  import clsx from "clsx";
4
4
  import React from "react";
5
5
 
6
- import { BusinessInfoIcon, ChatMailIcon, ChatPhoneCallIcon } from "../../../icons";
6
+ import { BusinessInfoIcon, ChatMailIcon, ChatPhoneCallIcon } from "../../icons";
7
7
  import type { BusinessCard } from "../types";
8
8
 
9
9
  // const AVATAR_SIZE = 60; // uncomment if avatar section is re-enabled
@@ -1,4 +1,4 @@
1
- // components/chat/ui/chat/scrollToMessage.ts
1
+ // ui/scrollToMessage.ts
2
2
  export function scrollToMessageById(messageId: string) {
3
3
  if (!messageId) {
4
4
  return;
@@ -1,5 +1,5 @@
1
- // components/chat/ui/chat/types.ts
2
- import type { MessageAudio, MessageFile } from "../../types";
1
+ // ui/types.ts
2
+ import type { MessageAudio, MessageFile } from "../types";
3
3
 
4
4
  // Re-export global types so UI components can import from this local file
5
5
  export type { MessageAudio as ChatAudio, MessageFile as ChatFile };
@@ -1,180 +0,0 @@
1
- "use client";
2
-
3
- import clsx from "clsx";
4
- import React, { useState } from "react";
5
- import { createPortal } from "react-dom";
6
-
7
- import { ChatInfoIcon } from "../../icons";
8
- import Button from "../../ui/Button";
9
- import Select from "../../ui/Select";
10
-
11
- /* ───────── Types ───────── */
12
-
13
- export type TranslateSettings = {
14
- incomingTarget?: string;
15
- autoIncoming: boolean;
16
- enableOutgoing: boolean;
17
- outgoingFrom: string;
18
- outgoingTo: string;
19
- };
20
-
21
- type Props = {
22
- open: boolean;
23
- onClose: () => void;
24
- onSave: (settings: TranslateSettings) => void;
25
- initial?: Partial<TranslateSettings>;
26
- className?: string;
27
- /** Controls layout / placement */
28
- variant?: "single" | "group";
29
- };
30
-
31
- /* Language options */
32
- const LANG_OPTIONS = [
33
- "English",
34
- "Bangla",
35
- "Arabic",
36
- "Chinese",
37
- "French",
38
- "German",
39
- "Hindi",
40
- "Italian",
41
- "Japanese",
42
- "Korean",
43
- "Portuguese",
44
- "Russian",
45
- "Spanish",
46
- "Turkish",
47
- "Urdu",
48
- ].map((l) => ({ label: l, value: l }));
49
-
50
- const ChatTranslateSettingsModal: React.FC<Props> = ({
51
- open,
52
- onClose,
53
- onSave,
54
- initial,
55
- className,
56
- variant = "group",
57
- }) => {
58
- const [incomingTarget, setIncomingTarget] = useState(
59
- initial?.incomingTarget ?? "",
60
- );
61
-
62
- // ESC to close
63
- React.useEffect(() => {
64
- if (!open) return;
65
- const onKey = (e: KeyboardEvent) => {
66
- if (e.key === "Escape") onClose();
67
- };
68
- window.addEventListener("keydown", onKey);
69
- return () => window.removeEventListener("keydown", onKey);
70
- }, [open, onClose]);
71
-
72
- if (!open) return null;
73
-
74
- const isSingle = variant === "single";
75
-
76
- const handleSave = () => {
77
- onSave({
78
- incomingTarget,
79
- autoIncoming: true,
80
- enableOutgoing: false,
81
- outgoingFrom: "English",
82
- outgoingTo: "Bangla",
83
- });
84
- };
85
-
86
- const content = (
87
- <div
88
- className={clsx(
89
- isSingle
90
- ? "fixed inset-0 z-9999 flex"
91
- : "absolute inset-0 z-50 flex items-center justify-center",
92
- )}
93
- onClick={() => onClose()}
94
- >
95
- {/* Backdrop */}
96
- <div className={isSingle ? "fixed inset-0 bg-black/30" : "absolute inset-0 bg-black/30"} />
97
-
98
- <div
99
- role="dialog"
100
- aria-modal="true"
101
- aria-labelledby="translate-settings-title"
102
- onClick={(e) => e.stopPropagation()}
103
- className={clsx(
104
- isSingle
105
- ? "fixed bottom-6 right-6 w-[500px] max-w-[95vw]"
106
- : "relative w-[500px] max-w-[95vw]",
107
- "z-10000 overflow-visible rounded-md bg-white shadow-[0_12px_30px_rgba(0,0,0,0.18)]",
108
- className,
109
- )}
110
- >
111
- {/* Header */}
112
- <div className="flex h-[44px] w-full items-center rounded-t-md bg-[#f8f8f8] px-6 py-[7px] shadow-[0px_2px_2px_rgba(47,47,47,0.08)]">
113
- <h2
114
- id="translate-settings-title"
115
- className="w-full text-[20px] font-semibold text-black"
116
- >
117
- Translation Settings
118
- </h2>
119
- </div>
120
-
121
- {/* Body */}
122
- <div className="p-4">
123
- <div className="grid gap-2">
124
- <span className="text-[12px] font-medium text-black">
125
- Translate message into
126
- </span>
127
-
128
- <Select
129
- options={LANG_OPTIONS}
130
- value={incomingTarget}
131
- onChange={setIncomingTarget}
132
- placeholder="Select Language"
133
- size={36}
134
- />
135
- </div>
136
-
137
- <div className="mt-6 flex items-start gap-1.5 text-[#FF5300]">
138
- <ChatInfoIcon className="h-4 w-4 shrink-0" />
139
- <p className="text-xs leading-relaxed">
140
- Automatically translate incoming messages. The language you save
141
- here will be used to display all incoming messages. You can choose
142
- from Spanish, Russian, French, Arabic, Portuguese, Turkish, Bangla,
143
- and among others.
144
- </p>
145
- </div>
146
- </div>
147
-
148
- {/* Footer */}
149
- <div className="flex h-[52px] items-center justify-end rounded-b-md bg-[#f8f8f8] px-6">
150
- <div className="flex items-center gap-3">
151
- <Button
152
- onClick={onClose}
153
- variant="outlined"
154
- color="black"
155
- size="34"
156
- >
157
- Cancel
158
- </Button>
159
- <Button
160
- onClick={handleSave}
161
- variant="filled"
162
- color="black"
163
- size="34"
164
- >
165
- Update
166
- </Button>
167
- </div>
168
- </div>
169
- </div>
170
- </div>
171
- );
172
-
173
- if (isSingle) {
174
- return createPortal(content, document.body);
175
- }
176
-
177
- return content;
178
- };
179
-
180
- export default ChatTranslateSettingsModal;
File without changes