@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.
Files changed (131) hide show
  1. package/dist/chat/ChatMain.d.ts.map +1 -1
  2. package/dist/chat/ChatMain.js +173 -145
  3. package/dist/chat/ChatSidebar.js +7 -8
  4. package/dist/chat/ConversationList.d.ts.map +1 -1
  5. package/dist/chat/ConversationList.js +20 -18
  6. package/dist/chat/ExpensePanel.d.ts +4 -1
  7. package/dist/chat/ExpensePanel.d.ts.map +1 -1
  8. package/dist/chat/ExpensePanel.js +215 -195
  9. package/dist/chat/MessageBubble.d.ts +5 -3
  10. package/dist/chat/MessageBubble.d.ts.map +1 -1
  11. package/dist/chat/MessageBubble.js +185 -103
  12. package/dist/chat/MessageInput.d.ts +8 -1
  13. package/dist/chat/MessageInput.d.ts.map +1 -1
  14. package/dist/chat/MessageInput.js +182 -165
  15. package/dist/chat/MilestonePanel.d.ts +4 -1
  16. package/dist/chat/MilestonePanel.d.ts.map +1 -1
  17. package/dist/chat/MilestonePanel.js +150 -150
  18. package/dist/chat/components/ParticipantSelector.d.ts +11 -0
  19. package/dist/chat/components/ParticipantSelector.d.ts.map +1 -0
  20. package/dist/chat/components/ParticipantSelector.js +17 -0
  21. package/dist/chat/components/SplitInputs.d.ts +11 -0
  22. package/dist/chat/components/SplitInputs.d.ts.map +1 -0
  23. package/dist/chat/components/SplitInputs.js +83 -0
  24. package/dist/chat/components/SplitTypeSelector.d.ts +8 -0
  25. package/dist/chat/components/SplitTypeSelector.d.ts.map +1 -0
  26. package/dist/chat/components/SplitTypeSelector.js +13 -0
  27. package/dist/chat/dialogs/AddMemberDialog.js +30 -90
  28. package/dist/chat/dialogs/CameraDialog.js +38 -86
  29. package/dist/chat/dialogs/CreatePollDialog.d.ts +8 -0
  30. package/dist/chat/dialogs/CreatePollDialog.d.ts.map +1 -0
  31. package/dist/chat/dialogs/CreatePollDialog.js +38 -0
  32. package/dist/chat/dialogs/ExpenseAnalyticsDialog.d.ts +19 -0
  33. package/dist/chat/dialogs/ExpenseAnalyticsDialog.d.ts.map +1 -0
  34. package/dist/chat/dialogs/ExpenseAnalyticsDialog.js +52 -0
  35. package/dist/chat/dialogs/GroupInfoDialog.d.ts.map +1 -1
  36. package/dist/chat/dialogs/GroupInfoDialog.js +55 -92
  37. package/dist/chat/dialogs/GroupInfoViewDialog.js +5 -6
  38. package/dist/chat/dialogs/NewChatDialog.d.ts.map +1 -1
  39. package/dist/chat/dialogs/NewChatDialog.js +49 -113
  40. package/dist/chat/dialogs/NewGroupDialog.d.ts.map +1 -1
  41. package/dist/chat/dialogs/NewGroupDialog.js +49 -92
  42. package/dist/chat/dialogs/ParticipantsDialog.d.ts.map +1 -1
  43. package/dist/chat/dialogs/ParticipantsDialog.js +68 -118
  44. package/dist/chat/dialogs/UserProfileDialog.d.ts +10 -0
  45. package/dist/chat/dialogs/UserProfileDialog.d.ts.map +1 -0
  46. package/dist/chat/dialogs/UserProfileDialog.js +100 -0
  47. package/dist/dashboard/action-buttons.js +4 -5
  48. package/dist/dashboard/app-sidebar.js +46 -128
  49. package/dist/dashboard/card-header.js +1 -2
  50. package/dist/dashboard/dashboard-components.js +3 -5
  51. package/dist/dashboard/data-table.js +21 -33
  52. package/dist/dashboard/nav-main.js +4 -5
  53. package/dist/dashboard/nav-secondary.js +2 -25
  54. package/dist/dashboard/stats-card.js +1 -2
  55. package/dist/dashboard/table.js +8 -54
  56. package/dist/header/mobile-nav-item.js +1 -2
  57. package/dist/header/mobile-navbar.js +8 -9
  58. package/dist/header/nav-item.js +1 -2
  59. package/dist/index.d.ts +1 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +1 -1
  62. package/dist/main/footer.js +5 -9
  63. package/dist/main/navbar.js +53 -136
  64. package/dist/main/paginationBar.js +12 -14
  65. package/dist/main/portfolio/portfolioItem.js +1 -2
  66. package/dist/main/portfolio/portfolioPopup.js +16 -17
  67. package/dist/main/review-page.d.ts.map +1 -1
  68. package/dist/main/review-page.js +131 -198
  69. package/dist/misc/accordion.js +8 -34
  70. package/dist/misc/alert-dialog.js +22 -55
  71. package/dist/misc/alert.js +7 -32
  72. package/dist/misc/alertdialogclaude.js +50 -125
  73. package/dist/misc/avatar.js +6 -31
  74. package/dist/misc/badge.js +4 -27
  75. package/dist/misc/button.js +4 -27
  76. package/dist/misc/card.js +12 -40
  77. package/dist/misc/carousel.js +37 -61
  78. package/dist/misc/checkbox.js +2 -25
  79. package/dist/misc/command.js +18 -49
  80. package/dist/misc/datepicker.js +66 -76
  81. package/dist/misc/dialog.js +20 -52
  82. package/dist/misc/dropdown-menu.js +30 -67
  83. package/dist/misc/faq.js +2 -3
  84. package/dist/misc/file-preview.js +43 -97
  85. package/dist/misc/filter.d.ts.map +1 -1
  86. package/dist/misc/filter.js +18 -21
  87. package/dist/misc/filterBar.js +136 -160
  88. package/dist/misc/form.js +39 -60
  89. package/dist/misc/image-cropper.d.ts +10 -0
  90. package/dist/misc/image-cropper.d.ts.map +1 -0
  91. package/dist/misc/image-cropper.js +44 -0
  92. package/dist/misc/input.js +2 -25
  93. package/dist/misc/label.js +2 -25
  94. package/dist/misc/line-carousel.js +3 -13
  95. package/dist/misc/multiImageUploader.js +2 -3
  96. package/dist/misc/newsLetter.js +18 -78
  97. package/dist/misc/notification.d.ts +1 -2
  98. package/dist/misc/notification.d.ts.map +1 -1
  99. package/dist/misc/notification.js +89 -125
  100. package/dist/misc/pagination.js +16 -45
  101. package/dist/misc/password-eye.js +2 -3
  102. package/dist/misc/popover.d.ts.map +1 -1
  103. package/dist/misc/popover.js +8 -34
  104. package/dist/misc/progress.js +2 -25
  105. package/dist/misc/scroll-area.js +5 -29
  106. package/dist/misc/searchBar.js +27 -31
  107. package/dist/misc/searchBox.js +18 -22
  108. package/dist/misc/select.d.ts.map +1 -1
  109. package/dist/misc/select.js +22 -54
  110. package/dist/misc/separator.js +2 -25
  111. package/dist/misc/share.js +48 -104
  112. package/dist/misc/sheet.js +21 -53
  113. package/dist/misc/sidebar.js +112 -153
  114. package/dist/misc/skeleton.js +2 -25
  115. package/dist/misc/slider.js +3 -26
  116. package/dist/misc/starRating.js +5 -15
  117. package/dist/misc/stateCard.js +7 -8
  118. package/dist/misc/switch.d.ts +5 -0
  119. package/dist/misc/switch.d.ts.map +1 -0
  120. package/dist/misc/switch.js +8 -0
  121. package/dist/misc/tabs.js +8 -34
  122. package/dist/misc/textarea.js +2 -25
  123. package/dist/misc/tile.js +31 -92
  124. package/dist/misc/tooltip.js +8 -34
  125. package/dist/profile/socialLink.d.ts +1 -1
  126. package/dist/profile/socialLink.d.ts.map +1 -1
  127. package/dist/profile/socialLink.js +53 -69
  128. package/dist/utils/permissions.d.ts +7 -0
  129. package/dist/utils/permissions.d.ts.map +1 -0
  130. package/dist/utils/permissions.js +38 -0
  131. package/package.json +3 -2
