@myrjfa/ui 1.1.0 → 1.1.1
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.map +1 -1
- package/dist/chat/ChatMain.js +173 -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/chat/dialogs/UserProfileDialog.d.ts +10 -0
- package/dist/chat/dialogs/UserProfileDialog.d.ts.map +1 -0
- package/dist/chat/dialogs/UserProfileDialog.js +100 -0
- package/dist/dashboard/action-buttons.js +4 -5
- package/dist/dashboard/app-sidebar.js +46 -128
- package/dist/dashboard/card-header.js +1 -2
- package/dist/dashboard/dashboard-components.js +3 -5
- 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 +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/main/footer.js +5 -9
- package/dist/main/navbar.js +53 -136
- 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 +131 -198
- 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/dropdown-menu.js +30 -67
- 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-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.js +2 -25
- package/dist/misc/label.js +2 -25
- package/dist/misc/line-carousel.js +3 -13
- package/dist/misc/multiImageUploader.js +2 -3
- package/dist/misc/newsLetter.js +18 -78
- 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/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.js +2 -25
- 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 +31 -92
- package/dist/misc/tooltip.js +8 -34
- 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 +3 -2
|
@@ -1,173 +1,173 @@
|
|
|
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, Fragment as _Fragment } from "react/jsx-runtime";
|
|
48
3
|
import { useState, useEffect } from "react";
|
|
49
4
|
import { chatApi } from "@myrjfa/state/dist/lib/actions/chat";
|
|
50
|
-
import { CheckCircle2, Circle, Plus, Trash2, Pencil, MoreVertical } from "lucide-react";
|
|
5
|
+
import { CheckCircle2, Circle, Plus, Trash2, Pencil, MoreVertical, Lock, Unlock, ListTodo, ChevronDown, AlertCircle, ChevronDownIcon, ChevronRightIcon } from "lucide-react";
|
|
51
6
|
import { Button } from "../misc/button";
|
|
7
|
+
import { Input } from "../misc/input";
|
|
8
|
+
import { Textarea } from "../misc/textarea";
|
|
52
9
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../misc/dropdown-menu";
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
10
|
+
import { deleteActions, showAlert } from "../misc/alertdialogclaude";
|
|
11
|
+
export function MilestonePanel({ conversationId, currentUserId, isFullScreen = false, isFeatureEnabled = true, isAdmin = false, onEnableFeature }) {
|
|
12
|
+
const [milestones, setMilestones] = useState([]);
|
|
13
|
+
const [loading, setLoading] = useState(true);
|
|
14
|
+
const [isAdding, setIsAdding] = useState(false);
|
|
15
|
+
const [milestoneId, setMilestoneId] = useState(null);
|
|
16
|
+
const [newTitle, setNewTitle] = useState("");
|
|
17
|
+
const [newSection, setNewSection] = useState("");
|
|
18
|
+
const [newDescription, setNewDescription] = useState("");
|
|
19
|
+
const [newDueDate, setNewDueDate] = useState("");
|
|
20
|
+
const [showMoreOptions, setShowMoreOptions] = useState(false);
|
|
21
|
+
const [sections, setSections] = useState([]);
|
|
22
|
+
const [expandedSections, setExpandedSections] = useState(new Set());
|
|
23
|
+
const [expandedMilestones, setExpandedMilestones] = useState(new Set());
|
|
24
|
+
const [allParticipants, setAllParticipants] = useState([]);
|
|
25
|
+
const fetchMilestones = async () => {
|
|
26
|
+
var _a;
|
|
27
|
+
setLoading(true);
|
|
28
|
+
const data = await chatApi.getMilestones(conversationId);
|
|
29
|
+
const convData = await chatApi.getConversation(conversationId);
|
|
30
|
+
setMilestones(data);
|
|
31
|
+
const participants = ((_a = convData === null || convData === void 0 ? void 0 : convData.participants) === null || _a === void 0 ? void 0 : _a.map((p) => p.userId)) || [];
|
|
32
|
+
setAllParticipants(participants);
|
|
33
|
+
setLoading(false);
|
|
34
|
+
};
|
|
35
|
+
useEffect(() => {
|
|
77
36
|
fetchMilestones();
|
|
78
37
|
}, [conversationId]);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
// Extract unique sections from existing milestones
|
|
40
|
+
const uniqueSections = Array.from(new Set(milestones.map(m => m.section).filter(Boolean)));
|
|
41
|
+
setSections(uniqueSections);
|
|
42
|
+
}, [milestones]);
|
|
43
|
+
const resetForm = () => {
|
|
44
|
+
setNewTitle("");
|
|
45
|
+
setNewSection("");
|
|
46
|
+
setNewDescription("");
|
|
47
|
+
setNewDueDate("");
|
|
48
|
+
setShowMoreOptions(false);
|
|
49
|
+
setIsAdding(false);
|
|
50
|
+
setShowMoreOptions(false);
|
|
51
|
+
setIsAdding(false);
|
|
52
|
+
setMilestoneId(null);
|
|
53
|
+
};
|
|
54
|
+
const toggleSection = (section) => {
|
|
55
|
+
setExpandedSections(prev => {
|
|
56
|
+
const newSet = new Set(prev);
|
|
57
|
+
if (newSet.has(section)) {
|
|
58
|
+
newSet.delete(section);
|
|
99
59
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
var handleToggle = function (id) { return __awaiter(_this, void 0, void 0, function () {
|
|
103
|
-
var updated;
|
|
104
|
-
return __generator(this, function (_a) {
|
|
105
|
-
switch (_a.label) {
|
|
106
|
-
case 0: return [4 /*yield*/, chatApi.toggleMilestone(id)];
|
|
107
|
-
case 1:
|
|
108
|
-
updated = _a.sent();
|
|
109
|
-
if (updated) {
|
|
110
|
-
setMilestones(function (prev) { return prev.map(function (m) { return m._id === id ? updated : m; }); });
|
|
111
|
-
}
|
|
112
|
-
return [2 /*return*/];
|
|
60
|
+
else {
|
|
61
|
+
newSet.add(section);
|
|
113
62
|
}
|
|
63
|
+
return newSet;
|
|
114
64
|
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
setMilestones(function (prev) { return prev.filter(function (m) { return m._id !== id; }); });
|
|
125
|
-
_a.label = 2;
|
|
126
|
-
case 2: return [2 /*return*/];
|
|
65
|
+
};
|
|
66
|
+
const toggleMilestoneExpand = (id) => {
|
|
67
|
+
setExpandedMilestones(prev => {
|
|
68
|
+
const newSet = new Set(prev);
|
|
69
|
+
if (newSet.has(id)) {
|
|
70
|
+
newSet.delete(id);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
newSet.add(id);
|
|
127
74
|
}
|
|
75
|
+
return newSet;
|
|
128
76
|
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
77
|
+
};
|
|
78
|
+
const handleCreate = async () => {
|
|
79
|
+
if (!newTitle.trim())
|
|
80
|
+
return;
|
|
81
|
+
try {
|
|
82
|
+
const milestoneData = {
|
|
83
|
+
title: newTitle.trim(),
|
|
84
|
+
section: newSection.trim() || "General",
|
|
85
|
+
description: newDescription.trim() || undefined,
|
|
86
|
+
dueDate: newDueDate || undefined
|
|
87
|
+
};
|
|
88
|
+
const milestoneResponse = milestoneId
|
|
89
|
+
? await chatApi.updateMilestone(milestoneId, milestoneData)
|
|
90
|
+
: await chatApi.createMilestone(conversationId, milestoneData);
|
|
91
|
+
if (milestoneResponse.error) {
|
|
92
|
+
console.error("Failed to create milestone:", milestoneResponse.error);
|
|
93
|
+
showAlert(milestoneResponse.error, "Failed to create milestone");
|
|
94
|
+
}
|
|
95
|
+
else if (milestoneResponse.data) {
|
|
96
|
+
await fetchMilestones();
|
|
97
|
+
resetForm();
|
|
98
|
+
}
|
|
134
99
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
100
|
+
catch (err) {
|
|
101
|
+
console.error("Failed to create milestone:", err);
|
|
102
|
+
showAlert(err, "Failed to create milestone");
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const handleToggle = async (id) => {
|
|
106
|
+
const response = await chatApi.toggleMilestone(id);
|
|
107
|
+
if (response.error) {
|
|
108
|
+
console.log("error toggling milestone " + id + "Error: " + response.error);
|
|
109
|
+
await showAlert("Error checking/unchecking milestone");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
else if (response.data) {
|
|
113
|
+
setMilestones(prev => prev.map(m => m._id === id ? response.data : m));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const handleDelete = async (id) => {
|
|
117
|
+
let confirmDelete = true;
|
|
118
|
+
await showAlert("Are you sure you want to delete this milestone?", undefined, deleteActions(() => confirmDelete = false));
|
|
119
|
+
if (confirmDelete) {
|
|
120
|
+
const response = await chatApi.deleteMilestone(id);
|
|
121
|
+
if (response.error) {
|
|
122
|
+
console.log("Unable to delete milestone:" + id + "Error: " + response.error);
|
|
123
|
+
await showAlert("Unable to delete milestone");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
setMilestones(prev => prev.filter(m => m._id !== id));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const handleEdit = async (milestone) => {
|
|
130
|
+
var _a, _b, _c;
|
|
131
|
+
setNewTitle(milestone.title);
|
|
132
|
+
setNewSection((_a = milestone.section) !== null && _a !== void 0 ? _a : "");
|
|
133
|
+
setNewDescription((_b = milestone.description) !== null && _b !== void 0 ? _b : "");
|
|
134
|
+
setNewDueDate((_c = milestone.dueDate) !== null && _c !== void 0 ? _c : "");
|
|
135
|
+
setMilestoneId(milestone._id);
|
|
136
|
+
setIsAdding(true);
|
|
137
|
+
};
|
|
138
|
+
// Check if current user has checked this milestone
|
|
139
|
+
const hasUserChecked = (milestone) => {
|
|
140
|
+
return milestone.checks.some(check => check.userId === currentUserId);
|
|
141
|
+
};
|
|
142
|
+
// Get users who haven't checked the milestone
|
|
143
|
+
const getUncheckedUsers = (milestone) => {
|
|
144
|
+
const checkedUserIds = new Set(milestone.checks.map(check => check.userId));
|
|
145
|
+
return allParticipants.filter(userId => !checkedUserIds.has(userId));
|
|
158
146
|
};
|
|
159
|
-
|
|
160
|
-
|
|
147
|
+
const groupedMilestones = milestones.reduce((acc, m) => {
|
|
148
|
+
const section = m.section || "General";
|
|
161
149
|
if (!acc[section])
|
|
162
150
|
acc[section] = [];
|
|
163
151
|
acc[section].push(m);
|
|
164
152
|
return acc;
|
|
165
153
|
}, {});
|
|
166
|
-
|
|
154
|
+
const panelClasses = isFullScreen
|
|
167
155
|
? "w-full h-full flex flex-col"
|
|
168
156
|
: "flex flex-col h-full w-full md:w-80 border-l border-gray-200 dark:border-gray-700";
|
|
169
|
-
return (_jsxs("div", { className:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
157
|
+
return (_jsxs("div", { className: `bg-white dark:bg-gray-900 ${panelClasses}`, children: [_jsx("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0", children: _jsx("h3", { className: "font-semibold text-gray-900 dark:text-white", children: "Milestones" }) }), _jsx("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: !isFeatureEnabled ? (_jsxs("div", { className: "flex flex-col items-center justify-center h-full py-12 px-6 text-center", children: [_jsx("div", { className: "mb-4 p-4 bg-teal-50 dark:bg-teal-900/20 rounded-full", children: _jsx(ListTodo, { className: "w-12 h-12 text-teal-500" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-2", children: "Milestones Feature" }), _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4 max-w-sm", children: "Track group tasks, organize by sections, and monitor progress together. Perfect for trip planning and group coordination." }), isAdmin ? (_jsxs(Button, { onClick: onEnableFeature, className: "bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700 text-white", children: [_jsx(Unlock, { className: "w-4 h-4 mr-2" }), "Enable Feature"] })) : (_jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [_jsx(Lock, { className: "w-4 h-4" }), "Ask admin to enable this feature"] }))] })) : loading ? (_jsx("div", { className: "flex justify-center py-8", children: _jsx("div", { className: "animate-spin w-5 h-5 border-2 border-teal-500 border-t-transparent rounded-full" }) })) : milestones.length === 0 && !isAdding ? (_jsx("div", { className: "text-center py-8 text-gray-400 text-sm", children: "No milestones yet" })) : (_jsxs(_Fragment, { children: [isAdding && (_jsxs("div", { className: "p-4 bg-gray-50 dark:bg-gray-800 rounded-lg space-y-3", children: [_jsx(Input, { placeholder: "Section (e.g., Day 1, Transport)", value: newSection, onChange: (e) => setNewSection(e.target.value), list: "section-suggestions", className: "text-sm" }), _jsx("datalist", { id: "section-suggestions", children: sections.map(section => (_jsx("option", { value: section }, section))) }), _jsx(Input, { placeholder: "Milestone title *", value: newTitle, onChange: (e) => setNewTitle(e.target.value), onKeyDown: (e) => e.key === "Enter" && !showMoreOptions && handleCreate(), className: "text-sm font-medium", autoFocus: true }), _jsxs("button", { type: "button", onClick: () => setShowMoreOptions(!showMoreOptions), className: "text-xs text-gray-600 dark:text-gray-400 hover:text-teal-600 dark:hover:text-teal-400 flex items-center gap-1 cursor-pointer", children: [showMoreOptions ? _jsx(ChevronDownIcon, { className: "w-3 h-3" }) : _jsx(ChevronRightIcon, { className: "w-3 h-3" }), " More Options"] }), showMoreOptions && (_jsxs("div", { className: "space-y-2 pl-4 border-l-2 border-teal-200 dark:border-teal-800", children: [_jsx(Textarea, { placeholder: "Description (optional)", value: newDescription, onChange: (e) => setNewDescription(e.target.value), className: "text-sm resize-none", rows: 2 }), _jsxs("div", { children: [_jsx("label", { className: "text-xs text-gray-600 dark:text-gray-400 block mb-1", children: "Due Date (optional)" }), _jsx(Input, { type: "date", value: newDueDate, onChange: (e) => setNewDueDate(e.target.value), className: "text-sm" })] })] })), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { onClick: handleCreate, size: "sm", className: "flex-1 bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700", children: "Add" }), _jsx(Button, { onClick: resetForm, size: "sm", variant: "outline", children: "Cancel" })] })] })), milestones.length > 0 && (Object.entries(groupedMilestones).map(([section, items]) => {
|
|
158
|
+
const isExpanded = expandedSections.has(section);
|
|
159
|
+
const completedCount = items.filter(m => m.isCompleted).length;
|
|
160
|
+
const totalCount = items.length;
|
|
161
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("button", { onClick: () => toggleSection(section), className: "w-full flex items-center justify-between p-3 bg-gradient-to-r from-teal-50 to-cyan-50 dark:from-teal-900/20 dark:to-cyan-900/20 hover:from-teal-100 hover:to-cyan-100 dark:hover:from-teal-900/30 dark:hover:to-cyan-900/30 rounded-lg border border-teal-100 dark:border-teal-800 transition-colors", children: [_jsxs("div", { className: "flex items-center gap-3 flex-1 text-left", children: [_jsx(ChevronDown, { className: `w-4 h-4 text-teal-600 dark:text-teal-400 transition-transform flex-shrink-0 ${isExpanded ? "" : "-rotate-90"}` }), _jsx("h4", { className: "text-sm font-semibold text-teal-900 dark:text-teal-100 uppercase tracking-widest", children: section })] }), _jsxs("span", { className: "text-xs font-semibold text-teal-700 dark:text-teal-300 bg-white dark:bg-gray-800 px-2.5 py-1 rounded-full flex-shrink-0", children: [completedCount, "/", totalCount] })] }), isExpanded && (_jsx("div", { className: "space-y-2 pl-4", children: items.map((milestone) => {
|
|
162
|
+
const userChecked = hasUserChecked(milestone);
|
|
163
|
+
const uncheckedUsers = getUncheckedUsers(milestone);
|
|
164
|
+
const isExpanded = expandedMilestones.has(milestone._id);
|
|
165
|
+
return (_jsxs("div", { className: "space-y-0", children: [_jsxs("button", { onClick: () => toggleMilestoneExpand(milestone._id), className: "w-full flex items-start gap-3 p-3 bg-gray-50 dark:bg-gray-800/30 hover:bg-gray-100 dark:hover:bg-gray-800/50 rounded-lg border border-gray-100 dark:border-gray-800 transition-colors group text-left", children: [_jsx("button", { onClick: (e) => {
|
|
166
|
+
e.stopPropagation();
|
|
167
|
+
handleToggle(milestone._id);
|
|
168
|
+
}, className: `mt-0.5 transition-colors flex-shrink-0 ${userChecked ? "text-green-500" : "text-gray-300 hover:text-teal-400"}`, children: userChecked ? _jsx(CheckCircle2, { className: "w-5 h-5" }) : _jsx(Circle, { className: "w-5 h-5" }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: `text-sm font-medium transition-all ${userChecked ? "text-gray-400 line-through" : "text-gray-700 dark:text-gray-200"}`, children: milestone.title }), milestone.dueDate && (_jsxs("p", { className: "text-[10px] text-gray-500 dark:text-gray-400 mt-1", children: ["Due: ", new Date(milestone.dueDate).toLocaleDateString()] }))] }), _jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [_jsxs("span", { className: `text-xs font-semibold px-2 py-1 rounded-full ${milestone.isCompleted
|
|
169
|
+
? "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400"
|
|
170
|
+
: "bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300"}`, children: [milestone.checks.length, "/", allParticipants.length] }), _jsx(ChevronDown, { className: `w-4 h-4 text-gray-400 transition-transform flex-shrink-0 ${isExpanded ? "" : "-rotate-90"}` })] }), (milestone.createdBy === currentUserId || isAdmin) && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { onClick: (e) => e.stopPropagation(), className: "p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md transition-all flex-shrink-0", children: _jsx(MoreVertical, { className: "w-4 h-4 text-gray-400" }) }) }), _jsxs(DropdownMenuContent, { align: "end", children: [_jsxs(DropdownMenuItem, { onClick: () => handleEdit(milestone), children: [_jsx(Pencil, { className: "w-4 h-4 mr-2" }), "Edit"] }), _jsxs(DropdownMenuItem, { className: "text-red-500", onClick: () => handleDelete(milestone._id), children: [_jsx(Trash2, { className: "w-4 h-4 mr-2" }), "Delete"] })] })] }))] }), isExpanded && (_jsxs("div", { className: "ml-8 bg-white dark:bg-gray-700/30 p-3 rounded-lg border border-gray-200 dark:border-gray-700 space-y-2", children: [milestone.description && (_jsxs("div", { children: [_jsx("p", { className: "text-[10px] font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider mb-1", children: "Description" }), _jsx("p", { className: "text-xs text-gray-700 dark:text-gray-300", children: milestone.description })] })), uncheckedUsers.length > 0 && (_jsxs("div", { children: [_jsxs("p", { className: "text-[10px] font-semibold text-gray-600 dark:text-gray-400 uppercase tracking-wider mb-1", children: ["Pending (", uncheckedUsers.length, ")"] }), _jsx("div", { className: "space-y-1", children: uncheckedUsers.map((userId) => (_jsxs("div", { className: "flex items-center gap-2 p-1.5 bg-yellow-50 dark:bg-yellow-900/20 rounded border border-yellow-100 dark:border-yellow-800/30", children: [_jsx(AlertCircle, { className: "w-3 h-3 text-yellow-600 dark:text-yellow-500 flex-shrink-0" }), _jsx("span", { className: "text-xs text-yellow-700 dark:text-yellow-300", children: userId })] }, userId))) })] })), milestone.isCompleted && (_jsxs("div", { className: "flex items-center gap-2 p-2 bg-green-50 dark:bg-green-900/20 rounded border border-green-200 dark:border-green-800/30", children: [_jsx(CheckCircle2, { className: "w-4 h-4 text-green-600 dark:text-green-400 flex-shrink-0" }), _jsx("p", { className: "text-xs text-green-700 dark:text-green-400 font-medium", children: "All participants have checked this milestone" })] }))] }))] }, milestone._id));
|
|
171
|
+
}) }))] }, section));
|
|
172
|
+
}))] })) }), isFeatureEnabled && !isAdding && (_jsx("div", { className: "p-4 border-t border-gray-200 dark:border-gray-700 flex-shrink-0", children: _jsxs(Button, { onClick: () => setIsAdding(true), className: "w-full bg-gradient-to-r from-teal-500 to-cyan-600 hover:from-teal-600 hover:to-cyan-700 text-white rounded-lg flex items-center justify-center gap-2", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Milestone"] }) }))] }));
|
|
173
173
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExpenseSplit } from "@myrjfa/state";
|
|
2
|
+
import { Dispatch, SetStateAction } from "react";
|
|
3
|
+
interface ParticipantSelectorProps {
|
|
4
|
+
participants: string[];
|
|
5
|
+
onChange: (participants: string[]) => void;
|
|
6
|
+
onSplitsChange: Dispatch<SetStateAction<ExpenseSplit[]>>;
|
|
7
|
+
availableUsers: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function ParticipantSelector({ participants, onChange, onSplitsChange, availableUsers }: ParticipantSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ParticipantSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParticipantSelector.d.ts","sourceRoot":"","sources":["../../../src/chat/components/ParticipantSelector.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEjD,UAAU,wBAAwB;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC3C,cAAc,EAAE,QAAQ,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IACzD,cAAc,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,CAAC,EAChC,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,cAAc,EACjB,EAAE,wBAAwB,2CA2D1B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { X } from "lucide-react";
|
|
4
|
+
export function ParticipantSelector({ participants, onChange, onSplitsChange, availableUsers }) {
|
|
5
|
+
const addParticipant = (userId) => {
|
|
6
|
+
if (!participants.includes(userId)) {
|
|
7
|
+
onChange([...participants, userId]);
|
|
8
|
+
onSplitsChange(prev => [...prev, { userId }]);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const removeParticipant = (userId) => {
|
|
12
|
+
onChange(participants.filter(p => p !== userId));
|
|
13
|
+
onSplitsChange(prev => prev.filter(s => s.userId !== userId));
|
|
14
|
+
};
|
|
15
|
+
const unselectedUsers = availableUsers.filter(u => !participants.includes(u));
|
|
16
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider", children: "Split Among" }), _jsx("div", { className: "flex flex-wrap gap-2", children: participants.length === 0 ? (_jsx("p", { className: "text-xs text-gray-500", children: "Select participants..." })) : (participants.map(userId => (_jsxs("div", { className: "flex items-center gap-1 bg-teal-100 dark:bg-teal-900/30 text-teal-700 dark:text-teal-300 rounded-full px-3 py-1 text-xs", children: [userId, _jsx("button", { onClick: () => removeParticipant(userId), className: "hover:text-teal-900 dark:hover:text-teal-100 transition-colors", children: _jsx(X, { className: "w-3 h-3" }) })] }, userId)))) }), unselectedUsers.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-1", children: unselectedUsers.map(userId => (_jsxs("button", { onClick: () => addParticipant(userId), className: "text-xs px-2 py-1 rounded-full border border-gray-300 dark:border-gray-600 text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors", children: ["+ ", userId] }, userId))) }))] }));
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SplitType, ExpenseSplit } from "@myrjfa/state/dist/lib/models/chat";
|
|
2
|
+
interface SplitInputsProps {
|
|
3
|
+
splitType: SplitType;
|
|
4
|
+
totalAmount: number;
|
|
5
|
+
participants: string[];
|
|
6
|
+
splits: ExpenseSplit[];
|
|
7
|
+
onChange: (splits: ExpenseSplit[]) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function SplitInputs({ splitType, totalAmount, participants, splits, onChange }: SplitInputsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=SplitInputs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitInputs.d.ts","sourceRoot":"","sources":["../../../src/chat/components/SplitInputs.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAGlF,UAAU,gBAAgB;IACtB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,WAAW,CAAC,EACxB,SAAS,EACT,WAAW,EACX,YAAY,EACZ,MAAM,EACN,QAAQ,EACX,EAAE,gBAAgB,kDA8KlB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from "react";
|
|
4
|
+
import { ChevronDown } from "lucide-react";
|
|
5
|
+
export function SplitInputs({ splitType, totalAmount, participants, splits, onChange }) {
|
|
6
|
+
const [isExpanded, setIsExpanded] = useState(splitType !== "equal");
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
setIsExpanded(splitType !== "equal");
|
|
9
|
+
}, [splitType]);
|
|
10
|
+
if (splitType === "equal") {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const handleInputChange = (userId, value, field) => {
|
|
14
|
+
const numValue = parseFloat(value) || 0;
|
|
15
|
+
const updatedSplits = splits.map(s => {
|
|
16
|
+
if (s.userId === userId) {
|
|
17
|
+
return { ...s, [field]: numValue, amount: field === "amount" ? numValue : s.amount };
|
|
18
|
+
}
|
|
19
|
+
return s;
|
|
20
|
+
});
|
|
21
|
+
// Auto-calculate amounts for percentage and shares
|
|
22
|
+
if (field === "percentage") {
|
|
23
|
+
updatedSplits.forEach(s => {
|
|
24
|
+
if (s.userId === userId) {
|
|
25
|
+
s.amount = (numValue / 100) * totalAmount;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else if (field === "shares") {
|
|
30
|
+
const totalShares = updatedSplits.reduce((sum, s) => sum + (s.shares || 0), 0);
|
|
31
|
+
updatedSplits.forEach(s => {
|
|
32
|
+
s.amount = (s.shares && s.shares > 0) ? (s.shares / totalShares) * totalAmount : 0;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
onChange(updatedSplits);
|
|
36
|
+
};
|
|
37
|
+
const getInputLabel = () => {
|
|
38
|
+
switch (splitType) {
|
|
39
|
+
case "exact":
|
|
40
|
+
return "Amount";
|
|
41
|
+
case "percentage":
|
|
42
|
+
return "Percentage";
|
|
43
|
+
case "shares":
|
|
44
|
+
return "Shares";
|
|
45
|
+
default:
|
|
46
|
+
return "Amount";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const validateSplits = () => {
|
|
50
|
+
if (splitType === "percentage") {
|
|
51
|
+
const total = splits.reduce((sum, s) => sum + (s.percentage || 0), 0);
|
|
52
|
+
return total === 100;
|
|
53
|
+
}
|
|
54
|
+
else if (splitType === "exact") {
|
|
55
|
+
const total = splits.reduce((sum, s) => sum + (s.amount || 0), 0);
|
|
56
|
+
return Math.abs(total - totalAmount) < 0.01;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
};
|
|
60
|
+
const isValid = getInputLabel();
|
|
61
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("button", { onClick: () => setIsExpanded(!isExpanded), className: "w-full flex items-center justify-between p-2 rounded-lg border border-gray-200 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors", children: [_jsx("span", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider", children: "Split Details" }), _jsx(ChevronDown, { className: `w-4 h-4 text-gray-400 transition-transform ${isExpanded ? "rotate-180" : ""}` })] }), isExpanded && (_jsx("div", { className: "bg-gray-50 dark:bg-gray-800/30 p-3 rounded-lg border border-gray-200 dark:border-gray-700 space-y-2", children: participants.length === 0 ? (_jsx("p", { className: "text-xs text-gray-500 text-center py-2", children: "Add participants to split expense" })) : (_jsxs(_Fragment, { children: [splits.map((split, idx) => {
|
|
62
|
+
var _a;
|
|
63
|
+
return (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "text-xs text-gray-600 dark:text-gray-400 flex-1 truncate font-medium", children: split.userId }), _jsxs("div", { className: "flex items-center gap-1 flex-1", children: [_jsx("input", { type: "number", step: "1", value: splitType === "exact"
|
|
64
|
+
? split.amount || ""
|
|
65
|
+
: splitType === "percentage"
|
|
66
|
+
? split.percentage || ""
|
|
67
|
+
: split.shares || "", onChange: (e) => handleInputChange(split.userId, e.target.value, splitType === "exact"
|
|
68
|
+
? "amount"
|
|
69
|
+
: splitType === "percentage"
|
|
70
|
+
? "percentage"
|
|
71
|
+
: "shares"), placeholder: "0", className: "w-20 bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded p-1 text-xs text-gray-900 dark:text-white outline-none focus:border-teal-500" }), _jsx("span", { className: "text-[10px] text-gray-500 min-w-fit", children: splitType === "percentage"
|
|
72
|
+
? "%"
|
|
73
|
+
: splitType === "shares"
|
|
74
|
+
? "shares"
|
|
75
|
+
: `₹${((_a = split.amount) === null || _a === void 0 ? void 0 : _a.toFixed(2)) || "0.00"}` })] })] }, split.userId));
|
|
76
|
+
}), splitType === "percentage" && (_jsx("div", { className: "text-[10px] text-gray-600 dark:text-gray-400 pt-2 border-t border-gray-200 dark:border-gray-600", children: _jsxs("p", { children: ["Total:", " ", _jsxs("span", { className: Math.abs(splits.reduce((sum, s) => sum + (s.percentage || 0), 0) -
|
|
77
|
+
100) < 0.01
|
|
78
|
+
? "text-green-600"
|
|
79
|
+
: "text-red-500", children: [splits.reduce((sum, s) => sum + (s.percentage || 0), 0).toFixed(1), "%"] })] }) })), splitType === "exact" && (_jsx("div", { className: "text-[10px] text-gray-600 dark:text-gray-400 pt-2 border-t border-gray-200 dark:border-gray-600", children: _jsxs("p", { children: ["Total:", " ", _jsxs("span", { className: Math.abs(splits.reduce((sum, s) => sum + (s.amount || 0), 0) -
|
|
80
|
+
totalAmount) < 0.01
|
|
81
|
+
? "text-green-600"
|
|
82
|
+
: "text-red-500", children: ["\u20B9", splits.reduce((sum, s) => sum + (s.amount || 0), 0).toFixed(2)] })] }) }))] })) }))] }));
|
|
83
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SplitType } from "@myrjfa/state/dist/lib/models/chat";
|
|
2
|
+
interface SplitTypeSelectorProps {
|
|
3
|
+
value: SplitType;
|
|
4
|
+
onChange: (type: SplitType) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function SplitTypeSelector({ value, onChange }: SplitTypeSelectorProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=SplitTypeSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitTypeSelector.d.ts","sourceRoot":"","sources":["../../../src/chat/components/SplitTypeSelector.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AAGpE,UAAU,sBAAsB;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC;AASD,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,sBAAsB,2CA4B5E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
const SPLIT_TYPES = [
|
|
4
|
+
{ value: "equal", label: "Equal", description: "Split evenly among all" },
|
|
5
|
+
{ value: "exact", label: "Exact", description: "Specify exact amounts" },
|
|
6
|
+
{ value: "percentage", label: "Percentage", description: "Split by percentages" },
|
|
7
|
+
{ value: "shares", label: "Shares", description: "Split by number of shares" }
|
|
8
|
+
];
|
|
9
|
+
export function SplitTypeSelector({ value, onChange }) {
|
|
10
|
+
return (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider", children: "Split Type" }), _jsx("div", { className: "grid grid-cols-2 gap-2", children: SPLIT_TYPES.map((type) => (_jsxs("button", { onClick: () => onChange(type.value), className: `p-2 rounded-lg border-2 transition-all text-left ${value === type.value
|
|
11
|
+
? "border-teal-500 bg-teal-50 dark:bg-teal-900/20"
|
|
12
|
+
: "border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`, children: [_jsx("p", { className: "text-sm font-semibold text-gray-900 dark:text-white", children: type.label }), _jsx("p", { className: "text-[10px] text-gray-500 dark:text-gray-400", children: type.description })] }, type.value))) })] }));
|
|
13
|
+
}
|