@myrjfa/ui 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 (55) hide show
  1. package/dist/chat/ChatMain.d.ts +9 -0
  2. package/dist/chat/ChatMain.d.ts.map +1 -0
  3. package/dist/chat/ChatMain.js +239 -0
  4. package/dist/chat/ChatSidebar.d.ts +13 -0
  5. package/dist/chat/ChatSidebar.d.ts.map +1 -0
  6. package/dist/chat/ChatSidebar.js +24 -0
  7. package/dist/chat/ConversationList.d.ts +12 -0
  8. package/dist/chat/ConversationList.d.ts.map +1 -0
  9. package/dist/chat/ConversationList.js +68 -0
  10. package/dist/chat/ExpensePanel.d.ts +8 -0
  11. package/dist/chat/ExpensePanel.d.ts.map +1 -0
  12. package/dist/chat/ExpensePanel.js +215 -0
  13. package/dist/chat/MessageBubble.d.ts +15 -0
  14. package/dist/chat/MessageBubble.d.ts.map +1 -0
  15. package/dist/chat/MessageBubble.js +197 -0
  16. package/dist/chat/MessageInput.d.ts +14 -0
  17. package/dist/chat/MessageInput.d.ts.map +1 -0
  18. package/dist/chat/MessageInput.js +235 -0
  19. package/dist/chat/MilestonePanel.d.ts +8 -0
  20. package/dist/chat/MilestonePanel.d.ts.map +1 -0
  21. package/dist/chat/MilestonePanel.js +173 -0
  22. package/dist/chat/dialogs/AddMemberDialog.d.ts +10 -0
  23. package/dist/chat/dialogs/AddMemberDialog.d.ts.map +1 -0
  24. package/dist/chat/dialogs/AddMemberDialog.js +110 -0
  25. package/dist/chat/dialogs/CameraDialog.d.ts +8 -0
  26. package/dist/chat/dialogs/CameraDialog.d.ts.map +1 -0
  27. package/dist/chat/dialogs/CameraDialog.js +128 -0
  28. package/dist/chat/dialogs/GroupInfoDialog.d.ts +10 -0
  29. package/dist/chat/dialogs/GroupInfoDialog.d.ts.map +1 -0
  30. package/dist/chat/dialogs/GroupInfoDialog.js +108 -0
  31. package/dist/chat/dialogs/GroupInfoViewDialog.d.ts +9 -0
  32. package/dist/chat/dialogs/GroupInfoViewDialog.d.ts.map +1 -0
  33. package/dist/chat/dialogs/GroupInfoViewDialog.js +16 -0
  34. package/dist/chat/dialogs/NewChatDialog.d.ts +2 -0
  35. package/dist/chat/dialogs/NewChatDialog.d.ts.map +1 -0
  36. package/dist/chat/dialogs/NewChatDialog.js +127 -0
  37. package/dist/chat/dialogs/NewGroupDialog.d.ts +2 -0
  38. package/dist/chat/dialogs/NewGroupDialog.d.ts.map +1 -0
  39. package/dist/chat/dialogs/NewGroupDialog.js +112 -0
  40. package/dist/chat/dialogs/ParticipantsDialog.d.ts +11 -0
  41. package/dist/chat/dialogs/ParticipantsDialog.d.ts.map +1 -0
  42. package/dist/chat/dialogs/ParticipantsDialog.js +143 -0
  43. package/dist/chat/index.d.ts +8 -0
  44. package/dist/chat/index.d.ts.map +1 -0
  45. package/dist/chat/index.js +7 -0
  46. package/dist/header/nav-item.d.ts +2 -1
  47. package/dist/header/nav-item.d.ts.map +1 -1
  48. package/dist/header/nav-item.js +2 -2
  49. package/dist/main/navbar.d.ts.map +1 -1
  50. package/dist/main/navbar.js +2 -2
  51. package/dist/misc/command.d.ts +3 -1
  52. package/dist/misc/command.d.ts.map +1 -1
  53. package/dist/misc/form.d.ts +1 -1
  54. package/dist/misc/form.d.ts.map +1 -1
  55. package/package.json +4 -3