@@ -1,29 +1,6 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
- var __rest = (this && this.__rest) || function (s, e) {
13
- var t = {};
14
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
- t[p] = s[p];
16
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
- t[p[i]] = s[p[i]];
20
- }
21
- return t;
22
- };
23
1
  import { jsx as _jsx } from "react/jsx-runtime";
24
2
  import { cn } from "@myrjfa/state/dist/lib/utils";
25
- function Textarea(_a) {
26
- var className = _a.className, props = __rest(_a, ["className"]);
27
- return (_jsx("textarea", __assign({ "data-slot": "textarea", className: cn("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className) }, props)));
3
+ function Textarea({ className, ...props }) {
4
+ return (_jsx("textarea", { "data-slot": "textarea", className: cn("border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", className), ...props }));
28
5
  }
29
6
  export { Textarea };
package/dist/misc/tile.js CHANGED
@@ -1,51 +1,4 @@
1
1
  'use client';
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- 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);
24
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- 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;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
50
3
  import { toggleUserWishlist } from "@myrjfa/state/dist/lib/actions";
51
4
  import { userAtom, userLoadingAtom } from "@myrjfa/state/dist/lib/userAtom";
@@ -59,21 +12,18 @@ import { showAlert } from "./alertdialogclaude";
59
12
  import { Badge } from "./badge";
60
13
  import { Button } from "./button";
61
14
  import { Card, CardContent } from "./card";
62
- function WishlistButton(_a) {
63
- var wishlisted = _a.wishlisted, handleWishlisted = _a.handleWishlisted;
15
+ function WishlistButton({ wishlisted, handleWishlisted }) {
64
16
  return _jsx(Button, { variant: "ghost", className: "absolute top-3 right-3 z-10 bg-white/70 hover:bg-white rounded-full transition", onClick: handleWishlisted, children: _jsx(Heart, { className: wishlisted ? "text-red-500 fill-red-500 drop-shadow" : "text-gray-400 fill-gray-400", size: 20 }) });
65
17
  }
66
18
  ;
67
- export function Tile(_a) {
68
- var _this = this;
69
- var _b, _c, _d, _e;
70
- var slug = _a.slug, image = _a.image, title = _a.title, description = _a.description, location = _a.location, rating = _a.rating, _f = _a.skills, skills = _f === void 0 ? [] : _f, _g = _a.tileType, tileType = _g === void 0 ? "opportunities" : _g, className = _a.className, date = _a.date, _h = _a.host, host = _h === void 0 ? undefined : _h, _j = _a.duration, duration = _j === void 0 ? 1 : _j, _k = _a.price, price = _k === void 0 ? 0.0 : _k, _l = _a.currency, currency = _l === void 0 ? "INR" : _l, _m = _a.includeHost, includeHost = _m === void 0 ? true : _m;
71
- var _o = useAtom(userAtom), user = _o[0], setUser = _o[1];
72
- var loading = useAtomValue(userLoadingAtom);
73
- var router = useRouter();
74
- var _p = useState(false), wishlisted = _p[0], setWishlisted = _p[1];
75
- var _q = useState(false), clicked = _q[0], setClicked = _q[1];
76
- useEffect(function () {
19
+ export function Tile({ slug, image, title, description, location, rating, skills = [], tileType = "opportunities", className, date, host = undefined, duration = 1, price = 0.0, currency = "INR", includeHost = true, }) {
20
+ var _a, _b, _c, _d;
21
+ const [user, setUser] = useAtom(userAtom);
22
+ const loading = useAtomValue(userLoadingAtom);
23
+ const router = useRouter();
24
+ const [wishlisted, setWishlisted] = useState(false);
25
+ const [clicked, setClicked] = useState(false);
26
+ useEffect(() => {
77
27
  var _a, _b, _c, _d;
78
28
  if (loading || !user)
79
29
  return;
@@ -84,41 +34,30 @@ export function Tile(_a) {
84
34
  setWishlisted((_d = (_c = user.favPackages) === null || _c === void 0 ? void 0 : _c.includes(slug)) !== null && _d !== void 0 ? _d : false);
85
35
  }
86
36
  }, [slug, loading, user]);
87
- var handleWishlisted = function (e) { return __awaiter(_this, void 0, void 0, function () {
88
- var response;
89
- return __generator(this, function (_a) {
90
- switch (_a.label) {
91
- case 0:
92
- e.stopPropagation();
93
- return [4 /*yield*/, toggleUserWishlist(slug, tileType)];
94
- case 1:
95
- response = _a.sent();
96
- if (!(response === null || response === void 0 ? void 0 : response.error)) return [3 /*break*/, 3];
97
- return [4 /*yield*/, showAlert(response.error)];
98
- case 2:
99
- _a.sent();
100
- return [2 /*return*/];
101
- case 3:
102
- if (tileType == "opportunities") {
103
- setUser(function (prev) { return prev ? __assign(__assign({}, prev), { wishlist: response.wishlist }) : prev; });
104
- }
105
- else if (tileType == "packages") {
106
- setUser(function (prev) { return prev ? __assign(__assign({}, prev), { favPackages: response.wishlist }) : prev; });
107
- }
108
- return [2 /*return*/];
109
- }
110
- });
111
- }); };
112
- var handleTileClick = function () {
37
+ const handleWishlisted = async (e) => {
38
+ e.stopPropagation();
39
+ const response = await toggleUserWishlist(slug, tileType);
40
+ if (response === null || response === void 0 ? void 0 : response.error) {
41
+ await showAlert(response.error);
42
+ return;
43
+ }
44
+ if (tileType == "opportunities") {
45
+ setUser((prev) => prev ? { ...prev, wishlist: response.wishlist } : prev);
46
+ }
47
+ else if (tileType == "packages") {
48
+ setUser((prev) => prev ? { ...prev, favPackages: response.wishlist } : prev);
49
+ }
50
+ };
51
+ const handleTileClick = () => {
113
52
  if (clicked)
114
53
  return; // prevent duplicate navigation
115
54
  setClicked(true);
116
- router.push("/".concat(tileType, "/").concat(slug));
55
+ router.push(`/${tileType}/${slug}`);
117
56
  };
118
- var formatPrice = function (price, currency) {
57
+ const formatPrice = (price, currency) => {
119
58
  return new Intl.NumberFormat('en-IN', {
120
59
  style: 'currency',
121
- currency: currency,
60
+ currency,
122
61
  maximumFractionDigits: 0
123
62
  }).format(price);
124
63
  };
@@ -127,11 +66,11 @@ export function Tile(_a) {
127
66
  WebkitMaskImage: "linear-gradient(to bottom, rgba(0,0,0,1) 90%, rgba(255, 255, 255, 0) 100%)",
128
67
  WebkitMaskRepeat: "no-repeat",
129
68
  WebkitMaskSize: "100% 100%",
130
- }, onError: function (e) { return console.error(e.target); } }), _jsx("div", { className: "absolute bottom-0 left-0 right-0 h-5 pointer-events-none bg-gradient-to-b from-transparent to-white" }), user && user.role == "user" && tileType !== "blogs" && (_jsx(WishlistButton, { wishlisted: wishlisted, handleWishlisted: handleWishlisted })), tileType == "packages" && (_jsx("div", { className: "absolute top-4 left-4 bg-white/80 backdrop-blur px-3 py-1 rounded-full shadow text-gray-900 font-semibold text-base", children: formatPrice(price, currency) }))] }), _jsxs(CardContent, { className: "p-4 pt-0 flex flex-col gap-3 z-10", children: [tileType !== "blogs" && (_jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [location && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(MapPin, { size: 15 }), " ", truncateText(location, 30)] })), (rating && rating > 0) ? _jsxs("div", { className: "flex items-center gap-1 bg-green-50 px-2 py-1 rounded-full", children: [_jsx(Star, { className: "w-4 h-4 text-amber-400 fill-current" }), _jsx("span", { className: " font-semibold", children: rating })] })
69
+ }, onError: (e) => console.error(e.target) }), _jsx("div", { className: "absolute bottom-0 left-0 right-0 h-5 pointer-events-none bg-gradient-to-b from-transparent to-white" }), user && user.role == "user" && tileType !== "blogs" && (_jsx(WishlistButton, { wishlisted: wishlisted, handleWishlisted: handleWishlisted })), tileType == "packages" && (_jsx("div", { className: "absolute top-4 left-4 bg-white/80 backdrop-blur px-3 py-1 rounded-full shadow text-gray-900 font-semibold text-base", children: formatPrice(price, currency) }))] }), _jsxs(CardContent, { className: "p-4 pt-0 flex flex-col gap-3 z-10", children: [tileType !== "blogs" && (_jsxs("div", { className: "flex justify-between text-sm text-muted-foreground", children: [location && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(MapPin, { size: 15 }), " ", truncateText(location, 30)] })), (rating && rating > 0) ? _jsxs("div", { className: "flex items-center gap-1 bg-green-50 px-2 py-1 rounded-full", children: [_jsx(Star, { className: "w-4 h-4 text-amber-400 fill-current" }), _jsx("span", { className: " font-semibold", children: rating })] })
131
70
  : null] })), _jsx("h4", { className: "text-lg font-semibold truncate-text", children: truncateText(title, 30) }), tileType !== "packages" &&
132
- _jsx("p", { className: "text-sm text-muted-foreground truncate-text-3", children: description }), tileType == "opportunities" && skills.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-2 truncate-text", children: skills.slice(0, 3).map(function (skill, index) { return (_jsx(Badge, { variant: "secondary", children: truncateText(skill, 10) }, index)); }) })), tileType == "blogs" && (includeHost ?
133
- _jsxs("div", { className: "flex items-center gap-3 pt-3 border-t min-h-12 max-h-15", children: [_jsx(Image, { src: (_b = host === null || host === void 0 ? void 0 : host.image) !== null && _b !== void 0 ? _b : "/images/profile_placeholder.webp", alt: "Host Image", width: 40, height: 40, className: "rounded-full object-cover" }), _jsxs("div", { className: "flex-1", children: [_jsxs("p", { className: "font-medium", children: ["By ", truncateText((_c = host === null || host === void 0 ? void 0 : host.name) !== null && _c !== void 0 ? _c : "Host", 18)] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["on ", formatDate(date)] })] })] }) :
71
+ _jsx("p", { className: "text-sm text-muted-foreground truncate-text-3", children: description }), tileType == "opportunities" && skills.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-2 truncate-text", children: skills.slice(0, 3).map((skill, index) => (_jsx(Badge, { variant: "secondary", children: truncateText(skill, 10) }, index))) })), tileType == "blogs" && (includeHost ?
72
+ _jsxs("div", { className: "flex items-center gap-3 pt-3 border-t min-h-12 max-h-15", children: [_jsx(Image, { src: (_a = host === null || host === void 0 ? void 0 : host.image) !== null && _a !== void 0 ? _a : "/images/profile_placeholder.webp", alt: "Host Image", width: 40, height: 40, className: "rounded-full object-cover" }), _jsxs("div", { className: "flex-1", children: [_jsxs("p", { className: "font-medium", children: ["By ", truncateText((_b = host === null || host === void 0 ? void 0 : host.name) !== null && _b !== void 0 ? _b : "Host", 18)] }), _jsxs("p", { className: "text-xs text-muted-foreground", children: ["on ", formatDate(date)] })] })] }) :
134
73
  _jsxs("div", { className: "flex justify-between items-center text-xs text-gray-500", children: [_jsx("span", { children: formatDate(date) }), _jsxs("span", { children: [rating, " likes"] })] })), tileType == "packages" && (_jsxs("div", { className: "flex items-center justify-between pt-3 border-t border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-1 text-gray-600 whitespace-nowrap", children: [_jsx(Clock, { className: "w-4 h-4 mr-1" }), _jsxs("span", { className: "text-sm", children: [duration, " Days"] })] }), includeHost ?
135
- _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Image, { src: (_d = host === null || host === void 0 ? void 0 : host.image) !== null && _d !== void 0 ? _d : "/images/profile_placeholder.webp", alt: (_e = host === null || host === void 0 ? void 0 : host.name) !== null && _e !== void 0 ? _e : "DP", width: 25, height: 25, className: "rounded-full" }), _jsx("span", { className: "text-sm text-gray-500 max-w-40", children: host === null || host === void 0 ? void 0 : host.name })] }) :
74
+ _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Image, { src: (_c = host === null || host === void 0 ? void 0 : host.image) !== null && _c !== void 0 ? _c : "/images/profile_placeholder.webp", alt: (_d = host === null || host === void 0 ? void 0 : host.name) !== null && _d !== void 0 ? _d : "DP", width: 25, height: 25, className: "rounded-full" }), _jsx("span", { className: "text-sm text-gray-500 max-w-40", children: host === null || host === void 0 ? void 0 : host.name })] }) :
136
75
  _jsx("div", { className: "flex justify-between items-center text-xs text-gray-500", children: _jsx("span", { children: formatDate(date) }) })] }))] })] }));
