@myrjfa/ui 1.0.8 → 1.1.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.
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 +244 -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 +16 -0
  14. package/dist/chat/MessageBubble.d.ts.map +1 -0
  15. package/dist/chat/MessageBubble.js +202 -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,128 @@
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
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
39
+ import { useRef, useState, useEffect } from "react";
40
+ import { Dialog, DialogContent } from "../../misc/dialog";
41
+ import { Button } from "../../misc/button";
42
+ import { RefreshCw, Check } from "lucide-react";
43
+ export function CameraDialog(_a) {
44
+ var _this = this;
45
+ var open = _a.open, onOpenChange = _a.onOpenChange, onCapture = _a.onCapture;
46
+ var videoRef = useRef(null);
47
+ var canvasRef = useRef(null);
48
+ var _b = useState(null), stream = _b[0], setStream = _b[1];
49
+ var _c = useState(null), capturedImage = _c[0], setCapturedImage = _c[1];
50
+ var _d = useState(false), loading = _d[0], setLoading = _d[1];
51
+ useEffect(function () {
52
+ if (open) {
53
+ startCamera();
54
+ }
55
+ else {
56
+ stopCamera();
57
+ setCapturedImage(null);
58
+ }
59
+ return function () { return stopCamera(); };
60
+ }, [open]);
61
+ var startCamera = function () { return __awaiter(_this, void 0, void 0, function () {
62
+ var mediaStream, err_1;
63
+ return __generator(this, function (_a) {
64
+ switch (_a.label) {
65
+ case 0:
66
+ _a.trys.push([0, 2, , 3]);
67
+ setLoading(true);
68
+ return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
69
+ video: { facingMode: "user" }
70
+ })];
71
+ case 1:
72
+ mediaStream = _a.sent();
73
+ setStream(mediaStream);
74
+ if (videoRef.current) {
75
+ videoRef.current.srcObject = mediaStream;
76
+ }
77
+ setLoading(false);
78
+ return [3 /*break*/, 3];
79
+ case 2:
80
+ err_1 = _a.sent();
81
+ console.error("Error accessing camera:", err_1);
82
+ setLoading(false);
83
+ alert("Could not access camera");
84
+ onOpenChange(false);
85
+ return [3 /*break*/, 3];
86
+ case 3: return [2 /*return*/];
87
+ }
88
+ });
89
+ }); };
90
+ var stopCamera = function () {
91
+ if (stream) {
92
+ stream.getTracks().forEach(function (track) { return track.stop(); });
93
+ setStream(null);
94
+ }
95
+ };
96
+ var handleCapture = function () {
97
+ if (videoRef.current && canvasRef.current) {
98
+ var video = videoRef.current;
99
+ var canvas = canvasRef.current;
100
+ canvas.width = video.videoWidth;
101
+ canvas.height = video.videoHeight;
102
+ var ctx = canvas.getContext("2d");
103
+ if (ctx) {
104
+ // Flip horizontally if facing user mode (optional, but good for selfies)
105
+ // ctx.translate(canvas.width, 0);
106
+ // ctx.scale(-1, 1);
107
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
108
+ var dataUrl = canvas.toDataURL("image/jpeg");
109
+ setCapturedImage(dataUrl);
110
+ }
111
+ }
112
+ };
113
+ var handleRetake = function () {
114
+ setCapturedImage(null);
115
+ };
116
+ var handleConfirm = function () {
117
+ if (capturedImage) {
118
+ fetch(capturedImage)
119
+ .then(function (res) { return res.blob(); })
120
+ .then(function (blob) {
121
+ var file = new File([blob], "camera_".concat(Date.now(), ".jpg"), { type: "image/jpeg" });
122
+ onCapture(file);
123
+ onOpenChange(false);
124
+ });
125
+ }
126
+ };
127
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-md p-0 overflow-hidden bg-black border-gray-800", children: [_jsxs("div", { className: "relative aspect-[3/4] sm:aspect-video bg-black flex items-center justify-center", children: [!capturedImage && (_jsx("video", { ref: videoRef, autoPlay: true, playsInline: true, className: "w-full h-full object-cover" })), capturedImage && (_jsx("img", { src: capturedImage, alt: "Captured", className: "w-full h-full object-contain" })), _jsx("canvas", { ref: canvasRef, className: "hidden" })] }), _jsx("div", { className: "p-4 flex items-center justify-center gap-4 bg-gray-900 border-t border-gray-800", children: !capturedImage ? (_jsx(Button, { onClick: handleCapture, className: "h-16 w-16 rounded-full border-4 border-white bg-transparent p-1 hover:bg-white/10", children: _jsx("div", { className: "h-full w-full rounded-full bg-white" }) })) : (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "ghost", className: "text-white hover:bg-gray-800", onClick: handleRetake, children: [_jsx(RefreshCw, { className: "w-5 h-5 mr-2" }), "Retake"] }), _jsxs(Button, { className: "bg-white text-black hover:bg-gray-200", onClick: handleConfirm, children: [_jsx(Check, { className: "w-5 h-5 mr-2" }), "Send Photo"] })] })) })] }) }));
128
+ }
@@ -0,0 +1,10 @@
1
+ import type { Conversation } from "@myrjfa/state/dist/lib/models/chat";
2
+ interface GroupInfoDialogProps {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ conversation: Conversation;
6
+ onUpdate: () => void;
7
+ }
8
+ export declare function GroupInfoDialog({ open, onOpenChange, conversation, onUpdate }: GroupInfoDialogProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=GroupInfoDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupInfoDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/GroupInfoDialog.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAIvE,UAAU,oBAAoB;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,EAC5B,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,QAAQ,EACX,EAAE,oBAAoB,2CAqGtB"}
@@ -0,0 +1,108 @@
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
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
39
+ import { useState } from "react";
40
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "../../misc/dialog";
41
+ import { Button } from "../../misc/button";
42
+ import { Input } from "../../misc/input";
43
+ import { Textarea } from "../../misc/textarea";
44
+ import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
45
+ import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
46
+ import { Users, Camera, Loader2 } from "lucide-react";
47
+ export function GroupInfoDialog(_a) {
48
+ var _this = this;
49
+ var open = _a.open, onOpenChange = _a.onOpenChange, conversation = _a.conversation, onUpdate = _a.onUpdate;
50
+ var _b = useState(conversation.name || ""), name = _b[0], setName = _b[1];
51
+ var _c = useState(conversation.description || ""), description = _c[0], setDescription = _c[1];
52
+ var _d = useState(null), imageFile = _d[0], setImageFile = _d[1];
53
+ var _e = useState(conversation.image || ""), previewImage = _e[0], setPreviewImage = _e[1];
54
+ var _f = useState(false), loading = _f[0], setLoading = _f[1];
55
+ var handleImageChange = function (e) {
56
+ if (e.target.files && e.target.files[0]) {
57
+ var file = e.target.files[0];
58
+ setImageFile(file);
59
+ setPreviewImage(URL.createObjectURL(file));
60
+ }
61
+ };
62
+ var handleSave = function () { return __awaiter(_this, void 0, void 0, function () {
63
+ var imageUrl, formData, res, err_1;
64
+ return __generator(this, function (_a) {
65
+ switch (_a.label) {
66
+ case 0:
67
+ setLoading(true);
68
+ _a.label = 1;
69
+ case 1:
70
+ _a.trys.push([1, 5, 6, 7]);
71
+ imageUrl = conversation.image;
72
+ if (!imageFile) return [3 /*break*/, 3];
73
+ formData = new FormData();
74
+ formData.append("chatFiles", imageFile);
75
+ return [4 /*yield*/, chatApi.uploadFiles(formData)];
76
+ case 2:
77
+ res = _a.sent();
78
+ if (res.data && res.data.files && res.data.files.length > 0) {
79
+ imageUrl = res.data.files[0].location;
80
+ }
81
+ _a.label = 3;
82
+ case 3:
83
+ // Update conversation
84
+ return [4 /*yield*/, chatApi.updateConversation(conversation._id, {
85
+ name: name,
86
+ description: description,
87
+ image: imageUrl
88
+ })];
89
+ case 4:
90
+ // Update conversation
91
+ _a.sent();
92
+ onUpdate();
93
+ onOpenChange(false);
94
+ return [3 /*break*/, 7];
95
+ case 5:
96
+ err_1 = _a.sent();
97
+ console.error("Failed to update group info:", err_1);
98
+ alert("Failed to update group info");
99
+ return [3 /*break*/, 7];
100
+ case 6:
101
+ setLoading(false);
102
+ return [7 /*endfinally*/];
103
+ case 7: return [2 /*return*/];
104
+ }
105
+ });
106
+ }); };
107
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Edit Group Info" }) }), _jsxs("div", { className: "space-y-6 py-4", children: [_jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsxs("div", { className: "relative group cursor-pointer", children: [_jsxs(Avatar, { className: "w-24 h-24 shadow-md", children: [_jsx(AvatarImage, { src: previewImage }), _jsx(AvatarFallback, { className: "bg-gradient-to-br from-indigo-500 to-purple-600 text-white text-2xl", children: _jsx(Users, { className: "w-10 h-10" }) })] }), _jsxs("label", { className: "absolute inset-0 flex items-center justify-center bg-black/40 text-white opacity-0 group-hover:opacity-100 rounded-full transition-opacity cursor-pointer", children: [_jsx(Camera, { className: "w-8 h-8" }), _jsx("input", { type: "file", className: "hidden", accept: "image/*", onChange: handleImageChange })] })] }), _jsx("p", { className: "text-xs text-gray-500", children: "Click to change group icon" })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Group Name" }), _jsx(Input, { value: name, onChange: function (e) { return setName(e.target.value); }, placeholder: "Enter group name" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Description" }), _jsx(Textarea, { value: description, onChange: function (e) { return setDescription(e.target.value); }, placeholder: "Add a group description (optional)", className: "resize-none", rows: 3 })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: function () { return onOpenChange(false); }, disabled: loading, children: "Cancel" }), _jsxs(Button, { onClick: handleSave, disabled: loading, children: [loading && _jsx(Loader2, { className: "w-4 h-4 mr-2 animate-spin" }), "Save Changes"] })] })] }) }));
108
+ }
@@ -0,0 +1,9 @@
1
+ import type { Conversation } from "@myrjfa/state/dist/lib/models/chat";
2
+ interface GroupInfoViewDialogProps {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ conversation: Conversation;
6
+ }
7
+ export declare function GroupInfoViewDialog({ open, onOpenChange, conversation, }: GroupInfoViewDialogProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=GroupInfoViewDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupInfoViewDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/GroupInfoViewDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEvE,UAAU,wBAAwB;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,YAAY,CAAC;CAC9B;AAED,wBAAgB,mBAAmB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,YAAY,GACf,EAAE,wBAAwB,2CAiH1B"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "../../misc/dialog";
4
+ import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
5
+ import { Users, Shield, Calendar } from "lucide-react";
6
+ export function GroupInfoViewDialog(_a) {
7
+ var open = _a.open, onOpenChange = _a.onOpenChange, conversation = _a.conversation;
8
+ var admins = conversation.participants.filter(function (p) { return p.chatRole === "admin"; });
9
+ var createdDate = conversation.createdAt ? new Date(conversation.createdAt).toLocaleDateString("en-US", {
10
+ year: "numeric",
11
+ month: "long",
12
+ day: "numeric"
13
+ }) : "Unknown";
14
+ var createdBy = conversation.participants.find(function (p) { return p.userId === conversation.createdBy; });
15
+ return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-md", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Group Information" }), _jsx(DialogDescription, { children: "View group details and members" })] }), _jsxs("div", { className: "space-y-6", children: [_jsx("div", { className: "flex justify-center", children: _jsxs(Avatar, { className: "w-24 h-24", children: [_jsx(AvatarImage, { src: conversation.image }), _jsx(AvatarFallback, { className: "bg-gradient-to-br from-indigo-500 to-purple-600 text-white text-2xl", children: _jsx(Users, { className: "w-8 h-8" }) })] }) }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Group Name" }), _jsx("p", { className: "text-lg font-semibold text-gray-900 dark:text-white mt-1", children: conversation.name })] }), conversation.description && (_jsxs("div", { children: [_jsx("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Description" }), _jsx("p", { className: "text-gray-700 dark:text-gray-300 mt-1", children: conversation.description })] })), _jsxs("div", { children: [_jsxs("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [_jsx(Users, { className: "w-4 h-4" }), "Members"] }), _jsxs("p", { className: "text-gray-900 dark:text-white mt-1", children: [conversation.participants.length, " ", conversation.participants.length === 1 ? "member" : "members"] })] }), _jsxs("div", { children: [_jsxs("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [_jsx(Calendar, { className: "w-4 h-4" }), "Created"] }), _jsx("p", { className: "text-gray-900 dark:text-white mt-1", children: createdDate })] }), createdBy && (_jsxs("div", { children: [_jsx("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Created by" }), _jsxs("div", { className: "flex items-center gap-3 mt-2", children: [_jsxs(Avatar, { className: "w-8 h-8", children: [_jsx(AvatarImage, { src: createdBy.profilePic }), _jsx(AvatarFallback, { className: "bg-indigo-500 text-white text-xs", children: createdBy.userId.charAt(0).toUpperCase() })] }), _jsx("span", { className: "text-gray-900 dark:text-white", children: createdBy.userId })] })] })), admins.length > 0 && (_jsxs("div", { children: [_jsxs("label", { className: "text-sm font-medium text-gray-500 dark:text-gray-400 flex items-center gap-2", children: [_jsx(Shield, { className: "w-4 h-4" }), "Admins"] }), _jsx("div", { className: "space-y-2 mt-2", children: admins.map(function (admin) { return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs(Avatar, { className: "w-8 h-8", children: [_jsx(AvatarImage, { src: admin.profilePic }), _jsx(AvatarFallback, { className: "bg-purple-500 text-white text-xs", children: admin.userId.charAt(0).toUpperCase() })] }), _jsx("span", { className: "text-gray-900 dark:text-white", children: admin.userId })] }, admin.userId)); }) })] }))] })] }) }));
16
+ }
@@ -0,0 +1,2 @@
1
+ export declare function NewChatDialog(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=NewChatDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NewChatDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewChatDialog.tsx"],"names":[],"mappings":"AAaA,wBAAgB,aAAa,4CAwG5B"}
@@ -0,0 +1,127 @@
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
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
39
+ import { useState } from "react";
40
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "../../misc/dialog";
41
+ import { Button } from "../../misc/button";
42
+ import { Input } from "../../misc/input";
43
+ import { MessageCircle, Search, User, Loader2 } from "lucide-react";
44
+ import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
45
+ import { userDetails } from "@myrjfa/state/dist/lib/actions/actions"; // Check if these are exported from index
46
+ import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
47
+ import { useRouter } from "next/navigation";
48
+ export function NewChatDialog() {
49
+ var _a = useState(false), open = _a[0], setOpen = _a[1];
50
+ var _b = useState(""), query = _b[0], setQuery = _b[1];
51
+ var _c = useState([]), results = _c[0], setResults = _c[1];
52
+ var _d = useState(false), loading = _d[0], setLoading = _d[1];
53
+ var _e = useState(false), creating = _e[0], setCreating = _e[1];
54
+ var router = useRouter();
55
+ function handleSearch(e) {
56
+ return __awaiter(this, void 0, void 0, function () {
57
+ var res, err_1;
58
+ return __generator(this, function (_a) {
59
+ switch (_a.label) {
60
+ case 0:
61
+ e.preventDefault();
62
+ if (!query.trim())
63
+ return [2 /*return*/];
64
+ setLoading(true);
65
+ _a.label = 1;
66
+ case 1:
67
+ _a.trys.push([1, 3, 4, 5]);
68
+ return [4 /*yield*/, userDetails(query, "user")];
69
+ case 2:
70
+ res = _a.sent();
71
+ if (res.error) {
72
+ console.error("user not found:", res.error);
73
+ setResults([]);
74
+ }
75
+ else {
76
+ if (res.user) {
77
+ setResults([res.user]);
78
+ }
79
+ }
80
+ return [3 /*break*/, 5];
81
+ case 3:
82
+ err_1 = _a.sent();
83
+ console.error(err_1);
84
+ return [3 /*break*/, 5];
85
+ case 4:
86
+ setLoading(false);
87
+ return [7 /*endfinally*/];
88
+ case 5: return [2 /*return*/];
89
+ }
90
+ });
91
+ });
92
+ }
93
+ function startChat(userId) {
94
+ return __awaiter(this, void 0, void 0, function () {
95
+ var conversation, err_2;
96
+ return __generator(this, function (_a) {
97
+ switch (_a.label) {
98
+ case 0:
99
+ setCreating(true);
100
+ _a.label = 1;
101
+ case 1:
102
+ _a.trys.push([1, 3, 4, 5]);
103
+ return [4 /*yield*/, chatApi.createConversation({
104
+ type: "individual",
105
+ otherUserId: userId
106
+ })];
107
+ case 2:
108
+ conversation = _a.sent();
109
+ setOpen(false);
110
+ setQuery("");
111
+ setResults([]);
112
+ router.replace("/chat?id=".concat(conversation._id));
113
+ return [3 /*break*/, 5];
114
+ case 3:
115
+ err_2 = _a.sent();
116
+ console.error("Failed to create chat:", err_2);
117
+ return [3 /*break*/, 5];
118
+ case 4:
119
+ setCreating(false);
120
+ return [7 /*endfinally*/];
121
+ case 5: return [2 /*return*/];
122
+ }
123
+ });
124
+ });
125
+ }
126
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs("div", { className: "flex-1 flex items-center justify-center gap-2 py-2.5 bg-indigo-50 dark:bg-indigo-950/30 text-indigo-600 dark:text-indigo-400 rounded-xl text-sm font-medium hover:bg-indigo-100 dark:hover:bg-indigo-950/50 transition-colors cursor-pointer", children: [_jsx(MessageCircle, { className: "w-4 h-4" }), "New Chat"] }) }), _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "New Chat" }) }), _jsxs("div", { className: "gap-4 py-4", children: [_jsxs("form", { onSubmit: handleSearch, className: "flex gap-2", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" }), _jsx(Input, { placeholder: "Search by email, contact or username...", className: "pl-8", value: query, onChange: function (e) { return setQuery(e.target.value); } })] }), _jsx(Button, { type: "submit", disabled: loading, children: loading ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : "Search" })] }), _jsxs("div", { className: "mt-4 flex flex-col gap-2 max-h-[300px] overflow-y-auto", children: [results.length === 0 && !loading && query && (_jsx("p", { className: "text-center text-sm text-muted-foreground", children: "No users found." })), results.map(function (user) { return (_jsxs("div", { className: "flex items-center justify-between p-2 hover:bg-accent rounded-md cursor-pointer", onClick: function () { return startChat(user.username || ""); }, children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs(Avatar, { 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] })] })] }), creating ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : null] }, user.username)); })] })] })] })] }));
127
+ }
@@ -0,0 +1,2 @@
1
+ export declare function NewGroupDialog(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=NewGroupDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NewGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewGroupDialog.tsx"],"names":[],"mappings":"AAaA,wBAAgB,cAAc,4CAwG7B"}
@@ -0,0 +1,112 @@
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
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
39
+ import { useState } from "react";
40
+ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "../../misc/dialog";
41
+ import { Button } from "../../misc/button";
42
+ import { Input } from "../../misc/input";
43
+ import { Users, Loader2, Camera } from "lucide-react";
44
+ import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
45
+ import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
46
+ import { useRouter } from "next/navigation";
47
+ import { AddMemberDialog } from "./AddMemberDialog";
48
+ export function NewGroupDialog() {
49
+ var _a = useState(false), open = _a[0], setOpen = _a[1];
50
+ var _b = useState(""), groupName = _b[0], setGroupName = _b[1];
51
+ var _c = useState([]), selectedUsers = _c[0], setSelectedUsers = _c[1];
52
+ var _d = useState(false), creating = _d[0], setCreating = _d[1];
53
+ var _e = useState(""), previewImage = _e[0], setPreviewImage = _e[1];
54
+ var _f = useState(null), imageFile = _f[0], setImageFile = _f[1];
55
+ var router = useRouter();
56
+ var handleImageChange = function (e) {
57
+ if (e.target.files && e.target.files[0]) {
58
+ var file = e.target.files[0];
59
+ setImageFile(file);
60
+ setPreviewImage(URL.createObjectURL(file));
61
+ }
62
+ };
63
+ function createGroup() {
64
+ return __awaiter(this, void 0, void 0, function () {
65
+ var imageUrl, formData, res, conversation, err_1;
66
+ return __generator(this, function (_a) {
67
+ switch (_a.label) {
68
+ case 0:
69
+ if (!groupName.trim() || selectedUsers.length === 0)
70
+ return [2 /*return*/];
71
+ setCreating(true);
72
+ _a.label = 1;
73
+ case 1:
74
+ _a.trys.push([1, 5, , 6]);
75
+ imageUrl = null;
76
+ if (!imageFile) return [3 /*break*/, 3];
77
+ formData = new FormData();
78
+ formData.append("chatFiles", imageFile);
79
+ return [4 /*yield*/, chatApi.uploadFiles(formData)];
80
+ case 2:
81
+ res = _a.sent();
82
+ if (res.data && res.data.files && res.data.files.length > 0) {
83
+ imageUrl = res.data.files[0].location;
84
+ }
85
+ _a.label = 3;
86
+ case 3: return [4 /*yield*/, chatApi.createConversation({
87
+ type: "group",
88
+ name: groupName,
89
+ participantIds: selectedUsers.map(function (u) { return u.username || ""; }).filter(Boolean),
90
+ image: imageUrl
91
+ })];
92
+ case 4:
93
+ conversation = _a.sent();
94
+ setOpen(false);
95
+ setGroupName("");
96
+ setSelectedUsers([]);
97
+ setPreviewImage("");
98
+ setImageFile(null);
99
+ router.replace("/chat?id=".concat(conversation._id));
100
+ return [3 /*break*/, 6];
101
+ case 5:
102
+ err_1 = _a.sent();
103
+ console.error("Failed to create group:", err_1);
104
+ setCreating(false);
105
+ return [3 /*break*/, 6];
106
+ case 6: return [2 /*return*/];
107
+ }
108
+ });
109
+ });
110
+ }
111
+ return (_jsxs(Dialog, { open: open, onOpenChange: setOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsxs("div", { className: "flex-1 flex items-center justify-center gap-2 py-2.5 bg-purple-50 dark:bg-purple-950/30 text-purple-600 dark:text-purple-400 rounded-xl text-sm font-medium hover:bg-purple-100 dark:hover:bg-purple-950/50 transition-colors cursor-pointer", children: [_jsx(Users, { className: "w-4 h-4" }), "New Group"] }) }), _jsxs(DialogContent, { className: "sm:max-w-[500px]", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "New Group Chat" }) }), _jsxs("div", { className: "flex flex-col gap-4 py-4", children: [_jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsxs("div", { className: "relative group cursor-pointer", children: [_jsxs(Avatar, { className: "w-24 h-24 shadow-md", children: [_jsx(AvatarImage, { src: previewImage }), _jsx(AvatarFallback, { className: "bg-gradient-to-br from-indigo-500 to-purple-600 text-white text-2xl", children: _jsx(Users, { className: "w-10 h-10" }) })] }), _jsxs("label", { className: "absolute inset-0 flex items-center justify-center bg-black/40 text-white opacity-0 group-hover:opacity-100 rounded-full transition-opacity cursor-pointer", children: [_jsx(Camera, { className: "w-8 h-8" }), _jsx("input", { type: "file", className: "hidden", accept: "image/*", onChange: handleImageChange })] })] }), _jsx("p", { className: "text-xs text-gray-500", children: "Click to change group icon" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Group Name" }), _jsx(Input, { placeholder: "Group Name", value: groupName, onChange: function (e) { return setGroupName(e.target.value); } })] }), _jsx(AddMemberDialog, { selectedUsers: selectedUsers, setSelectedUsers: setSelectedUsers, excludeUsernames: selectedUsers.map(function (u) { return u.username || ""; }) })] }), _jsx("div", { className: "flex justify-end pt-4", children: _jsxs(Button, { onClick: createGroup, disabled: creating || !groupName || selectedUsers.length === 0, children: [creating ? _jsx(Loader2, { className: "h-4 w-4 animate-spin mr-2" }) : null, "Create Group"] }) })] })] })] }));
112
+ }
@@ -0,0 +1,11 @@
1
+ import type { Conversation } from "@myrjfa/state/dist/lib/models/chat";
2
+ interface ParticipantsDialogProps {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ conversation: Conversation;
6
+ currentUserId: string;
7
+ onUpdate: () => void;
8
+ }
9
+ export declare function ParticipantsDialog({ open, onOpenChange, conversation, currentUserId, onUpdate }: ParticipantsDialogProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=ParticipantsDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParticipantsDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/ParticipantsDialog.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,oCAAoC,CAAC;AAOpF,UAAU,uBAAuB;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,QAAQ,EACX,EAAE,uBAAuB,2CA6JzB"}