@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,49 +1,4 @@
|
|
|
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
|
-
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
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
48
3
|
import { useState } from "react";
|
|
49
4
|
import { Input } from "../../misc/input";
|
|
@@ -51,60 +6,45 @@ import { Button } from "../../misc/button";
|
|
|
51
6
|
import { User, Loader2, X } from "lucide-react";
|
|
52
7
|
import { userDetails } from "@myrjfa/state/dist/lib/actions/actions";
|
|
53
8
|
import { Avatar, AvatarFallback, AvatarImage } from "../../misc/avatar";
|
|
54
|
-
export function AddMemberDialog(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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*/];
|
|
9
|
+
export function AddMemberDialog({ selectedUsers, setSelectedUsers, excludeUsernames = [] }) {
|
|
10
|
+
const [query, setQuery] = useState("");
|
|
11
|
+
const [results, setResults] = useState([]);
|
|
12
|
+
const [loading, setLoading] = useState(false);
|
|
13
|
+
async function handleSearch(e) {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
if (!query.trim())
|
|
16
|
+
return;
|
|
17
|
+
setLoading(true);
|
|
18
|
+
try {
|
|
19
|
+
const res = await userDetails(query, "user");
|
|
20
|
+
if (res.error) {
|
|
21
|
+
console.error("user not found:", res.error);
|
|
22
|
+
setResults([]);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
if (res.user && !excludeUsernames.includes(res.user.username || "") && !selectedUsers.some(u => res.user ? u.username == res.user.username : false)) {
|
|
26
|
+
setResults([res.user]);
|
|
93
27
|
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
console.error(err);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
setLoading(false);
|
|
35
|
+
}
|
|
96
36
|
}
|
|
97
37
|
function toggleUser(user) {
|
|
98
|
-
if (selectedUsers.find(
|
|
99
|
-
setSelectedUsers(
|
|
38
|
+
if (selectedUsers.find(u => u.username === user.username)) {
|
|
39
|
+
setSelectedUsers(prev => prev.filter(u => u.username !== user.username));
|
|
100
40
|
setQuery("");
|
|
101
41
|
setResults([]);
|
|
102
42
|
}
|
|
103
43
|
else {
|
|
104
|
-
setSelectedUsers(
|
|
44
|
+
setSelectedUsers(prev => [...prev, user]);
|
|
105
45
|
setQuery("");
|
|
106
46
|
setResults([]);
|
|
107
47
|
}
|
|
108
48
|
}
|
|
109
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "flex flex-wrap gap-2", children: selectedUsers.map(
|
|
49
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "flex flex-wrap gap-2", children: selectedUsers.map(user => (_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: () => 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: (e) => 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((user) => (_jsx("div", { className: "flex items-center justify-between p-2 hover:bg-accent rounded-md cursor-pointer", onClick: () => 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
50
|
}
|
|
@@ -1,54 +1,16 @@
|
|
|
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, Fragment as _Fragment } from "react/jsx-runtime";
|
|
39
3
|
import { useRef, useState, useEffect } from "react";
|
|
40
4
|
import { Dialog, DialogContent } from "../../misc/dialog";
|
|
41
5
|
import { Button } from "../../misc/button";
|
|
42
6
|
import { RefreshCw, Check } from "lucide-react";
|
|
43
|
-
export function CameraDialog(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
var _d = useState(false), loading = _d[0], setLoading = _d[1];
|
|
51
|
-
useEffect(function () {
|
|
7
|
+
export function CameraDialog({ open, onOpenChange, onCapture }) {
|
|
8
|
+
const videoRef = useRef(null);
|
|
9
|
+
const canvasRef = useRef(null);
|
|
10
|
+
const [stream, setStream] = useState(null);
|
|
11
|
+
const [capturedImage, setCapturedImage] = useState(null);
|
|
12
|
+
const [loading, setLoading] = useState(false);
|
|
13
|
+
useEffect(() => {
|
|
52
14
|
if (open) {
|
|
53
15
|
startCamera();
|
|
54
16
|
}
|
|
@@ -56,69 +18,59 @@ export function CameraDialog(_a) {
|
|
|
56
18
|
stopCamera();
|
|
57
19
|
setCapturedImage(null);
|
|
58
20
|
}
|
|
59
|
-
return
|
|
21
|
+
return () => stopCamera();
|
|
60
22
|
}, [open]);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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*/];
|
|
23
|
+
const startCamera = async () => {
|
|
24
|
+
try {
|
|
25
|
+
setLoading(true);
|
|
26
|
+
const mediaStream = await navigator.mediaDevices.getUserMedia({
|
|
27
|
+
video: { facingMode: "user" }
|
|
28
|
+
});
|
|
29
|
+
setStream(mediaStream);
|
|
30
|
+
if (videoRef.current) {
|
|
31
|
+
videoRef.current.srcObject = mediaStream;
|
|
87
32
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
33
|
+
setLoading(false);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.error("Error accessing camera:", err);
|
|
37
|
+
setLoading(false);
|
|
38
|
+
alert("Could not access camera");
|
|
39
|
+
onOpenChange(false);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const stopCamera = () => {
|
|
91
43
|
if (stream) {
|
|
92
|
-
stream.getTracks().forEach(
|
|
44
|
+
stream.getTracks().forEach(track => track.stop());
|
|
93
45
|
setStream(null);
|
|
94
46
|
}
|
|
95
47
|
};
|
|
96
|
-
|
|
48
|
+
const handleCapture = () => {
|
|
97
49
|
if (videoRef.current && canvasRef.current) {
|
|
98
|
-
|
|
99
|
-
|
|
50
|
+
const video = videoRef.current;
|
|
51
|
+
const canvas = canvasRef.current;
|
|
100
52
|
canvas.width = video.videoWidth;
|
|
101
53
|
canvas.height = video.videoHeight;
|
|
102
|
-
|
|
54
|
+
const ctx = canvas.getContext("2d");
|
|
103
55
|
if (ctx) {
|
|
104
56
|
// Flip horizontally if facing user mode (optional, but good for selfies)
|
|
105
57
|
// ctx.translate(canvas.width, 0);
|
|
106
58
|
// ctx.scale(-1, 1);
|
|
107
59
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
108
|
-
|
|
60
|
+
const dataUrl = canvas.toDataURL("image/jpeg");
|
|
109
61
|
setCapturedImage(dataUrl);
|
|
110
62
|
}
|
|
111
63
|
}
|
|
112
64
|
};
|
|
113
|
-
|
|
65
|
+
const handleRetake = () => {
|
|
114
66
|
setCapturedImage(null);
|
|
115
67
|
};
|
|
116
|
-
|
|
68
|
+
const handleConfirm = () => {
|
|
117
69
|
if (capturedImage) {
|
|
118
70
|
fetch(capturedImage)
|
|
119
|
-
.then(
|
|
120
|
-
.then(
|
|
121
|
-
|
|
71
|
+
.then(res => res.blob())
|
|
72
|
+
.then(blob => {
|
|
73
|
+
const file = new File([blob], `camera_${Date.now()}.jpg`, { type: "image/jpeg" });
|
|
122
74
|
onCapture(file);
|
|
123
75
|
onOpenChange(false);
|
|
124
76
|
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface CreatePollDialogProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onOpenChange: (open: boolean) => void;
|
|
4
|
+
onCreate: (question: string, options: string[], allowMultiple: boolean) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function CreatePollDialog({ open, onOpenChange, onCreate }: CreatePollDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=CreatePollDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreatePollDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/CreatePollDialog.tsx"],"names":[],"mappings":"AAQA,UAAU,qBAAqB;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;CACnF;AAED,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,qBAAqB,2CAmHvF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../../misc/dialog";
|
|
5
|
+
import { Button } from "../../misc/button";
|
|
6
|
+
import { Input } from "../../misc/input";
|
|
7
|
+
import { Plus, Trash2, ChartBar } from "lucide-react";
|
|
8
|
+
export function CreatePollDialog({ open, onOpenChange, onCreate }) {
|
|
9
|
+
const [question, setQuestion] = useState("");
|
|
10
|
+
const [options, setOptions] = useState(["", ""]);
|
|
11
|
+
const [allowMultiple, setAllowMultiple] = useState(false);
|
|
12
|
+
const addOption = () => {
|
|
13
|
+
if (options.length < 10) {
|
|
14
|
+
setOptions([...options, ""]);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const removeOption = (index) => {
|
|
18
|
+
if (options.length > 2) {
|
|
19
|
+
setOptions(options.filter((_, i) => i !== index));
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const updateOption = (index, value) => {
|
|
23
|
+
const next = [...options];
|
|
24
|
+
next[index] = value;
|
|
25
|
+
setOptions(next);
|
|
26
|
+
};
|
|
27
|
+
const handleCreate = () => {
|
|
28
|
+
const validOptions = options.map(o => o.trim()).filter(o => o.length > 0);
|
|
29
|
+
if (!question.trim() || validOptions.length < 2)
|
|
30
|
+
return;
|
|
31
|
+
onCreate(question.trim(), validOptions, allowMultiple);
|
|
32
|
+
setQuestion("");
|
|
33
|
+
setOptions(["", ""]);
|
|
34
|
+
setAllowMultiple(false);
|
|
35
|
+
onOpenChange(false);
|
|
36
|
+
};
|
|
37
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onOpenChange, children: _jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [_jsx(DialogHeader, { children: _jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(ChartBar, { className: "w-5 h-5 text-indigo-500" }), "Create Poll"] }) }), _jsxs("div", { className: "space-y-4 py-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Question" }), _jsx(Input, { placeholder: "Ask a question...", value: question, onChange: (e) => setQuestion(e.target.value) })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", children: "Options" }), _jsx("div", { className: "space-y-2 max-h-[200px] overflow-y-auto pr-1", children: options.map((opt, i) => (_jsxs("div", { className: "flex gap-2", children: [_jsx(Input, { placeholder: `Option ${i + 1}`, value: opt, onChange: (e) => updateOption(i, e.target.value) }), options.length > 2 && (_jsx(Button, { variant: "ghost", size: "icon", className: "text-red-500 hover:text-red-700 hover:bg-red-50 shrink-0", onClick: () => removeOption(i), children: _jsx(Trash2, { className: "w-4 h-4" }) }))] }, i))) }), options.length < 10 && (_jsxs(Button, { variant: "outline", size: "sm", className: "w-full gap-2 border-dashed", onClick: addOption, children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Option"] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "checkbox", id: "allowMultiple", checked: allowMultiple, onChange: (e) => setAllowMultiple(e.target.checked), className: "w-4 h-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" }), _jsx("label", { htmlFor: "allowMultiple", className: "text-sm text-gray-600", children: "Allow selecting multiple answers" })] })] }), _jsxs("div", { className: "flex justify-end gap-3 mt-2", children: [_jsx(Button, { variant: "ghost", onClick: () => onOpenChange(false), children: "Cancel" }), _jsx(Button, { onClick: handleCreate, disabled: !question.trim() || options.filter(o => o.trim()).length < 2, className: "bg-indigo-600 hover:bg-indigo-700 text-white", children: "Create Poll" })] })] }) }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface ExpenseAnalyticsDialogProps {
|
|
2
|
+
conversationId: string;
|
|
3
|
+
open: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
}
|
|
6
|
+
export interface GroupBalance {
|
|
7
|
+
balances: {
|
|
8
|
+
userId: string;
|
|
9
|
+
netBalance: number;
|
|
10
|
+
}[];
|
|
11
|
+
settlements: {
|
|
12
|
+
from: string;
|
|
13
|
+
to: string;
|
|
14
|
+
amount: number;
|
|
15
|
+
}[];
|
|
16
|
+
}
|
|
17
|
+
export declare function ExpenseAnalyticsDialog({ conversationId, open, onClose }: ExpenseAnalyticsDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=ExpenseAnalyticsDialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpenseAnalyticsDialog.d.ts","sourceRoot":"","sources":["../../../src/chat/dialogs/ExpenseAnalyticsDialog.tsx"],"names":[],"mappings":"AAQA,UAAU,2BAA2B;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAYD,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAA;KACrB,EAAE,CAAC;IACJ,WAAW,EAAE;QACT,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAA;KACjB,EAAE,CAAA;CACN;AAED,wBAAgB,sBAAsB,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,2BAA2B,2CAyMpG"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../../misc/dialog";
|
|
5
|
+
import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
|
|
6
|
+
import { BarChart3, TrendingUp, Users, PieChart } from "lucide-react";
|
|
7
|
+
export function ExpenseAnalyticsDialog({ conversationId, open, onClose }) {
|
|
8
|
+
const [analytics, setAnalytics] = useState(null);
|
|
9
|
+
const [loading, setLoading] = useState(false);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (open && conversationId) {
|
|
12
|
+
fetchAnalytics();
|
|
13
|
+
}
|
|
14
|
+
}, [open, conversationId]);
|
|
15
|
+
const fetchAnalytics = async () => {
|
|
16
|
+
setLoading(true);
|
|
17
|
+
try {
|
|
18
|
+
const data = await chatApi.getExpenseAnalytics(conversationId);
|
|
19
|
+
setAnalytics(data);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error("Failed to fetch analytics:", error);
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const getCategoryColor = (index) => {
|
|
29
|
+
const colors = [
|
|
30
|
+
"bg-teal-500", "bg-cyan-500", "bg-blue-500", "bg-purple-500",
|
|
31
|
+
"bg-pink-500", "bg-orange-500", "bg-yellow-500", "bg-green-500"
|
|
32
|
+
];
|
|
33
|
+
return colors[index % colors.length];
|
|
34
|
+
};
|
|
35
|
+
return (_jsx(Dialog, { open: open, onOpenChange: onClose, children: _jsxs(DialogContent, { className: "sm:max-w-2xl mt-15 max-h-[90vh] overflow-y-auto", children: [_jsx(DialogHeader, { children: _jsxs(DialogTitle, { className: "flex items-center gap-2", children: [_jsx(BarChart3, { className: "w-5 h-5 text-teal-500" }), "Expense Analytics"] }) }), loading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx("div", { className: "animate-spin w-6 h-6 border-2 border-teal-500 border-t-transparent rounded-full" }) })) : !analytics || analytics.count === 0 ? (_jsxs("div", { className: "text-center py-8 text-gray-400", children: [_jsx(PieChart, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }), _jsx("p", { children: "No expenses to analyze yet" })] })) : (_jsxs("div", { className: "space-y-6 py-2", children: [_jsxs("div", { className: "grid grid-cols-3 gap-3", children: [_jsxs("div", { className: "bg-gradient-to-br from-teal-50 to-cyan-50 dark:from-teal-900/20 dark:to-cyan-900/20 rounded-xl p-3 text-center", children: [_jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-1", children: "Total" }), _jsxs("p", { className: "text-lg font-bold text-teal-700 dark:text-teal-300", children: ["\u20B9", analytics.total.toFixed(0)] })] }), _jsxs("div", { className: "bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 rounded-xl p-3 text-center", children: [_jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-1", children: "Count" }), _jsx("p", { className: "text-lg font-bold text-blue-700 dark:text-blue-300", children: analytics.count })] }), _jsxs("div", { className: "bg-gradient-to-br from-purple-50 to-pink-50 dark:from-purple-900/20 dark:to-pink-900/20 rounded-xl p-3 text-center", children: [_jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-1", children: "Average" }), _jsxs("p", { className: "text-lg font-bold text-purple-700 dark:text-purple-300", children: ["\u20B9", analytics.averageAmount.toFixed(0)] })] })] }), Object.keys(analytics.byCategory).length > 0 && (_jsxs("div", { children: [_jsxs("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3 flex items-center gap-2", children: [_jsx(PieChart, { className: "w-4 h-4" }), "By Category"] }), _jsx("div", { className: "space-y-2", children: Object.entries(analytics.byCategory)
|
|
36
|
+
.sort(([, a], [, b]) => b - a)
|
|
37
|
+
.map(([category, amount], index) => {
|
|
38
|
+
const percentage = (amount / analytics.total) * 100;
|
|
39
|
+
return (_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex justify-between text-xs", children: [_jsx("span", { className: "text-gray-600 dark:text-gray-400", children: category }), _jsxs("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: ["\u20B9", amount.toFixed(0), " (", percentage.toFixed(0), "%)"] })] }), _jsx("div", { className: "w-full h-2 bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden", children: _jsx("div", { className: `h-full ${getCategoryColor(index)} rounded-full transition-all duration-500`, style: { width: `${percentage}%` } }) })] }, category));
|
|
40
|
+
}) })] })), Object.keys(analytics.byPerson).length > 0 && (_jsxs("div", { children: [_jsxs("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3 flex items-center gap-2", children: [_jsx(Users, { className: "w-4 h-4" }), "Expense per person"] }), _jsx("div", { className: "space-y-2", children: Object.entries(analytics.byPerson)
|
|
41
|
+
.sort(([, a], [, b]) => b - a)
|
|
42
|
+
.map(([person, amount]) => {
|
|
43
|
+
const percentage = (amount / analytics.total) * 100;
|
|
44
|
+
return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "w-8 h-8 bg-gradient-to-br from-teal-400 to-cyan-500 rounded-full flex items-center justify-center text-white text-xs font-bold flex-shrink-0", children: person.charAt(0).toUpperCase() }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400 truncate", children: person }), _jsx("div", { className: "w-full h-1.5 bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden mt-1", children: _jsx("div", { className: "h-full bg-gradient-to-r from-teal-400 to-cyan-500 rounded-full transition-all duration-500", style: { width: `${percentage}%` } }) })] }), _jsxs("span", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 flex-shrink-0", children: ["\u20B9", amount.toFixed(0)] })] }, person));
|
|
45
|
+
}) })] })), Object.keys(analytics.byCategoryForUser).length > 0 && (_jsxs("div", { children: [_jsxs("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3 flex items-center gap-2", children: [_jsx(BarChart3, { className: "w-4 h-4" }), "Your Expenses by Category"] }), _jsx("div", { className: "bg-gray-50 dark:bg-gray-800/50 rounded-lg p-3", children: _jsx("div", { className: "space-y-1.5", children: Object.entries(analytics.byCategoryForUser)
|
|
46
|
+
.sort(([, a], [, b]) => b - a)
|
|
47
|
+
.map(([category, amount], index) => {
|
|
48
|
+
const userTotal = Object.values(analytics.byCategoryForUser).reduce((sum, val) => sum + val, 0);
|
|
49
|
+
const percentage = (amount / userTotal) * 100;
|
|
50
|
+
return (_jsxs("div", { className: "text-xs", children: [_jsxs("div", { className: "flex justify-between mb-1", children: [_jsx("span", { className: "text-gray-600 dark:text-gray-400", children: category }), _jsxs("span", { className: "font-medium text-gray-700 dark:text-gray-300", children: ["\u20B9", amount.toFixed(0), " (", percentage.toFixed(0), "%)"] })] }), _jsx("div", { className: "w-full h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden", children: _jsx("div", { className: `h-full ${getCategoryColor(index)} rounded-full`, style: { width: `${percentage}%` } }) })] }, category));
|
|
51
|
+
}) }) })] })), analytics.groupBalances && (_jsxs("div", { children: [_jsxs("h4", { className: "text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3 flex items-center gap-2", children: [_jsx(TrendingUp, { className: "w-4 h-4" }), "Settlement Balances"] }), analytics.groupBalances.balances && analytics.groupBalances.balances.length > 0 && (_jsxs("div", { className: "bg-gray-50 dark:bg-gray-800/50 rounded-lg p-3 mb-3", children: [_jsx("p", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 mb-2", children: "Individual Balances" }), _jsx("div", { className: "space-y-1.5", children: analytics.groupBalances.balances.map((b) => (_jsxs("div", { className: "flex justify-between text-xs py-1", children: [_jsx("span", { className: "text-gray-600 dark:text-gray-400", children: b.userId }), _jsxs("span", { className: `font-medium ${b.netBalance >= 0 ? "text-green-600" : "text-red-500"}`, children: [b.netBalance >= 0 ? "+" : "", "\u20B9", b.netBalance.toFixed(2)] })] }, b.userId))) })] }))] }))] }))] }) }));
|
|
52
|
+
}
|
|
@@ -1 +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;
|
|
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;AAKvE,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,2CA4ItB"}
|