137
76
  }
@@ -1,43 +1,17 @@
1
1
  "use client";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __rest = (this && this.__rest) || function (s, e) {
14
- var t = {};
15
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
- t[p] = s[p];
17
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
- t[p[i]] = s[p[i]];
21
- }
22
- return t;
23
- };
24
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
25
3
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
26
4
  import { cn } from "@myrjfa/state/dist/lib/utils";
27
- function TooltipProvider(_a) {
28
- var _b = _a.delayDuration, delayDuration = _b === void 0 ? 0 : _b, props = __rest(_a, ["delayDuration"]);
29
- return (_jsx(TooltipPrimitive.Provider, __assign({ "data-slot": "tooltip-provider", delayDuration: delayDuration }, props)));
5
+ function TooltipProvider({ delayDuration = 0, ...props }) {
6
+ return (_jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration: delayDuration, ...props }));
30
7
  }
31
- function Tooltip(_a) {
32
- var props = __rest(_a, []);
33
- return (_jsx(TooltipProvider, { children: _jsx(TooltipPrimitive.Root, __assign({ "data-slot": "tooltip" }, props)) }));
8
+ function Tooltip({ ...props }) {
9
+ return (_jsx(TooltipProvider, { children: _jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props }) }));
34
10
  }
35
- function TooltipTrigger(_a) {
36
- var props = __rest(_a, []);
37
- return _jsx(TooltipPrimitive.Trigger, __assign({ "data-slot": "tooltip-trigger" }, props));
11
+ function TooltipTrigger({ ...props }) {
12
+ return _jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
38
13
  }
39
- function TooltipContent(_a) {
40
- var className = _a.className, _b = _a.sideOffset, sideOffset = _b === void 0 ? 0 : _b, children = _a.children, props = __rest(_a, ["className", "sideOffset", "children"]);
41
- return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, __assign({ "data-slot": "tooltip-content", sideOffset: sideOffset, className: cn("bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance", className) }, props, { children: [children, _jsx(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })] })) }));
14
+ function TooltipContent({ className, sideOffset = 0, children, ...props }) {
15
+ return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { "data-slot": "tooltip-content", sideOffset: sideOffset, className: cn("bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance", className), ...props, children: [children, _jsx(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })] }) }));
42
16
  }