@@ -0,0 +1,235 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
+ if (ar || !(i in from)) {
41
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
+ ar[i] = from[i];
43
+ }
44
+ }
45
+ return to.concat(ar || Array.prototype.slice.call(from));
46
+ };
47
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
48
+ import { useState, useRef, useEffect } from "react";
49
+ import { Send, Smile, Image as ImageIcon, FileText, Camera, MapPin, Mic, X, CircleStopIcon, VideoIcon, PlusCircleIcon, ListTodo, ReceiptText } from "lucide-react";
50
+ import { Button } from "../misc/button";
51
+ import { Textarea } from "../misc/textarea";
52
+ import { Popover, PopoverContent, PopoverTrigger } from "../misc/popover";
53
+ import { CameraDialog } from "./dialogs/CameraDialog";
54
+ import { showAlert } from "../misc/alertdialogclaude";
55
+ import EmojiPicker from 'emoji-picker-react';
56
+ export function MessageInput(_a) {
57
+ var _this = this;
58
+ var _b;
59
+ var onSend = _a.onSend, onTypingStart = _a.onTypingStart, onTypingStop = _a.onTypingStop, disabled = _a.disabled, replyTo = _a.replyTo, onCancelReply = _a.onCancelReply, onAddMilestone = _a.onAddMilestone, onAddExpense = _a.onAddExpense, _c = _a.activePanel, activePanel = _c === void 0 ? "chat" : _c;
60
+ var _d = useState(""), text = _d[0], setText = _d[1];
61
+ var _e = useState([]), selectedFiles = _e[0], setSelectedFiles = _e[1];
62
+ var textareaRef = useRef(null);
63
+ var fileInputRef = useRef(null);
64
+ var _f = useState(""), fileAcceptType = _f[0], setFileAcceptType = _f[1];
65
+ var typingTimeoutRef = useRef(null);
66
+ var isTypingRef = useRef(false);
67
+ var _g = useState(false), showEmojiPicker = _g[0], setShowEmojiPicker = _g[1];
68
+ var _h = useState(false), isCameraOpen = _h[0], setIsCameraOpen = _h[1];
69
+ var _j = useState(false), isRecording = _j[0], setIsRecording = _j[1];
70
+ var mediaRecorderRef = useRef(null);
71
+ var audioChunksRef = useRef([]);
72
+ // Auto-resize textarea
73
+ useEffect(function () {
74
+ var el = textareaRef.current;
75
+ if (el) {
76
+ el.style.height = "auto";
77
+ el.style.height = Math.min(el.scrollHeight, 120) + "px";
78
+ }
79
+ }, [text]);
80
+ function handleChange(e) {
81
+ setText(e.target.value);
82
+ // Typing indicator
83
+ if (!isTypingRef.current && e.target.value.length > 0) {
84
+ isTypingRef.current = true;
85
+ onTypingStart === null || onTypingStart === void 0 ? void 0 : onTypingStart();
86
+ }
87
+ // Reset typing timeout
88
+ if (typingTimeoutRef.current)
89
+ clearTimeout(typingTimeoutRef.current);
90
+ typingTimeoutRef.current = setTimeout(function () {
91
+ isTypingRef.current = false;
92
+ onTypingStop === null || onTypingStop === void 0 ? void 0 : onTypingStop();
93
+ }, 2000);
94
+ }
95
+ function handleSend() {
96
+ var _a;
97
+ var trimmed = text.trim();
98
+ if ((!trimmed && selectedFiles.length === 0) || disabled)
99
+ return;
100
+ onSend(trimmed, selectedFiles);
101
+ setText("");
102
+ setSelectedFiles([]);
103
+ // Clear typing
104
+ if (typingTimeoutRef.current)
105
+ clearTimeout(typingTimeoutRef.current);
106
+ isTypingRef.current = false;
107
+ onTypingStop === null || onTypingStop === void 0 ? void 0 : onTypingStop();
108
+ // Refocus
109
+ (_a = textareaRef.current) === null || _a === void 0 ? void 0 : _a.focus();
110
+ }
111
+ function handleKeyDown(e) {
112
+ if (e.key === "Enter" && !e.shiftKey) {
113
+ e.preventDefault();
114
+ handleSend();
115
+ }
116
+ }
117
+ var handleFileChange = function (e) {
118
+ if (e.target.files) {
119
+ setSelectedFiles(function (prev) { return __spreadArray(__spreadArray([], prev, true), Array.from(e.target.files), true); });
120
+ }
121
+ };
122
+ var removeFile = function (index) {
123
+ setSelectedFiles(function (prev) { return prev.filter(function (_, i) { return i !== index; }); });
124
+ };
125
+ var handleLocation = function () {
126
+ if ("geolocation" in navigator) {
127
+ navigator.geolocation.getCurrentPosition(function (position) {
128
+ var _a = position.coords, latitude = _a.latitude, longitude = _a.longitude;
129
+ var mapLink = "https://www.google.com/maps?q=".concat(latitude, ",").concat(longitude);
130
+ onSend(mapLink);
131
+ }, function (error) {
132
+ console.error("Error getting location:", error);
133
+ showAlert("Could not get location.");
134
+ });
135
+ }
136
+ else {
137
+ showAlert("Geolocation is not supported by this browser.");
138
+ }
139
+ };
140
+ var handleCameraCapture = function (file) {
141
+ setSelectedFiles(function (prev) { return __spreadArray(__spreadArray([], prev, true), [file], false); });
142
+ };
143
+ var startRecording = function () { return __awaiter(_this, void 0, void 0, function () {
144
+ var stream_1, mediaRecorder, err_1;
145
+ return __generator(this, function (_a) {
146
+ switch (_a.label) {
147
+ case 0:
148
+ _a.trys.push([0, 2, , 3]);
149
+ return [4 /*yield*/, navigator.mediaDevices.getUserMedia({ audio: true })];
150
+ case 1:
151
+ stream_1 = _a.sent();
152
+ mediaRecorder = new MediaRecorder(stream_1);
153
+ mediaRecorderRef.current = mediaRecorder;
154
+ audioChunksRef.current = [];
155
+ mediaRecorder.ondataavailable = function (event) {
156
+ if (event.data.size > 0) {
157
+ audioChunksRef.current.push(event.data);
158
+ }
159
+ };
160
+ mediaRecorder.onstop = function () {
161
+ var audioBlob = new Blob(audioChunksRef.current, { type: "audio/webm" });
162
+ var audioFile = new File([audioBlob], "voice_".concat(Date.now(), ".webm"), { type: "audio/webm" });
163
+ setSelectedFiles(function (prev) { return __spreadArray(__spreadArray([], prev, true), [audioFile], false); });
164
+ stream_1.getTracks().forEach(function (track) { return track.stop(); });
165
+ };
166
+ mediaRecorder.start();
167
+ setIsRecording(true);
168
+ return [3 /*break*/, 3];
169
+ case 2:
170
+ err_1 = _a.sent();
171
+ console.error("Error accessing microphone:", err_1);
172
+ alert("Could not access microphone");
173
+ return [3 /*break*/, 3];
174
+ case 3: return [2 /*return*/];
175
+ }
176
+ });
177
+ }); };
178
+ var stopRecording = function () {
179
+ if (mediaRecorderRef.current && isRecording) {
180
+ mediaRecorderRef.current.stop();
181
+ setIsRecording(false);
182
+ }
183
+ };
184
+ var handleEmojiSelect = function (emojiObject) {
185
+ if (textareaRef.current) {
186
+ var cursorPos = textareaRef.current.selectionStart;
187
+ var newText = text.slice(0, cursorPos) + emojiObject.emoji + text.slice(cursorPos);
188
+ setText(newText);
189
+ setShowEmojiPicker(false);
190
+ textareaRef.current.focus();
191
+ }
192
+ };
193
+ // Only show message input for chat panel
194
+ var showMessageInput = activePanel === "chat";
195
+ return (_jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900 p-3", children: [_jsx(CameraDialog, { open: isCameraOpen, onOpenChange: setIsCameraOpen, onCapture: handleCameraCapture }), selectedFiles.length > 0 && (_jsx("div", { className: "max-w-4xl mx-auto mb-2 flex flex-wrap gap-2", children: selectedFiles.map(function (file, i) { return (_jsxs("div", { className: "flex items-center bg-gray-100 dark:bg-gray-800 rounded-lg px-2 py-1 text-xs text-gray-600 dark:text-gray-300", children: [_jsx("span", { className: "truncate max-w-[150px]", children: file.name }), _jsx("button", { onClick: function () { return removeFile(i); }, className: "ml-2 text-red-500 hover:text-red-700 font-bold", children: "\u00D7" })] }, i)); }) })), replyTo && (_jsxs("div", { className: "max-w-4xl mx-auto mb-2 flex items-center gap-2 bg-gray-100 dark:bg-gray-800 px-3 py-2 rounded-lg border-l-2 border-teal-500", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "text-xs font-semibold text-teal-600 dark:text-teal-400", children: ["Replying to ", replyTo.senderId] }), _jsx("div", { className: "text-xs text-gray-600 dark:text-gray-400 truncate", children: (_b = replyTo.content.text) === null || _b === void 0 ? void 0 : _b.substring(0, 60) })] }), _jsx("button", { onClick: onCancelReply, className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 flex-shrink-0", children: _jsx(X, { className: "w-4 h-4" }) })] })), _jsxs("div", { className: "".concat(showMessageInput ? "flex" : "hidden md:flex", " items-end gap-2 max-w-4xl mx-auto"), children: [_jsx("input", { type: "file", ref: fileInputRef, onChange: handleFileChange, accept: fileAcceptType, multiple: true, className: "hidden" }), _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full h-10 w-10 shrink-0", children: _jsx(PlusCircleIcon, { className: "w-5 h-5" }) }) }), _jsxs(PopoverContent, { side: "top", align: "start", className: "w-48 p-2 flex flex-col gap-1", children: [_jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full", onClick: function () { return __awaiter(_this, void 0, void 0, function () {
196
+ var _a;
197
+ return __generator(this, function (_b) {
198
+ switch (_b.label) {
199
+ case 0: return [4 /*yield*/, setFileAcceptType(".pdf,.doc,.docx,.txt,.xlsx,.pptx")];
200
+ case 1:
201
+ _b.sent();
202
+ (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
203
+ return [2 /*return*/];
204
+ }
205
+ });
206
+ }); }, children: [_jsx(FileText, { className: "w-4 h-4 text-purple-500" }), "Document"] }), _jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full", onClick: function () { return __awaiter(_this, void 0, void 0, function () {
207
+ var _a;
208
+ return __generator(this, function (_b) {
209
+ switch (_b.label) {
210
+ case 0: return [4 /*yield*/, setFileAcceptType("image/*")];
211
+ case 1:
212
+ _b.sent();
213
+ (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
214
+ return [2 /*return*/];
215
+ }
216
+ });
217
+ }); }, children: [_jsx(ImageIcon, { className: "w-4 h-4 text-blue-500" }), "Photos"] }), _jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full", onClick: function () { return __awaiter(_this, void 0, void 0, function () {
218
+ var _a;
219
+ return __generator(this, function (_b) {
220
+ switch (_b.label) {
221
+ case 0: return [4 /*yield*/, setFileAcceptType("video/*")];
222
+ case 1:
223
+ _b.sent();
224
+ (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
225
+ return [2 /*return*/];
226
+ }
227
+ });
228
+ }); }, children: [_jsx(VideoIcon, { className: "w-4 h-4 text-rose-500" }), "Videos"] }), _jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full", onClick: handleLocation, children: [_jsx(MapPin, { className: "w-4 h-4 text-green-500" }), "Location"] }), _jsx("div", { className: "border-t border-gray-200 dark:border-gray-700 my-1" }), _jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full text-teal-600 dark:text-teal-400", onClick: function () {
229
+ onAddMilestone === null || onAddMilestone === void 0 ? void 0 : onAddMilestone();
230
+ }, children: [_jsx(ListTodo, { className: "w-4 h-4" }), "Add Milestone"] }), _jsxs(Button, { variant: "ghost", className: "justify-start gap-2 w-full text-teal-600 dark:text-teal-400", onClick: function () {
231
+ onAddExpense === null || onAddExpense === void 0 ? void 0 : onAddExpense();
232
+ }, children: [_jsx(ReceiptText, { className: "w-4 h-4" }), "Add Expense"] })] })] }), _jsxs("div", { className: "flex-1 bg-gray-100 dark:bg-gray-800 rounded-2xl flex items-end", children: [_jsx(Textarea, { ref: textareaRef, value: text, onChange: handleChange, onKeyDown: handleKeyDown, placeholder: "Type a message...", disabled: disabled, rows: 1, className: "flex-1 bg-transparent border-none focus-visible:ring-0 px-4 py-3 text-[15px] resize-none text-gray-900 dark:text-white placeholder-gray-400 max-h-[120px] min-h-[48px]" }), _jsx(Button, { variant: "ghost", size: "icon", className: "mr-1 mb-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hidden sm:inline-flex", onClick: function () { return setShowEmojiPicker(!showEmojiPicker); }, children: _jsx(Smile, { className: "w-5 h-5" }) }), _jsx(Button, { variant: "ghost", size: "icon", className: "mr-1 mb-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full", onClick: function () { return setIsCameraOpen(true); }, children: _jsx(Camera, { className: "w-5 h-5" }) })] }), text.trim() || selectedFiles.length > 0 ? (_jsx(Button, { onClick: handleSend, disabled: disabled, className: "rounded-full h-11 w-11 p-0 bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700 shadow-lg shadow-teal-500/25 shrink-0", children: _jsx(Send, { className: "w-5 h-5" }) })) : (_jsx(Button, { variant: "ghost", size: "icon", className: "rounded-full h-11 w-11 shrink-0 transition-all ".concat(isRecording
233
+ ? "bg-red-500 hover:bg-red-600 animate-pulse text-white"
234
+ : "text-teal-400 hover:bg-teal-100 dark:hover:bg-teal-800"), onClick: function () { return isRecording ? stopRecording() : startRecording(); }, children: isRecording ? _jsx(CircleStopIcon, { className: "w-6 h-6" }) : _jsx(Mic, { className: "w-6 h-6" }) })), showEmojiPicker && _jsx(EmojiPicker, { onEmojiClick: handleEmojiSelect })] })] }));
235
+ }
@@ -0,0 +1,8 @@
1
+ interface MilestonePanelProps {
2
+ conversationId: string;
3
+ currentUserId: string;
4
+ isFullScreen?: boolean;
5
+ }
6
+ export declare function MilestonePanel({ conversationId, currentUserId, isFullScreen }: MilestonePanelProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=MilestonePanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MilestonePanel.d.ts","sourceRoot":"","sources":["../../src/chat/MilestonePanel.tsx"],"names":[],"mappings":"AASA,UAAU,mBAAmB;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,YAAoB,EAAE,EAAE,mBAAmB,2CAgL1G"}
@@ -0,0 +1,173 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
+ if (ar || !(i in from)) {
41
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
+ ar[i] = from[i];
43
+ }
44
+ }
45
+ return to.concat(ar || Array.prototype.slice.call(from));
46
+ };
47
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
48
+ import { useState, useEffect } from "react";
49
+ import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
50
+ import { CheckCircle2, Circle, Plus, Trash2, Pencil, MoreVertical } from "lucide-react";
51
+ import { Button } from "../misc/button";
52
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../misc/dropdown-menu";
53
+ export function MilestonePanel(_a) {
54
+ var _this = this;
55
+ var conversationId = _a.conversationId, currentUserId = _a.currentUserId, _b = _a.isFullScreen, isFullScreen = _b === void 0 ? false : _b;
56
+ var _c = useState([]), milestones = _c[0], setMilestones = _c[1];
57
+ var _d = useState(true), loading = _d[0], setLoading = _d[1];
58
+ var _e = useState(false), isAdding = _e[0], setIsAdding = _e[1];
59
+ var _f = useState(""), newTitle = _f[0], setNewTitle = _f[1];
60
+ var _g = useState(""), newSection = _g[0], setNewSection = _g[1];
61
+ var fetchMilestones = function () { return __awaiter(_this, void 0, void 0, function () {
62
+ var data;
63
+ return __generator(this, function (_a) {
64
+ switch (_a.label) {
65
+ case 0:
66
+ setLoading(true);
67
+ return [4 /*yield*/, chatApi.getMilestones(conversationId)];
68
+ case 1:
69
+ data = _a.sent();
70
+ setMilestones(data);
71
+ setLoading(false);
72
+ return [2 /*return*/];
73
+ }
74
+ });
75
+ }); };
76
+ useEffect(function () {
77
+ fetchMilestones();
78
+ }, [conversationId]);
79
+ var handleCreate = function () { return __awaiter(_this, void 0, void 0, function () {
80
+ var milestone;
81
+ return __generator(this, function (_a) {
82
+ switch (_a.label) {
83
+ case 0:
84
+ if (!newTitle.trim())
85
+ return [2 /*return*/];
86
+ return [4 /*yield*/, chatApi.createMilestone(conversationId, {
87
+ title: newTitle.trim(),
88
+ section: newSection.trim() || "General"
89
+ })];
90
+ case 1:
91
+ milestone = _a.sent();
92
+ if (milestone) {
93
+ setMilestones(function (prev) { return __spreadArray(__spreadArray([], prev, true), [milestone], false); });
94
+ setNewTitle("");
95
+ setNewSection("");
96
+ setIsAdding(false);
97
+ }
98
+ return [2 /*return*/];
99
+ }
100
+ });
101
+ }); };
102
+ var handleToggle = function (id) { return __awaiter(_this, void 0, void 0, function () {
103
+ var updated;
104
+ return __generator(this, function (_a) {
105
+ switch (_a.label) {
106
+ case 0: return [4 /*yield*/, chatApi.toggleMilestone(id)];
107
+ case 1:
108
+ updated = _a.sent();
109
+ if (updated) {
110
+ setMilestones(function (prev) { return prev.map(function (m) { return m._id === id ? updated : m; }); });
111
+ }
112
+ return [2 /*return*/];
113
+ }
114
+ });
115
+ }); };
116
+ var handleDelete = function (id) { return __awaiter(_this, void 0, void 0, function () {
117
+ return __generator(this, function (_a) {
118
+ switch (_a.label) {
119
+ case 0:
120
+ if (!window.confirm("Are you sure you want to delete this milestone?")) return [3 /*break*/, 2];
121
+ return [4 /*yield*/, chatApi.deleteMilestone(id)];
122
+ case 1:
123
+ _a.sent();
124
+ setMilestones(function (prev) { return prev.filter(function (m) { return m._id !== id; }); });
125
+ _a.label = 2;
126
+ case 2: return [2 /*return*/];
127
+ }
128
+ });
129
+ }); };
130
+ var handleEdit = function (id_1, currentTitle_1) {
131
+ var args_1 = [];
132
+ for (var _i = 2; _i < arguments.length; _i++) {
133
+ args_1[_i - 2] = arguments[_i];
134
+ }
135
+ return __awaiter(_this, __spreadArray([id_1, currentTitle_1], args_1, true), void 0, function (id, currentTitle, currentSection) {
136
+ var newTitle, newSection, updates, updated_1;
137
+ if (currentSection === void 0) { currentSection = "General"; }
138
+ return __generator(this, function (_a) {
139
+ switch (_a.label) {
140
+ case 0:
141
+ newTitle = window.prompt("Edit milestone title:", currentTitle);
142
+ newSection = window.prompt("Edit section:", currentSection);
143
+ if (!(newTitle && newTitle.trim() !== "")) return [3 /*break*/, 2];
144
+ updates = { title: newTitle.trim() };
145
+ if (newSection !== null)
146
+ updates.section = newSection.trim() || "General";
147
+ return [4 /*yield*/, chatApi.updateMilestone(id, updates)];
148
+ case 1:
149
+ updated_1 = _a.sent();
150
+ if (updated_1) {
151
+ setMilestones(function (prev) { return prev.map(function (m) { return m._id === id ? updated_1 : m; }); });
152
+ }
153
+ _a.label = 2;
154
+ case 2: return [2 /*return*/];
155
+ }
156
+ });
157
+ });
158
+ };
159
+ var groupedMilestones = milestones.reduce(function (acc, m) {
160
+ var section = m.section || "General";
161
+ if (!acc[section])
162
+ acc[section] = [];
163
+ acc[section].push(m);
164
+ return acc;
165
+ }, {});
166
+ var panelClasses = isFullScreen
167
+ ? "w-full h-full flex flex-col"
168
+ : "flex flex-col h-full w-full md:w-80 border-l border-gray-200 dark:border-gray-700";
169
+ return (_jsxs("div", { className: "bg-white dark:bg-gray-900 ".concat(panelClasses), children: [_jsx("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0", children: _jsx("h3", { className: "font-semibold text-gray-900 dark:text-white", children: "Milestones" }) }), _jsx("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: loading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx("div", { className: "animate-spin w-5 h-5 border-2 border-teal-500 border-t-transparent rounded-full" }) })) : milestones.length === 0 && !isAdding ? (_jsx("div", { className: "text-center py-8 text-gray-400 text-sm", children: "No milestones yet" })) : (_jsxs(_Fragment, { children: [isAdding && (_jsxs("div", { className: "bg-teal-50 dark:bg-teal-900/20 p-3 rounded-xl border border-teal-100 dark:border-teal-800", children: [_jsx("input", { autoFocus: true, value: newTitle, onChange: function (e) { return setNewTitle(e.target.value); }, placeholder: "Milestone title...", className: "w-full bg-white dark:bg-gray-800 border-none outline-none rounded-lg p-2 text-sm text-gray-900 dark:text-white mb-2 shadow-sm" }), _jsx("input", { value: newSection, onChange: function (e) { return setNewSection(e.target.value); }, onKeyDown: function (e) { return e.key === "Enter" && handleCreate(); }, placeholder: "Section (e.g., Day 1)...", className: "w-full bg-white dark:bg-gray-800 border-none outline-none rounded-lg p-2 text-sm text-gray-900 dark:text-white mb-2 shadow-sm" }), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: function () { return setIsAdding(false); }, children: "Cancel" }), _jsx(Button, { size: "sm", onClick: handleCreate, className: "bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700 text-white", children: "Add" })] })] })), milestones.length > 0 && (Object.entries(groupedMilestones).map(function (_a) {
170
+ var section = _a[0], items = _a[1];
171
+ return (_jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-widest pl-1 sticky top-0 bg-white dark:bg-gray-900 py-1 z-10", children: section }), items.map(function (m) { return (_jsxs("div", { className: "group flex items-start gap-3 p-2 hover:bg-gray-50 dark:hover:bg-gray-800/50 rounded-xl transition-colors", children: [_jsx("button", { onClick: function () { return handleToggle(m._id); }, className: "mt-0.5 transition-colors flex-shrink-0 ".concat(m.isCompleted ? "text-green-500" : "text-gray-300 hover:text-teal-400"), children: m.isCompleted ? _jsx(CheckCircle2, { className: "w-5 h-5" }) : _jsx(Circle, { className: "w-5 h-5" }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-sm font-medium transition-all ".concat(m.isCompleted ? "text-gray-400 line-through" : "text-gray-700 dark:text-gray-200"), children: m.title }), m.completedAt && (_jsxs("p", { className: "text-[10px] text-gray-400 mt-0.5", children: ["Completed on ", new Date(m.completedAt).toLocaleDateString()] }))] }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { className: "opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md transition-all flex-shrink-0", children: _jsx(MoreVertical, { className: "w-4 h-4 text-gray-400" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: function () { return handleEdit(m._id, m.title, m.section); }, children: [_jsx(Pencil, { className: "w-4 h-4 mr-2" }), "Edit"] }), _jsxs(DropdownMenuItem, { className: "text-red-500", onClick: function () { return handleDelete(m._id); }, children: [_jsx(Trash2, { className: "w-4 h-4 mr-2" }), "Delete"] })] })] })] }, m._id)); })] }, section));
172
+ }))] })) }), !isAdding && (_jsx("div", { className: "p-4 border-t border-gray-200 dark:border-gray-700 flex-shrink-0", children: _jsxs(Button, { onClick: function () { return setIsAdding(true); }, className: "w-full bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700 text-white rounded-lg flex items-center justify-center gap-2", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Milestone"] }) }))] }));
173
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { User as UserType } from "@myrjfa/state/dist/lib/models/user";
3
+ interface AddMemberDialogProps {
4
+ selectedUsers: UserType[];
5
+ setSelectedUsers: React.Dispatch<React.SetStateAction<UserType[]>>;
6
+ excludeUsernames?: string[];
7
+ }
8
+ export declare function AddMemberDialog({ selectedUsers, setSelectedUsers, excludeUsernames }: AddMemberDialogProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=AddMemberDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddMemberDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/AddMemberDialog.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAMxC,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAE3E,UAAU,oBAAoB;IAC1B,aAAa,EAAE,QAAQ,EAAE,CAAC;IAC1B,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAClE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,wBAAgB,eAAe,CAAC,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAqB,EAAE,EAAE,oBAAoB,2CAmF/G"}
@@ -0,0 +1,110 @@
1
+ "use client";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
+ if (ar || !(i in from)) {
41
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
+ ar[i] = from[i];
43
+ }
44
+ }
45
+ return to.concat(ar || Array.prototype.slice.call(from));
46
+ };
47
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
48
+ import { useState } from "react";
49
+ import { Input } from "../../misc/input";
50
+ import { Button } from "../../misc/button";
51
+ import { User, Loader2, X } from "lucide-react";
52
+ import { userDetails } from "@myrjfa/state/dist/lib/actions/actions";
53
+ import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
54
+ export function AddMemberDialog(_a) {
55
+ var selectedUsers = _a.selectedUsers, setSelectedUsers = _a.setSelectedUsers, _b = _a.excludeUsernames, excludeUsernames = _b === void 0 ? [] : _b;
56
+ var _c = useState(""), query = _c[0], setQuery = _c[1];
57
+ var _d = useState([]), results = _d[0], setResults = _d[1];
58
+ var _e = useState(false), loading = _e[0], setLoading = _e[1];
59
+ function handleSearch(e) {
60
+ return __awaiter(this, void 0, void 0, function () {
61
+ var res_1, err_1;
62
+ return __generator(this, function (_a) {
63
+ switch (_a.label) {
64
+ case 0:
65
+ e.preventDefault();
66
+ if (!query.trim())
67
+ return [2 /*return*/];
68
+ setLoading(true);
69
+ _a.label = 1;
70
+ case 1:
71
+ _a.trys.push([1, 3, 4, 5]);
72
+ return [4 /*yield*/, userDetails(query, "user")];
73
+ case 2:
74
+ res_1 = _a.sent();
75
+ if (res_1.error) {
76
+ console.error("user not found:", res_1.error);
77
+ setResults([]);
78
+ }
79
+ else {
80
+ if (res_1.user && !excludeUsernames.includes(res_1.user.username || "") && !selectedUsers.some(function (u) { return res_1.user ? u.username == res_1.user.username : false; })) {
81
+ setResults([res_1.user]);
82
+ }
83
+ }
84
+ return [3 /*break*/, 5];
85
+ case 3:
86
+ err_1 = _a.sent();
87
+ console.error(err_1);
88
+ return [3 /*break*/, 5];
89
+ case 4:
90
+ setLoading(false);
91
+ return [7 /*endfinally*/];
92
+ case 5: return [2 /*return*/];
93
+ }
94
+ });
95
+ });
96
+ }
97
+ function toggleUser(user) {
98
+ if (selectedUsers.find(function (u) { return u.username === user.username; })) {
99
+ setSelectedUsers(function (prev) { return prev.filter(function (u) { return u.username !== user.username; }); });
100
+ setQuery("");
101
+ setResults([]);
102
+ }
103
+ else {
104
+ setSelectedUsers(function (prev) { return __spreadArray(__spreadArray([], prev, true), [user], false); });
105
+ setQuery("");
106
+ setResults([]);
107
+ }
108
+ }
109
+ return (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "flex flex-wrap gap-2", children: selectedUsers.map(function (user) { return (_jsxs("div", { className: "flex items-center gap-1 bg-indigo-100 text-indigo-700 text-xs px-2 py-1 rounded-full", children: [_jsx("span", { children: user.firstName }), _jsx(X, { className: "w-3 h-3 cursor-pointer", onClick: function () { return toggleUser(user); } })] }, user.username)); }) }), _jsxs("form", { onSubmit: handleSearch, className: "flex gap-2", children: [_jsx(Input, { placeholder: "Add members by email, contact or username...", value: query, onChange: function (e) { return setQuery(e.target.value); } }), _jsx(Button, { type: "submit", size: "sm", disabled: loading, children: loading ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : "Find" })] }), _jsx("div", { className: "flex flex-col gap-2 max-h-[200px] overflow-y-auto", children: results.map(function (user) { return (_jsx("div", { className: "flex items-center justify-between p-2 hover:bg-accent rounded-md cursor-pointer", onClick: function () { return toggleUser(user); }, children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs(Avatar, { className: "h-8 w-8", children: [_jsx(AvatarImage, { src: user.profilePic }), _jsx(AvatarFallback, { children: _jsx(User, { className: "h-4 w-4" }) })] }), _jsxs("div", { children: [_jsxs("p", { className: "text-sm font-medium", children: [user.firstName, " ", user.lastName] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["@", user.username] })] })] }) }, user.username)); }) })] }));
110
+ }
@@ -0,0 +1,8 @@
1
+ interface CameraDialogProps {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ onCapture: (file: File) => void;
5
+ }
6
+ export declare function CameraDialog({ open, onOpenChange, onCapture }: CameraDialogProps): import("react/jsx-runtime").JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=CameraDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CameraDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/CameraDialog.tsx"],"names":[],"mappings":"AAOA,UAAU,iBAAiB;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CACnC;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,iBAAiB,2CA2HhF"}