@myrjfa/ui 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/ChatMain.d.ts +3 -1
- package/dist/chat/ChatMain.d.ts.map +1 -1
- package/dist/chat/ChatMain.js +174 -145
- package/dist/chat/ChatSidebar.js +7 -8
- package/dist/chat/ConversationList.d.ts.map +1 -1
- package/dist/chat/ConversationList.js +20 -18
- package/dist/chat/ExpensePanel.d.ts +4 -1
- package/dist/chat/ExpensePanel.d.ts.map +1 -1
- package/dist/chat/ExpensePanel.js +215 -195
- package/dist/chat/MessageBubble.d.ts +5 -3
- package/dist/chat/MessageBubble.d.ts.map +1 -1
- package/dist/chat/MessageBubble.js +185 -103
- package/dist/chat/MessageInput.d.ts +8 -1
- package/dist/chat/MessageInput.d.ts.map +1 -1
- package/dist/chat/MessageInput.js +182 -165
- package/dist/chat/MilestonePanel.d.ts +4 -1
- package/dist/chat/MilestonePanel.d.ts.map +1 -1
- package/dist/chat/MilestonePanel.js +150 -150
- package/dist/chat/components/ParticipantSelector.d.ts +11 -0
- package/dist/chat/components/ParticipantSelector.d.ts.map +1 -0
- package/dist/chat/components/ParticipantSelector.js +17 -0
- package/dist/chat/components/SplitInputs.d.ts +11 -0
- package/dist/chat/components/SplitInputs.d.ts.map +1 -0
- package/dist/chat/components/SplitInputs.js +83 -0
- package/dist/chat/components/SplitTypeSelector.d.ts +8 -0
- package/dist/chat/components/SplitTypeSelector.d.ts.map +1 -0
- package/dist/chat/components/SplitTypeSelector.js +13 -0
- package/dist/chat/dialogs/AddMemberDialog.js +30 -90
- package/dist/chat/dialogs/CameraDialog.js +38 -86
- package/dist/chat/dialogs/CreatePollDialog.d.ts +8 -0
- package/dist/chat/dialogs/CreatePollDialog.d.ts.map +1 -0
- package/dist/chat/dialogs/CreatePollDialog.js +38 -0
- package/dist/chat/dialogs/ExpenseAnalyticsDialog.d.ts +19 -0
- package/dist/chat/dialogs/ExpenseAnalyticsDialog.d.ts.map +1 -0
- package/dist/chat/dialogs/ExpenseAnalyticsDialog.js +52 -0
- package/dist/chat/dialogs/GroupInfoDialog.d.ts.map +1 -1
- package/dist/chat/dialogs/GroupInfoDialog.js +55 -92
- package/dist/chat/dialogs/GroupInfoViewDialog.js +5 -6
- package/dist/chat/dialogs/NewChatDialog.d.ts.map +1 -1
- package/dist/chat/dialogs/NewChatDialog.js +49 -113
- package/dist/chat/dialogs/NewGroupDialog.d.ts.map +1 -1
- package/dist/chat/dialogs/NewGroupDialog.js +49 -92
- package/dist/chat/dialogs/ParticipantsDialog.d.ts.map +1 -1
- package/dist/chat/dialogs/ParticipantsDialog.js +68 -118
- package/dist/dashboard/action-buttons.js +4 -5
- package/dist/dashboard/app-sidebar.js +47 -129
- package/dist/dashboard/card-header.js +1 -2
- package/dist/dashboard/dashboard-components.js +3 -5
- package/dist/dashboard/data-table.d.ts +2 -1
- package/dist/dashboard/data-table.d.ts.map +1 -1
- package/dist/dashboard/data-table.js +21 -33
- package/dist/dashboard/nav-main.js +4 -5
- package/dist/dashboard/nav-secondary.js +2 -25
- package/dist/dashboard/stats-card.js +1 -2
- package/dist/dashboard/table.js +8 -54
- package/dist/header/mobile-nav-item.js +1 -2
- package/dist/header/mobile-navbar.js +8 -9
- package/dist/header/nav-item.js +1 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/main/footer.js +5 -9
- package/dist/main/navbar.js +55 -138
- package/dist/main/paginationBar.js +12 -14
- package/dist/main/portfolio/portfolioItem.js +1 -2
- package/dist/main/portfolio/portfolioPopup.js +16 -17
- package/dist/main/review-page.d.ts.map +1 -1
- package/dist/main/review-page.js +132 -199
- package/dist/misc/accordion.js +8 -34
- package/dist/misc/alert-dialog.js +22 -55
- package/dist/misc/alert.js +7 -32
- package/dist/misc/alertdialogclaude.js +50 -125
- package/dist/misc/avatar.js +6 -31
- package/dist/misc/badge.js +4 -27
- package/dist/misc/button.js +4 -27
- package/dist/misc/card.js +12 -40
- package/dist/misc/carousel.js +37 -61
- package/dist/misc/checkbox.js +2 -25
- package/dist/misc/command.js +18 -49
- package/dist/misc/datepicker.js +66 -76
- package/dist/misc/dialog.js +20 -52
- package/dist/misc/document-upload-button.d.ts +12 -0
- package/dist/misc/document-upload-button.d.ts.map +1 -0
- package/dist/misc/document-upload-button.js +27 -0
- package/dist/misc/dropdown-menu.js +30 -67
- package/dist/misc/empty-state.d.ts +10 -0
- package/dist/misc/empty-state.d.ts.map +1 -0
- package/dist/misc/empty-state.js +5 -0
- package/dist/misc/faq.js +2 -3
- package/dist/misc/file-preview.js +43 -97
- package/dist/misc/filter.d.ts.map +1 -1
- package/dist/misc/filter.js +18 -21
- package/dist/misc/filterBar.js +136 -160
- package/dist/misc/form.js +39 -60
- package/dist/misc/image-compressor.d.ts +29 -0
- package/dist/misc/image-compressor.d.ts.map +1 -0
- package/dist/misc/image-compressor.js +70 -0
- package/dist/misc/image-cropper.d.ts +10 -0
- package/dist/misc/image-cropper.d.ts.map +1 -0
- package/dist/misc/image-cropper.js +44 -0
- package/dist/misc/input.d.ts.map +1 -1
- package/dist/misc/input.js +2 -25
- package/dist/misc/label.js +2 -25
- package/dist/misc/line-carousel.js +3 -13
- package/dist/misc/multiImageUploader.d.ts +2 -1
- package/dist/misc/multiImageUploader.d.ts.map +1 -1
- package/dist/misc/multiImageUploader.js +26 -3
- package/dist/misc/newsLetter.js +19 -79
- package/dist/misc/notification.d.ts +1 -2
- package/dist/misc/notification.d.ts.map +1 -1
- package/dist/misc/notification.js +89 -125
- package/dist/misc/pagination.js +16 -45
- package/dist/misc/password-eye.js +2 -3
- package/dist/misc/popover.d.ts.map +1 -1
- package/dist/misc/popover.js +8 -34
- package/dist/misc/progress.js +2 -25
- package/dist/misc/pwa-install-button.d.ts +9 -0
- package/dist/misc/pwa-install-button.d.ts.map +1 -0
- package/dist/misc/pwa-install-button.js +158 -0
- package/dist/misc/scroll-area.js +5 -29
- package/dist/misc/searchBar.js +27 -31
- package/dist/misc/searchBox.js +18 -22
- package/dist/misc/select.d.ts.map +1 -1
- package/dist/misc/select.js +22 -54
- package/dist/misc/separator.js +2 -25
- package/dist/misc/share.js +48 -104
- package/dist/misc/sheet.js +21 -53
- package/dist/misc/sidebar.js +112 -153
- package/dist/misc/skeleton.d.ts +36 -1
- package/dist/misc/skeleton.d.ts.map +1 -1
- package/dist/misc/skeleton.js +41 -27
- package/dist/misc/slider.js +3 -26
- package/dist/misc/starRating.js +5 -15
- package/dist/misc/stateCard.js +7 -8
- package/dist/misc/switch.d.ts +5 -0
- package/dist/misc/switch.d.ts.map +1 -0
- package/dist/misc/switch.js +8 -0
- package/dist/misc/tabs.js +8 -34
- package/dist/misc/textarea.js +2 -25
- package/dist/misc/tile.js +32 -93
- package/dist/misc/tooltip.js +8 -34
- package/dist/misc/whatsapp-help.d.ts +9 -0
- package/dist/misc/whatsapp-help.d.ts.map +1 -0
- package/dist/misc/whatsapp-help.js +13 -0
- package/dist/profile/socialLink.d.ts +1 -1
- package/dist/profile/socialLink.d.ts.map +1 -1
- package/dist/profile/socialLink.js +53 -69
- package/dist/utils/permissions.d.ts +7 -0
- package/dist/utils/permissions.d.ts.map +1 -0
- package/dist/utils/permissions.js +38 -0
- package/package.json +6 -4
- package/dist/main/portfolio/temp-page.d.ts +0 -2
- package/dist/main/portfolio/temp-page.d.ts.map +0 -1
- package/dist/main/portfolio/temp-page.js +0 -102
|
@@ -1,42 +1,6 @@
|
|
|
1
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
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
39
|
-
import { useState } from "react";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
40
4
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "../../misc/dialog";
|
|
41
5
|
import { Button } from "../../misc/button";
|
|
42
6
|
import { Input } from "../../misc/input";
|
|
@@ -44,65 +8,64 @@ import { Textarea } from "../../misc/textarea";
|
|
|
44
8
|
import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
|
|
45
9
|
import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
|
|
46
10
|
import { Users, Camera, Loader2 } from "lucide-react";
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
11
|
+
import { Switch } from "../../misc/switch";
|
|
12
|
+
export function GroupInfoDialog({ open, onOpenChange, conversation, onUpdate }) {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const [name, setName] = useState(conversation.name || "");
|
|
15
|
+
const [description, setDescription] = useState(conversation.description || "");
|
|
16
|
+
const [imageFile, setImageFile] = useState(null);
|
|
17
|
+
const [previewImage, setPreviewImage] = useState(conversation.image || "");
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const [milestonesEnabled, setMilestonesEnabled] = useState(((_a = conversation.features) === null || _a === void 0 ? void 0 : _a.milestones) || false);
|
|
20
|
+
const [expensesEnabled, setExpensesEnabled] = useState(((_b = conversation.features) === null || _b === void 0 ? void 0 : _b.expenses) || false);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
setName(conversation.name || "");
|
|
24
|
+
setDescription(conversation.description || "");
|
|
25
|
+
setPreviewImage(conversation.image || "");
|
|
26
|
+
setMilestonesEnabled(((_a = conversation.features) === null || _a === void 0 ? void 0 : _a.milestones) || false);
|
|
27
|
+
setExpensesEnabled(((_b = conversation.features) === null || _b === void 0 ? void 0 : _b.expenses) || false);
|
|
28
|
+
}, [conversation]);
|
|
29
|
+
const handleImageChange = (e) => {
|
|
56
30
|
if (e.target.files && e.target.files[0]) {
|
|
57
|
-
|
|
31
|
+
const file = e.target.files[0];
|
|
58
32
|
setImageFile(file);
|
|
59
33
|
setPreviewImage(URL.createObjectURL(file));
|
|
60
34
|
}
|
|
61
35
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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*/];
|
|
36
|
+
const handleSave = async () => {
|
|
37
|
+
setLoading(true);
|
|
38
|
+
try {
|
|
39
|
+
// If image changed, upload it first (reuse chat upload or dedicated endpoint)
|
|
40
|
+
let imageUrl = conversation.image;
|
|
41
|
+
if (imageFile) {
|
|
42
|
+
const formData = new FormData();
|
|
43
|
+
formData.append("chatFiles", imageFile);
|
|
44
|
+
const res = await chatApi.uploadFiles(formData);
|
|
45
|
+
if (res.data && res.data.files && res.data.files.length > 0) {
|
|
46
|
+
imageUrl = res.data.files[0].location;
|
|
47
|
+
}
|
|
104
48
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
49
|
+
// Update conversation
|
|
50
|
+
await chatApi.updateConversation(conversation._id, {
|
|
51
|
+
name,
|
|
52
|
+
description,
|
|
53
|
+
image: imageUrl,
|
|
54
|
+
features: {
|
|
55
|
+
milestones: milestonesEnabled,
|
|
56
|
+
expenses: expensesEnabled
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
onUpdate();
|
|
60
|
+
onOpenChange(false);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.error("Failed to update group info:", err);
|
|
64
|
+
alert("Failed to update group info");
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
setLoading(false);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-[425px] mt-15", 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: (e) => 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: (e) => setDescription(e.target.value), placeholder: "Add a group description (optional)", className: "resize-none", rows: 3 })] }), _jsxs("div", { className: "space-y-3 pt-4 border-t border-gray-200 dark:border-gray-700", children: [_jsx("p", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider", children: "Group Features" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "text-sm font-medium", children: "Milestones" }), _jsx("p", { className: "text-xs text-gray-500", children: "Track group tasks and progress" })] }), _jsx(Switch, { checked: milestonesEnabled, onCheckedChange: setMilestonesEnabled })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex-1", children: [_jsx("label", { className: "text-sm font-medium", children: "Expenses" }), _jsx("p", { className: "text-xs text-gray-500", children: "Split costs and track balances" })] }), _jsx(Switch, { checked: expensesEnabled, onCheckedChange: setExpensesEnabled })] })] })] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => 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
71
|
}
|
|
@@ -3,14 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "../../misc/dialog";
|
|
4
4
|
import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
|
|
5
5
|
import { Users, Shield, Calendar } from "lucide-react";
|
|
6
|
-
export function GroupInfoViewDialog(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var createdDate = conversation.createdAt ? new Date(conversation.createdAt).toLocaleDateString("en-US", {
|
|
6
|
+
export function GroupInfoViewDialog({ open, onOpenChange, conversation, }) {
|
|
7
|
+
const admins = conversation.participants.filter(p => p.chatRole === "admin");
|
|
8
|
+
const createdDate = conversation.createdAt ? new Date(conversation.createdAt).toLocaleDateString("en-US", {
|
|
10
9
|
year: "numeric",
|
|
11
10
|
month: "long",
|
|
12
11
|
day: "numeric"
|
|
13
12
|
}) : "Unknown";
|
|
14
|
-
|
|
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(
|
|
13
|
+
const createdBy = conversation.participants.find(p => p.userId === conversation.createdBy);
|
|
14
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-md mt-15", 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((admin) => (_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
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewChatDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewChatDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NewChatDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewChatDialog.tsx"],"names":[],"mappings":"AAcA,wBAAgB,aAAa,4CA2G5B"}
|
|
@@ -1,127 +1,63 @@
|
|
|
1
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
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
39
|
-
import { useState } from "react";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
40
4
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "../../misc/dialog";
|
|
41
5
|
import { Button } from "../../misc/button";
|
|
42
6
|
import { Input } from "../../misc/input";
|
|
43
7
|
import { MessageCircle, Search, User, Loader2 } from "lucide-react";
|
|
44
|
-
import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
|
|
45
8
|
import { userDetails } from "@myrjfa/state/dist/lib/actions/actions"; // Check if these are exported from index
|
|
46
9
|
import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
|
|
47
10
|
import { useRouter } from "next/navigation";
|
|
11
|
+
import { userApi } from "@myrjfa/state/dist/lib/actions/user";
|
|
48
12
|
export function NewChatDialog() {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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*/];
|
|
13
|
+
const [open, setOpen] = useState(false);
|
|
14
|
+
const [query, setQuery] = useState("");
|
|
15
|
+
const [results, setResults] = useState([]);
|
|
16
|
+
const [loading, setLoading] = useState(false);
|
|
17
|
+
const [creating, setCreating] = useState(false);
|
|
18
|
+
const [blockedUserIds, setBlockedUserIds] = useState([]);
|
|
19
|
+
const router = useRouter();
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (open) {
|
|
22
|
+
fetchBlockerUsers();
|
|
23
|
+
}
|
|
24
|
+
}, [open]);
|
|
25
|
+
const fetchBlockerUsers = async () => {
|
|
26
|
+
const blocked = await userApi.getBlockerUsers();
|
|
27
|
+
setBlockedUserIds(blocked.map((u) => u._id));
|
|
28
|
+
};
|
|
29
|
+
async function handleSearch(e) {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
if (!query.trim())
|
|
32
|
+
return;
|
|
33
|
+
setLoading(true);
|
|
34
|
+
try {
|
|
35
|
+
const res = await userDetails(query, "user");
|
|
36
|
+
if (res.error) {
|
|
37
|
+
console.error("user not found:", res.error);
|
|
38
|
+
setResults([]);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
if (res.user && !blockedUserIds.includes(res.user.username)) {
|
|
42
|
+
setResults([res.user]);
|
|
89
43
|
}
|
|
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*/];
|
|
44
|
+
else {
|
|
45
|
+
setResults([]);
|
|
122
46
|
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
console.error(err);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
setLoading(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async function startChat(userId) {
|
|
57
|
+
setOpen(false);
|
|
58
|
+
setQuery("");
|
|
59
|
+
setResults([]);
|
|
60
|
+
router.push(`/chat?u=${userId}`);
|
|
125
61
|
}
|
|
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:
|
|
62
|
+
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: (e) => 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((user) => (_jsxs("div", { className: "flex items-center justify-between p-2 hover:bg-accent rounded-md cursor-pointer", onClick: () => 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
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NewGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewGroupDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NewGroupDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/NewGroupDialog.tsx"],"names":[],"mappings":"AAcA,wBAAgB,cAAc,4CAwI7B"}
|
|
@@ -1,42 +1,6 @@
|
|
|
1
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
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
39
|
-
import { useState } from "react";
|
|
3
|
+
import { useState, useMemo } from "react";
|
|
40
4
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "../../misc/dialog";
|
|
41
5
|
import { Button } from "../../misc/button";
|
|
42
6
|
import { Input } from "../../misc/input";
|
|
@@ -45,68 +9,61 @@ import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
|
|
|
45
9
|
import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
|
|
46
10
|
import { useRouter } from "next/navigation";
|
|
47
11
|
import { AddMemberDialog } from "./AddMemberDialog";
|
|
12
|
+
import { getCurrencies } from "@myrjfa/state/dist/lib/data/countryStates";
|
|
48
13
|
export function NewGroupDialog() {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
const [groupName, setGroupName] = useState("");
|
|
16
|
+
const [selectedUsers, setSelectedUsers] = useState([]);
|
|
17
|
+
const [selectedCurrency, setSelectedCurrency] = useState("INR");
|
|
18
|
+
const [creating, setCreating] = useState(false);
|
|
19
|
+
const [previewImage, setPreviewImage] = useState("");
|
|
20
|
+
const [imageFile, setImageFile] = useState(null);
|
|
21
|
+
const router = useRouter();
|
|
22
|
+
// Get unique currencies and format them
|
|
23
|
+
const currencies = useMemo(() => {
|
|
24
|
+
const allCurrencies = getCurrencies();
|
|
25
|
+
return allCurrencies.map(currency => currency.toUpperCase()).sort();
|
|
26
|
+
}, []);
|
|
27
|
+
const handleImageChange = (e) => {
|
|
57
28
|
if (e.target.files && e.target.files[0]) {
|
|
58
|
-
|
|
29
|
+
const file = e.target.files[0];
|
|
59
30
|
setImageFile(file);
|
|
60
31
|
setPreviewImage(URL.createObjectURL(file));
|
|
61
32
|
}
|
|
62
33
|
};
|
|
63
|
-
function createGroup() {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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*/];
|
|
34
|
+
async function createGroup() {
|
|
35
|
+
if (!groupName.trim() || selectedUsers.length === 0)
|
|
36
|
+
return;
|
|
37
|
+
setCreating(true);
|
|
38
|
+
try {
|
|
39
|
+
let imageUrl = null;
|
|
40
|
+
if (imageFile) {
|
|
41
|
+
const formData = new FormData();
|
|
42
|
+
formData.append("chatFiles", imageFile);
|
|
43
|
+
const res = await chatApi.uploadFiles(formData);
|
|
44
|
+
if (res.data && res.data.files && res.data.files.length > 0) {
|
|
45
|
+
imageUrl = res.data.files[0].location;
|
|
107
46
|
}
|
|
47
|
+
}
|
|
48
|
+
const conversation = await chatApi.createConversation({
|
|
49
|
+
type: "group",
|
|
50
|
+
name: groupName,
|
|
51
|
+
participantIds: selectedUsers.map(u => u.username || "").filter(Boolean),
|
|
52
|
+
image: imageUrl,
|
|
53
|
+
expenseCurrency: selectedCurrency
|
|
108
54
|
});
|
|
109
|
-
|
|
55
|
+
setOpen(false);
|
|
56
|
+
setGroupName("");
|
|
57
|
+
setSelectedUsers([]);
|
|
58
|
+
setSelectedCurrency("INR");
|
|
59
|
+
setPreviewImage("");
|
|
60
|
+
setImageFile(null);
|
|
61
|
+
router.replace(`/chat?id=${conversation._id}`);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.error("Failed to create group:", err);
|
|
65
|
+
setCreating(false);
|
|
66
|
+
}
|
|
110
67
|
}
|
|
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-
|
|
68
|
+
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] mt-15", 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-4", 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: (e) => setGroupName(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Expense Currency" }), _jsxs("select", { value: selectedCurrency, onChange: (e) => setSelectedCurrency(e.target.value), className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white outline-none focus:border-purple-500 focus:ring-1 focus:ring-purple-500 transition-colors", children: [_jsx("option", { value: "", children: "Select Currency" }), currencies.map((currency) => (_jsx("option", { value: currency, children: currency }, currency)))] }), _jsx("p", { className: "text-xs text-gray-500", children: "This currency will be used for all expense tracking in this group" })] }), _jsx(AddMemberDialog, { selectedUsers: selectedUsers, setSelectedUsers: setSelectedUsers, excludeUsernames: selectedUsers.map(u => u.username || "") })] }), _jsx("div", { className: "flex justify-end pt-4", children: _jsxs(Button, { onClick: createGroup, variant: "default", disabled: creating || !groupName || selectedUsers.length === 0 || !selectedCurrency, children: [creating ? _jsx(Loader2, { className: "h-4 w-4 animate-spin mr-2" }) : null, "Create Group"] }) })] })] })] }));
|
|
112
69
|
}
|
|
@@ -1 +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;
|
|
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;AAQpF,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,2CA4KzB"}
|