43
17
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -1,4 +1,4 @@
1
- export type SocialPlatformType = "instagram" | "youtube" | "linkedin" | "googleBusiness";
1
+ import { SocialPlatformType } from "@myrjfa/state/dist/lib/utils/socialMediaUrl";
2
2
  interface SocialLinkFieldProps {
3
3
  platform: SocialPlatformType;
4
4
  url?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"socialLink.d.ts","sourceRoot":"","sources":["../../src/profile/socialLink.tsx"],"names":[],"mappings":"AAQA,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAEzF,UAAU,oBAAoB;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvF;AAYD,wBAAgB,eAAe,CAAC,EAC5B,QAAQ,EACR,GAAG,EACH,aAAa,EACb,oBAAoB,GACvB,EAAE,oBAAoB,kDA8CtB"}
1
+ {"version":3,"file":"socialLink.d.ts","sourceRoot":"","sources":["../../src/profile/socialLink.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAsB,kBAAkB,EAAE,MAAM,6CAA6C,CAAC;AAGrG,UAAU,oBAAoB;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvF;AAeD,wBAAgB,eAAe,CAAC,EAC5B,QAAQ,EACR,GAAG,EACH,aAAa,EACb,oBAAoB,GACvB,EAAE,oBAAoB,kDAgFtB"}
@@ -1,81 +1,65 @@
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
3
  import { useState } from "react";
40
4
  import { Input } from "../misc/input";
41
5
  import { Button } from "../misc/button";
42
- import { InstagramIcon, YoutubeIcon, LinkedinIcon, StoreIcon } from "lucide-react";
43
- import { useRouter } from "next/navigation";
44
- var platformConfig = {
45
- instagram: { label: "Instagram", icon: InstagramIcon, color: "hover:text-pink-600" },
46
- youtube: { label: "YouTube", icon: YoutubeIcon, color: "hover:text-red-600" },
47
- linkedin: { label: "LinkedIn", icon: LinkedinIcon, color: "hover:text-blue-600" },
48
- googleBusiness: { label: "Google Business", icon: StoreIcon, color: "hover:text-green-600" },
6
+ import { GithubIcon, InstagramIcon, StoreIcon, YoutubeIcon } from "lucide-react";
7
+ import { normalizeSocialUrl } from "@myrjfa/state/dist/lib/utils/socialMediaUrl";
8
+ import { FacebookIcon, LinkedinIcon, TwitterIcon } from "react-share";
9
+ const platformConfig = {
10
+ instagram: { label: "Instagram", icon: InstagramIcon, color: "hover:text-pink-600", hint: "Enter username or profile URL" },
11
+ youtube: { label: "YouTube", icon: YoutubeIcon, color: "hover:text-red-600", hint: "Enter @handle or profile URL" },
12
+ twitter: { label: "Twitter", icon: TwitterIcon, color: "hover:text-blue-600", hint: "Enter @handle or profile URL" },
13
+ facebook: { label: "Facebook", icon: FacebookIcon, color: "hover:text-blue-600", hint: "Enter @handle or profile URL" },
14
+ github: { label: "GitHub", icon: GithubIcon, color: "hover:text-blue-600", hint: "Enter @handle or profile URL" },
15
+ linkedin: { label: "LinkedIn", icon: LinkedinIcon, color: "hover:text-blue-600", hint: "Enter username or profile URL" },
16
+ googleBusiness: { label: "Google Business", icon: StoreIcon, color: "hover:text-green-600", hint: "Enter full Google Business URL" },
49
17
  };
50
- export function SocialLinkField(_a) {
51
- var _this = this;
52
- var platform = _a.platform, url = _a.url, isCurrentUser = _a.isCurrentUser, updateUserSocialLink = _a.updateUserSocialLink;
53
- var _b = useState(url), input = _b[0], setInput = _b[1];
54
- var _c = useState(false), loading = _c[0], setLoading = _c[1];
55
- var router = useRouter();
56
- var _d = platformConfig[platform], label = _d.label, Icon = _d.icon, color = _d.color;
18
+ export function SocialLinkField({ platform, url, isCurrentUser, updateUserSocialLink, }) {
19
+ const [input, setInput] = useState(url !== null && url !== void 0 ? url : "");
20
+ const [urlError, setUrlError] = useState(null);
21
+ const [loading, setLoading] = useState(false);
22
+ const { label, icon: Icon, color, hint } = platformConfig[platform];
23
+ // #13: Validate and normalize the URL when focus leaves the input
24
+ const handleBlur = () => {
25
+ if (!input.trim() || platform === "googleBusiness")
26
+ return;
27
+ const { url: normalized, error } = normalizeSocialUrl(platform, input);
28
+ setUrlError(error);
29
+ if (!error)
30
+ setInput(normalized); // auto-correct the field to canonical URL
31
+ };
32
+ const handleSave = async () => {
33
+ if (!input.trim() || !updateUserSocialLink)
34
+ return;
35
+ // Final normalization before saving
36
+ let finalUrl = input;
37
+ if (platform !== "googleBusiness") {
38
+ const { url: normalized, error } = normalizeSocialUrl(platform, input);
39
+ if (error) {
40
+ setUrlError(error);
41
+ return;
42
+ }
43
+ finalUrl = normalized;
44
+ setInput(normalized);
45
+ }
46
+ try {
47
+ setLoading(true);
48
+ await updateUserSocialLink(platform, finalUrl);
49
+ setUrlError(null);
50
+ }
51
+ finally {
52
+ setLoading(false);
53
+ }
54
+ };
57
55
  if (isCurrentUser) {
58
- return (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Input, { type: "url", placeholder: "".concat(label, " profile url"), value: input, onChange: function (e) { return setInput(e.target.value); } }), updateUserSocialLink &&
59
- _jsx(Button, { disabled: loading || !input, onClick: function () { return __awaiter(_this, void 0, void 0, function () {
60
- return __generator(this, function (_a) {
61
- switch (_a.label) {
62
- case 0:
63
- _a.trys.push([0, , 2, 3]);
64
- setLoading(true);
65
- return [4 /*yield*/, updateUserSocialLink(platform, input)];
66
- case 1:
67
- _a.sent();
68
- return [3 /*break*/, 3];
69
- case 2:
70
- setLoading(false);
71
- return [7 /*endfinally*/];
72
- case 3: return [2 /*return*/];
73
- }
74
- });
75
- }); }, children: "Add" })] }));
56
+ return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Icon, { className: `h-5 w-5 shrink-0 text-gray-400 ${color}` }), _jsx(Input, { type: "text", placeholder: hint, value: input, onChange: (e) => {
57
+ setInput(e.target.value);
58
+ setUrlError(null);
59
+ }, onBlur: handleBlur, className: urlError ? "border-red-400 focus:ring-red-400" : "" }), _jsx(Button, { disabled: loading || !input.trim(), onClick: handleSave, children: loading ? "Adding..." : "Add" })] }), urlError && (_jsx("p", { className: "text-xs text-red-500 ml-6", children: urlError }))] }));
76
60
  }
77
61
  else if (url) {
78
- return (_jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: "text-gray-500 ".concat(color, " flex flex-row gap-1"), children: _jsx(Icon, { className: "h-5 w-5" }) }));
62
+ return (_jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", className: `text-gray-500 ${color} flex flex-row gap-1`, children: _jsx(Icon, { className: "h-5 w-5" }) }));
79
63
  }
80
64
  else
81
65
  return null;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Utility functions for checking browser permissions
3
+ */
4
+ export declare const checkPhonePermission: () => Promise<boolean>;
5
+ export declare const checkMicrophonePermission: () => Promise<boolean>;
6
+ export declare const checkCameraPermission: () => Promise<boolean>;
7
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,OAAO,CAI5D,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,OAAO,CAejE,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,OAAO,CAa7D,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Utility functions for checking browser permissions
3
+ */
4
+ export const checkPhonePermission = async () => {
5
+ // For phone calls, we don't need microphone permission
6
+ // Just check if the device supports tel: protocol
7
+ return true;
8
+ };
9
+ export const checkMicrophonePermission = async () => {
10
+ if (!('permissions' in navigator)) {
11
+ // Assume granted if API not available
12
+ return true;
13
+ }
14
+ try {
15
+ const result = await navigator.permissions.query({
16
+ name: 'microphone'
17
+ });
18
+ return result.state === 'granted' || result.state === 'prompt';
19
+ }
20
+ catch (_a) {
21
+ // Fallback to true if query fails
22
+ return true;
23
+ }
24
+ };
25
+ export const checkCameraPermission = async () => {
26
+ if (!('permissions' in navigator)) {
27
+ return true;
28
+ }
29
+ try {
30
+ const result = await navigator.permissions.query({
31
+ name: 'camera'
32
+ });
33
+ return result.state === 'granted' || result.state === 'prompt';
34
+ }
35
+ catch (_a) {
36
+ return true;
37
+ }
38
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrjfa/ui",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Shared UI components for my apps",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,6 +37,7 @@
37
37
  "embla-carousel-react": "^8.5.2",
38
38
  "emoji-picker-react": "^4.18.0",
39
39
  "pnpm": "^10.14.0",
40
+ "react-easy-crop": "^5.5.6",
40
41
  "react-hook-form": "^7.54.2",
41
42
  "react-icons": "^5.5.0",
42
43
  "react-share": "^5.2.2"
@@ -52,7 +53,7 @@
52
53
  "zod": "*"
53
54
  },
54
55
  "devDependencies": {
55
- "@myrjfa/state": "1.1.0",
56
+ "@myrjfa/state": "1.1.1",
56
57
  "@types/react": "19.0.10",
57
58
  "@types/react-dom": "^19.0.4",
58
59
  "date-fns": "^3.0.0",