@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
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ interface ImageCropperProps {
3
+ image: string;
4
+ onCancel: () => void;
5
+ onCropComplete: (croppedImage: Blob) => void;
6
+ open: boolean;
7
+ }
8
+ declare const ImageCropper: React.FC<ImageCropperProps>;
9
+ export default ImageCropper;
10
+ //# sourceMappingURL=image-cropper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-cropper.d.ts","sourceRoot":"","sources":["../../src/misc/image-cropper.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAMrD,UAAU,iBAAiB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,cAAc,EAAE,CAAC,YAAY,EAAE,IAAI,KAAK,IAAI,CAAC;IAC7C,IAAI,EAAE,OAAO,CAAC;CACjB;AAED,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgG7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import Cropper from "react-easy-crop";
5
+ import { Button } from "./button";
6
+ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "./dialog";
7
+ import { Slider } from "./slider";
8
+ const ImageCropper = ({ image, onCancel, onCropComplete, open }) => {
9
+ const [crop, setCrop] = useState({ x: 0, y: 0 });
10
+ const [zoom, setZoom] = useState(1);
11
+ const [croppedAreaPixels, setCroppedAreaPixels] = useState(null);
12
+ const onCropChange = (crop) => {
13
+ setCrop(crop);
14
+ };
15
+ const onZoomChange = (zoom) => {
16
+ setZoom(zoom);
17
+ };
18
+ const onCropCompleteCallback = useCallback((_, croppedAreaPixels) => {
19
+ setCroppedAreaPixels(croppedAreaPixels);
20
+ }, []);
21
+ const createCroppedImage = async () => {
22
+ if (!croppedAreaPixels || !image)
23
+ return;
24
+ const img = new Image();
25
+ img.src = image;
26
+ await new Promise((resolve) => {
27
+ img.onload = resolve;
28
+ });
29
+ const canvas = document.createElement("canvas");
30
+ const ctx = canvas.getContext("2d");
31
+ if (!ctx)
32
+ return;
33
+ canvas.width = croppedAreaPixels.width;
34
+ canvas.height = croppedAreaPixels.height;
35
+ ctx.drawImage(img, croppedAreaPixels.x, croppedAreaPixels.y, croppedAreaPixels.width, croppedAreaPixels.height, 0, 0, croppedAreaPixels.width, croppedAreaPixels.height);
36
+ canvas.toBlob((blob) => {
37
+ if (blob) {
38
+ onCropComplete(blob);
39
+ }
40
+ }, "image/jpeg");
41
+ };
42
+ return (_jsx(Dialog, { open: open, onOpenChange: (isOpen) => !isOpen && onCancel(), children: _jsxs(DialogContent, { className: "sm:max-w-[500px] z-[300]", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Crop Profile Picture" }) }), _jsx("div", { className: "relative h-[300px] w-full bg-gray-100 rounded-md overflow-hidden", children: _jsx(Cropper, { image: image, crop: crop, zoom: zoom, aspect: 1, cropShape: "round", showGrid: false, onCropChange: onCropChange, onCropComplete: onCropCompleteCallback, onZoomChange: onZoomChange }) }), _jsx("div", { className: "py-4", children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("span", { className: "text-sm font-medium", children: "Zoom" }), _jsx(Slider, { value: [zoom], min: 1, max: 5, step: 0.1, onValueChange: (values) => { var _a; return setZoom((_a = values[0]) !== null && _a !== void 0 ? _a : 1); }, className: "flex-1" })] }) }), _jsxs(DialogFooter, { className: "flex gap-2", children: [_jsx(Button, { variant: "outline", onClick: onCancel, children: "Cancel" }), _jsx(Button, { onClick: createCroppedImage, children: "Set Profile Picture" })] })] }) }));
43
+ };
44
+ export default ImageCropper;
@@ -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 Input(_a) {
26
- var className = _a.className, type = _a.type, props = __rest(_a, ["className", "type"]);
27
- return (_jsx("input", __assign({ type: type, "data-slot": "input", className: cn("border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className) }, props)));
3
+ function Input({ className, type, ...props }) {
4
+ return (_jsx("input", { type: type, "data-slot": "input", className: cn("border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", className), ...props }));
28
5
  }
29
6
  export { Input };
@@ -1,31 +1,8 @@
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 } from "react/jsx-runtime";
25
3
  import * as LabelPrimitive from "@radix-ui/react-label";
26
4
  import { cn } from "@myrjfa/state/dist/lib/utils";
27
- function Label(_a) {
28
- var className = _a.className, props = __rest(_a, ["className"]);
29
- return (_jsx(LabelPrimitive.Root, __assign({ "data-slot": "label", className: cn("flex items-center gap-2 leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className) }, props)));
5
+ function Label({ className, ...props }) {
6
+ return (_jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn("flex items-center gap-2 leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50", className), ...props }));
30
7
  }
31
8
  export { Label };
@@ -1,15 +1,5 @@
1
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
- if (ar || !(i in from)) {
4
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
- ar[i] = from[i];
6
- }
7
- }
8
- return to.concat(ar || Array.prototype.slice.call(from));
9
- };
10
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- export default function LineCarousel(_a) {
12
- var skillsData = _a.skillsData;
13
- var loopedSkills = __spreadArray(__spreadArray(__spreadArray([], skillsData, true), skillsData, true), skillsData, true);
14
- return (_jsxs("section", { className: "relative w-full pt-10 pb-5 bg-background text-white", children: [_jsx("h2", { className: "text-2xl font-bold text-left mx-10 md:mx-15 lg:mx-25 tracking-tight text-foreground", children: "Popular Skills Offered" }), _jsx("p", { className: "text-muted-foreground mx-10 md:mx-15 lg:mx-25 mb-10", children: "Discover In-Demand Creative Skills for the Modern World." }), _jsxs("div", { className: "relative w-full overflow-hidden", children: [_jsx("div", { className: "absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background to-transparent z-10" }), _jsx("div", { className: "absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background to-transparent z-10" }), _jsx("div", { className: "flex animate-scroll items-center space-x-10", children: loopedSkills.map(function (item, i) { return (_jsxs("div", { className: "flex items-center space-x-3 px-5 text-lg", children: [_jsx(item.icon, { className: "w-6 h-6 text-foreground" }), _jsx("span", { className: "text-muted-foreground font-semibold", children: item.title })] }, i)); }) })] })] }));
2
+ export default function LineCarousel({ skillsData }) {
3
+ const loopedSkills = [...skillsData, ...skillsData, ...skillsData];
4
+ return (_jsxs("section", { className: "relative w-full pt-10 pb-5 bg-background text-white", children: [_jsx("h2", { className: "text-2xl font-bold text-left mx-10 md:mx-15 lg:mx-25 tracking-tight text-foreground", children: "Popular Skills Offered" }), _jsx("p", { className: "text-muted-foreground mx-10 md:mx-15 lg:mx-25 mb-10", children: "Discover In-Demand Creative Skills for the Modern World." }), _jsxs("div", { className: "relative w-full overflow-hidden", children: [_jsx("div", { className: "absolute inset-y-0 left-0 w-1/4 bg-gradient-to-r from-background to-transparent z-10" }), _jsx("div", { className: "absolute inset-y-0 right-0 w-1/4 bg-gradient-to-l from-background to-transparent z-10" }), _jsx("div", { className: "flex animate-scroll items-center space-x-10", children: loopedSkills.map((item, i) => (_jsxs("div", { className: "flex items-center space-x-3 px-5 text-lg", children: [_jsx(item.icon, { className: "w-6 h-6 text-foreground" }), _jsx("span", { className: "text-muted-foreground font-semibold", children: item.title })] }, i))) })] })] }));
15
5
  }
@@ -5,7 +5,6 @@ import { Input } from "./input";
5
5
  import { Card, CardHeader, CardTitle, CardContent } from "./card";
6
6
  import { Trash2, Upload } from "lucide-react";
7
7
  import Image from "next/image";
8
- export default function MultiImageUploader(_a) {
9
- var previewImages = _a.previewImages, handleImageUpload = _a.handleImageUpload, handleRemoveImage = _a.handleRemoveImage, message = _a.message;
10
- return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs(CardTitle, { children: ["Images", _jsx(FormDescription, { children: message })] }) }), _jsxs(CardContent, { children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-4", children: [previewImages.map(function (image, index) { return (_jsxs("div", { className: "relative rounded-lg overflow-hidden h-40", children: [_jsx(Image, { id: "image-" + index, src: image, alt: "Opportunity image ".concat(index + 1), fill: true, className: "object-cover" }), _jsx(Button, { type: "button", onClick: function () { return handleRemoveImage(index); }, className: "absolute top-2 right-2 bg-white/80 rounded-full hover:bg-white", children: _jsx(Trash2, { className: "text-red-500" }) })] }, index)); }), _jsxs("div", { className: "flex flex-col items-center justify-center w-full space-y-4", children: [_jsx("label", { htmlFor: "image", className: "cursor-pointer w-full", children: _jsxs("div", { className: "border-2 border-dashed border-slate-300 rounded-lg p-6 flex flex-col items-center justify-center text-slate-500 hover:border-primary hover:text-primary transition-colors", children: [_jsx(Upload, { className: "h-12 w-12 text-gray-500 mb-4" }), _jsx("span", { className: "text-lg font-semibold mb-2", children: "Upload Image" }), _jsx("span", { className: "text-sm", children: "Click or drag to upload" })] }) }), _jsx(Input, { id: "image", type: "file", accept: "image/*", multiple: true, onChange: handleImageUpload, placeholder: "Upload Image", className: "hidden" })] })] }), _jsx(FormDescription, { children: "Images should be in Valid format. Maximum file size: 5MB." })] })] }));
8
+ export default function MultiImageUploader({ previewImages, handleImageUpload, handleRemoveImage, message }) {
9
+ return (_jsxs(Card, { children: [_jsx(CardHeader, { children: _jsxs(CardTitle, { children: ["Images", _jsx(FormDescription, { children: message })] }) }), _jsxs(CardContent, { children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-4", children: [previewImages.map((image, index) => (_jsxs("div", { className: "relative rounded-lg overflow-hidden h-40", children: [_jsx(Image, { id: "image-" + index, src: image, alt: `Opportunity image ${index + 1}`, fill: true, className: "object-cover" }), _jsx(Button, { type: "button", onClick: () => handleRemoveImage(index), className: "absolute top-2 right-2 bg-white/80 rounded-full hover:bg-white", children: _jsx(Trash2, { className: "text-red-500" }) })] }, index))), _jsxs("div", { className: "flex flex-col items-center justify-center w-full space-y-4", children: [_jsx("label", { htmlFor: "image", className: "cursor-pointer w-full", children: _jsxs("div", { className: "border-2 border-dashed border-slate-300 rounded-lg p-6 flex flex-col items-center justify-center text-slate-500 hover:border-primary hover:text-primary transition-colors", children: [_jsx(Upload, { className: "h-12 w-12 text-gray-500 mb-4" }), _jsx("span", { className: "text-lg font-semibold mb-2", children: "Upload Image" }), _jsx("span", { className: "text-sm", children: "Click or drag to upload" })] }) }), _jsx(Input, { id: "image", type: "file", accept: "image/*", multiple: true, onChange: handleImageUpload, placeholder: "Upload Image", className: "hidden" })] })] }), _jsx(FormDescription, { children: "Images should be in Valid format. Maximum file size: 5MB." })] })] }));
11
10
  }
@@ -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 { zodResolver } from "@hookform/resolvers/zod";
51
4
  import { subscribeToNewsLetter } from "@myrjfa/state/dist/lib/actions";
@@ -57,45 +10,32 @@ import { showAlert } from "./alertdialogclaude";
57
10
  import { Button } from "./button";
58
11
  import { Form, FormControl, FormField, FormItem, FormMessage } from "./form";
59
12
  import { Input } from "./input";
60
- var formSchema = z.object({
13
+ const formSchema = z.object({
61
14
  email: z.string().email("Please enter a valid email address"),
62
15
  });
63
- var NewsletterSubscribe = function () {
64
- var pathname = usePathname();
65
- var form = useForm({
16
+ const NewsletterSubscribe = () => {
17
+ const pathname = usePathname();
18
+ const form = useForm({
66
19
  resolver: zodResolver(formSchema),
67
20
  defaultValues: {
68
21
  email: "",
69
22
  },
70
23
  });
71
- useEffect(function () {
24
+ useEffect(() => {
72
25
  form.reset();
73
26
  }, [pathname]);
74
- var isSubmitting = form.formState.isSubmitting;
75
- var onSubmit = function (values) { return __awaiter(void 0, void 0, void 0, function () {
76
- var res;
77
- return __generator(this, function (_a) {
78
- switch (_a.label) {
79
- case 0: return [4 /*yield*/, subscribeToNewsLetter(values.email)];
80
- case 1:
81
- res = _a.sent();
82
- if (!(res === null || res === void 0 ? void 0 : res.error)) return [3 /*break*/, 2];
83
- form.setError("email", { message: res.error });
84
- return [3 /*break*/, 4];
85
- case 2:
86
- form.reset();
87
- form.setValue("email", "");
88
- return [4 /*yield*/, showAlert(res.message || "Subscribed successfully!")];
89
- case 3:
90
- _a.sent();
91
- _a.label = 4;
92
- case 4: return [2 /*return*/];
93
- }
94
- });
95
- }); };
96
- return (_jsx(Form, __assign({}, form, { children: _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), noValidate: true, className: "mt-4 flex flex-col sm:flex-row gap-3", children: [_jsx(FormField, { control: form.control, name: "email", render: function (_a) {
97
- var field = _a.field;
98
- return (_jsxs(FormItem, { className: "flex-1", children: [_jsx(FormControl, { children: _jsx(Input, __assign({ placeholder: "Your email address", type: "email", disabled: isSubmitting }, field)) }), _jsx(FormMessage, {})] }));
99
- } }), _jsx(Button, { type: "submit", disabled: isSubmitting, className: "w-full sm:w-auto", children: isSubmitting ? "Subscribing..." : "Subscribe" })] }) })));
27
+ const { isSubmitting } = form.formState;
28
+ const onSubmit = async (values) => {
29
+ const res = await subscribeToNewsLetter(values.email);
30
+ if (res === null || res === void 0 ? void 0 : res.error) {
31
+ form.setError("email", { message: res.error });
32
+ }
33
+ else {
34
+ form.reset();
35
+ form.setValue("email", "");
36
+ await showAlert(res.message || "Subscribed successfully!");
37
+ }
38
+ };
39
+ return (_jsx(Form, { ...form, children: _jsxs("form", { onSubmit: form.handleSubmit(onSubmit), noValidate: true, className: "mt-4 flex flex-col sm:flex-row gap-3", children: [_jsx(FormField, { control: form.control, name: "email", render: ({ field }) => (_jsxs(FormItem, { className: "flex-1", children: [_jsx(FormControl, { children: _jsx(Input, { placeholder: "Your email address", type: "email", disabled: isSubmitting, ...field }) }), _jsx(FormMessage, {})] })) }), _jsx(Button, { type: "submit", disabled: isSubmitting, className: "w-full sm:w-auto", children: isSubmitting ? "Subscribing..." : "Subscribe" })] }) }));
100
40
  };
101
41
  export default NewsletterSubscribe;
@@ -1,5 +1,4 @@
1
- export declare function NotificationBell({ id, navItemColor }: {
2
- id: string | null;
1
+ export declare function NotificationBell({ navItemColor }: {
3
2
  navItemColor: string;
4
3
  }): import("react/jsx-runtime").JSX.Element;
5
4
  export declare function MobileNotificationBell(): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../src/misc/notification.tsx"],"names":[],"mappings":"AA2BA,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,2CA8GjG;AAED,wBAAgB,sBAAsB,4CAerC"}
1
+ {"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../src/misc/notification.tsx"],"names":[],"mappings":"AAkDA,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,EAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,2CA8I1E;AAED,wBAAgB,sBAAsB,4CAUrC"}
@@ -1,56 +1,9 @@
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 { Popover, PopoverContent, PopoverTrigger } from "@radix-ui/react-popover";
51
- import { toggleAllNotification, toggleNotification } from "@myrjfa/state/dist/lib/actions";
4
+ import { getNotifications, toggleAllNotification, toggleNotification } from "@myrjfa/state/dist/lib/actions";
52
5
  import { formatTimestamp } from "@myrjfa/state/dist/lib/utils";
53
- import { Bell } from "lucide-react";
6
+ import { Bell, MessageCircle, CheckCircle2, Receipt, Users, AlertCircle, Megaphone, Briefcase, ShieldCheck, ShieldX, Package, ClipboardList } from "lucide-react";
54
7
  import { useRouter } from "next/navigation";
55
8
  import { useEffect, useState } from "react";
56
9
  import { FaSpinner } from "react-icons/fa6";
@@ -59,89 +12,100 @@ import { Button } from "./button";
59
12
  import { Card, CardHeader, CardTitle } from "./card";
60
13
  import { ScrollArea } from "./scroll-area";
61
14
  import { MobileNavItem } from "../header/mobile-nav-item";
62
- var NOTIF_LIMIT_FOR_BELL = 10;
63
- var getNotificationIcon = function (type) {
15
+ const NOTIF_LIMIT_FOR_BELL = 10;
16
+ const getNotificationIcon = (notif) => {
17
+ const type = notif.type || "general";
64
18
  switch (type) {
65
- case "false":
66
- return _jsx("div", { className: "w-2 h-2 rounded-full bg-green-500 mt-2" });
19
+ case "new_message":
20
+ return _jsx(MessageCircle, { className: "w-4 h-4 text-blue-500 mt-0.5 flex-shrink-0" });
21
+ case "milestone_completed":
22
+ return _jsx(CheckCircle2, { className: "w-4 h-4 text-green-500 mt-0.5 flex-shrink-0" });
23
+ case "expense_added":
24
+ return _jsx(Receipt, { className: "w-4 h-4 text-orange-500 mt-0.5 flex-shrink-0" });
25
+ case "group_invite":
26
+ return _jsx(Users, { className: "w-4 h-4 text-purple-500 mt-0.5 flex-shrink-0" });
27
+ case "mention":
28
+ return _jsx(Megaphone, { className: "w-4 h-4 text-yellow-500 mt-0.5 flex-shrink-0" });
29
+ case "application_received":
30
+ case "application_status":
31
+ case "application_shortlisted":
32
+ return _jsx(Briefcase, { className: "w-4 h-4 text-indigo-500 mt-0.5 flex-shrink-0" });
33
+ case "id_verified":
34
+ return _jsx(ShieldCheck, { className: "w-4 h-4 text-emerald-500 mt-0.5 flex-shrink-0" });
35
+ case "id_rejected":
36
+ return _jsx(ShieldX, { className: "w-4 h-4 text-red-500 mt-0.5 flex-shrink-0" });
37
+ case "package_enquiry":
38
+ return _jsx(Package, { className: "w-4 h-4 text-cyan-500 mt-0.5 flex-shrink-0" });
39
+ case "opportunity_assigned":
40
+ return _jsx(ClipboardList, { className: "w-4 h-4 text-amber-500 mt-0.5 flex-shrink-0" });
41
+ case "system":
42
+ return _jsx(AlertCircle, { className: "w-4 h-4 text-gray-500 mt-0.5 flex-shrink-0" });
67
43
  default:
68
- return _jsx("div", { className: "w-2 h-2 rounded-full bg-gray-500 mt-2" });
44
+ return _jsx("div", { className: `w-2.5 h-2.5 rounded-full mt-1.5 flex-shrink-0 ${!notif.read ? "bg-blue-500" : "bg-gray-300"}` });
69
45
  }
70
46
  };
71
- export function NotificationBell(_a) {
72
- var _this = this;
73
- var id = _a.id, navItemColor = _a.navItemColor;
74
- var _b = useState([]), notifs = _b[0], setNotifs = _b[1];
75
- var _c = useState(0), unreadCount = _c[0], setUnreadCount = _c[1];
76
- var _d = useState(null), loadingNotifId = _d[0], setLoadingNotifId = _d[1];
77
- var router = useRouter();
78
- useEffect(function () {
79
- var fetchData = function () { return __awaiter(_this, void 0, void 0, function () {
80
- return __generator(this, function (_a) {
81
- if (!id)
82
- return [2 /*return*/];
83
- return [2 /*return*/];
84
- });
85
- }); };
86
- fetchData();
87
- }, [id]);
88
- var handleMarkAllNotifRead = function () { return __awaiter(_this, void 0, void 0, function () {
89
- var response;
90
- return __generator(this, function (_a) {
91
- switch (_a.label) {
92
- case 0: return [4 /*yield*/, toggleAllNotification(true)];
93
- case 1:
94
- response = _a.sent();
95
- if (!(response === null || response === void 0 ? void 0 : response.error)) return [3 /*break*/, 3];
96
- return [4 /*yield*/, showAlert(response.error)];
97
- case 2:
98
- _a.sent();
99
- return [3 /*break*/, 4];
100
- case 3:
101
- setNotifs(notifs.map(function (notif) { return (__assign(__assign({}, notif), { read: true })); }));
102
- setUnreadCount(0);
103
- console.log("marked");
104
- _a.label = 4;
105
- case 4: return [2 /*return*/];
47
+ export function NotificationBell({ navItemColor }) {
48
+ const [notifs, setNotifs] = useState([]);
49
+ const [unreadCount, setUnreadCount] = useState(0);
50
+ const [loadingNotifId, setLoadingNotifId] = useState(null);
51
+ const [isOpen, setIsOpen] = useState(false);
52
+ const router = useRouter();
53
+ const fetchData = async () => {
54
+ try {
55
+ const response = await getNotifications(NOTIF_LIMIT_FOR_BELL);
56
+ if (response && !response.error) {
57
+ setNotifs(response.notifs || []);
58
+ setUnreadCount(response.unreadCount || 0);
106
59
  }
107
- });
108
- }); };
109
- var handleNotifClick = function (notif) { return __awaiter(_this, void 0, void 0, function () {
110
- var response, url;
111
- return __generator(this, function (_a) {
112
- switch (_a.label) {
113
- case 0:
114
- if (loadingNotifId)
115
- return [2 /*return*/];
116
- if (!!notif.read) return [3 /*break*/, 4];
117
- setLoadingNotifId(notif._id);
118
- return [4 /*yield*/, toggleNotification(notif._id, true)];
119
- case 1:
120
- response = _a.sent();
121
- if (!(response === null || response === void 0 ? void 0 : response.error)) return [3 /*break*/, 3];
122
- return [4 /*yield*/, showAlert(response.error)];
123
- case 2:
124
- _a.sent();
125
- return [3 /*break*/, 4];
126
- case 3:
127
- setNotifs(notifs.map(function (n) {
128
- return n._id === notif._id ? __assign(__assign({}, n), { read: true }) : n;
129
- }));
130
- setUnreadCount(unreadCount - 1);
131
- console.log("read notification");
132
- _a.label = 4;
133
- case 4:
134
- setLoadingNotifId(null);
135
- url = notif.url;
136
- return [2 /*return*/, url && router.push(url)];
60
+ }
61
+ catch (err) {
62
+ console.error("Failed to fetch notifications:", err);
63
+ }
64
+ };
65
+ // Re-fetch when popover opens
66
+ useEffect(() => {
67
+ if (isOpen)
68
+ fetchData();
69
+ }, [isOpen]);
70
+ const handleMarkAllNotifRead = async () => {
71
+ const response = await toggleAllNotification(true);
72
+ if (response === null || response === void 0 ? void 0 : response.error) {
73
+ await showAlert(response.error);
74
+ }
75
+ else {
76
+ setNotifs(notifs.map((notif) => ({
77
+ ...notif, read: true
78
+ })));
79
+ setUnreadCount(0);
80
+ }
81
+ };
82
+ const handleNotifClick = async (notif) => {
83
+ if (loadingNotifId)
84
+ return;
85
+ if (!notif.read) {
86
+ setLoadingNotifId(notif._id);
87
+ const response = await toggleNotification(notif._id, true);
88
+ if (response === null || response === void 0 ? void 0 : response.error) {
89
+ await showAlert(response.error);
137
90
  }
138
- });
139
- }); };
91
+ else {
92
+ setNotifs(notifs.map((n) => n._id === notif._id ? { ...n, read: true } : n));
93
+ setUnreadCount(Math.max(0, unreadCount - 1));
94
+ }
95
+ }
96
+ setLoadingNotifId(null);
97
+ // Navigate to the link or URL
98
+ const url = notif.link;
99
+ if (url) {
100
+ setIsOpen(false);
101
+ router.push(url);
102
+ }
103
+ };
140
104
  if (notifs == null)
141
- return _jsx(FaSpinner, {});
142
- return _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("div", { className: "relative cursor-pointer ".concat(navItemColor, " transition-colors"), "aria-label": "Notification Bell", children: [_jsx(Bell, { className: "h-5 w-5" }), unreadCount > 0 && (_jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[1rem] items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white", children: unreadCount > 99 ? "99+" : unreadCount }))] }) }), _jsx(PopoverContent, { className: "w-96 p-0 mt-3 bg-white rounded-lg shadow-lg", align: "end", sideOffset: 5, children: _jsxs(Card, { className: "border-0 shadow-none", children: [_jsx(CardHeader, { className: "px-8", children: _jsxs("div", { className: "flex justify-between items-center", children: [_jsx(CardTitle, { className: "text-lg font-medium", children: "Notifications" }), notifs.length != 0 && _jsx(Button, { variant: "ghost", size: "sm", className: "text-xs text-blue-600 hover:text-blue-800", onClick: function () {
143
- handleMarkAllNotifRead();
144
- }, children: "Mark all as read" })] }) }), _jsx(ScrollArea, { className: "h-80 w-full rounded-md", children: _jsx("div", { className: "px-2", children: notifs.length === 0 ? (_jsx("div", { className: "text-center text-sm text-gray-500 py-30", children: "You're all caught up \uD83C\uDF89" })) : (notifs.map(function (notif) { return (_jsxs("div", { className: "flex items-start gap-3 p-2 pb-1 mt-1 hover:bg-gray-50 rounded-lg transition-colors ".concat(!notif.read ? "bg-blue-50/50" : "", " ").concat(loadingNotifId === notif._id ? "opacity-50 pointer-events-none" : ""), onClick: function () { return handleNotifClick(notif); }, children: [_jsx("div", { className: "flex-shrink-0 mt-1", children: getNotificationIcon(notif.read.toString()) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: "text-sm ".concat(!notif.read ? "font-medium" : "text-gray-600"), children: notif.message }), _jsx("p", { className: "text-xs text-gray-500 mt-1", children: formatTimestamp(notif.timestamp) })] }), !notif.read && (_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "w-2 h-2 rounded-full bg-blue-500" }) }))] }, notif._id)); })) }) }), notifs.length > NOTIF_LIMIT_FOR_BELL && _jsx("div", { className: "px-3 pt-2 border-t border-gray-100", children: _jsx(Button, { variant: "ghost", className: "w-full text-blue-600 hover:text-blue-800 hover:bg-blue-50 text-sm", onClick: function () { router.push("/inbox"); }, children: "View all notifications" }) })] }) })] });
105
+ return _jsx(FaSpinner, { className: "animate-spin" });
106
+ return _jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("div", { className: `relative cursor-pointer ${navItemColor} transition-colors`, "aria-label": "Notification Bell", children: [_jsx(Bell, { className: "h-5 w-5" }), unreadCount > 0 && (_jsx("span", { className: "absolute -top-1.5 -right-1.5 flex h-4 min-w-[1rem] items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white animate-pulse", children: unreadCount > 99 ? "99+" : unreadCount }))] }) }), _jsx(PopoverContent, { className: "w-96 p-0 mt-3 bg-white dark:bg-gray-900 rounded-xl shadow-xl border border-gray-100 dark:border-gray-800", align: "end", sideOffset: 5, children: _jsxs(Card, { className: "border-0 shadow-none bg-transparent", children: [_jsx(CardHeader, { className: "px-5 pb-2", children: _jsxs("div", { className: "flex justify-between items-center", children: [_jsx(CardTitle, { className: "text-base font-semibold", children: "Notifications" }), notifs.length > 0 && unreadCount > 0 && (_jsx(Button, { variant: "ghost", size: "sm", className: "text-xs text-teal-600 hover:text-teal-800 dark:text-teal-400", onClick: handleMarkAllNotifRead, children: "Mark all as read" }))] }) }), _jsx(ScrollArea, { className: "h-80 w-full", children: _jsx("div", { className: "px-2 pb-2", children: notifs.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-gray-400", children: [_jsx(Bell, { className: "w-10 h-10 mb-3 opacity-30" }), _jsx("p", { className: "text-sm", children: "You're all caught up \uD83C\uDF89" })] })) : (notifs.map((notif) => (_jsxs("div", { className: `flex items-start gap-3 p-3 rounded-lg cursor-pointer transition-all duration-200 hover:bg-gray-50 dark:hover:bg-gray-800/50 ${!notif.read
107
+ ? "bg-teal-50/50 dark:bg-teal-900/10 border-l-2 border-teal-500"
108
+ : "border-l-2 border-transparent"} ${loadingNotifId === notif._id ? "opacity-50 pointer-events-none" : ""}`, onClick: () => handleNotifClick(notif), children: [_jsx("div", { className: "flex-shrink-0 mt-0.5", children: getNotificationIcon(notif) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("p", { className: `text-sm leading-snug ${!notif.read ? "font-medium text-gray-900 dark:text-white" : "text-gray-600 dark:text-gray-400"}`, children: notif.message }), _jsxs("div", { className: "flex items-center gap-2 mt-1", children: [_jsx("p", { className: "text-[11px] text-gray-400", children: notif.timestamp ? formatTimestamp(notif.timestamp) : "" }), notif.type && notif.type !== "general" && (_jsx("span", { className: "text-[10px] px-1.5 py-0.5 rounded-full bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400", children: notif.type.replace(/_/g, " ") }))] })] }), !notif.read && (_jsx("div", { className: "flex-shrink-0 mt-2", children: _jsx("div", { className: "w-2 h-2 rounded-full bg-teal-500" }) }))] }, notif._id)))) }) }), notifs.length > NOTIF_LIMIT_FOR_BELL && (_jsx("div", { className: "px-3 py-2 border-t border-gray-100 dark:border-gray-800", children: _jsx(Button, { variant: "ghost", className: "w-full text-teal-600 hover:text-teal-800 hover:bg-teal-50 dark:text-teal-400 dark:hover:bg-teal-900/20 text-sm", onClick: () => { setIsOpen(false); router.push("/inbox"); }, children: "View all notifications" }) }))] }) })] });
145
109
  }
146
110
  export function MobileNotificationBell() {
147
111
  return (_jsx(MobileNavItem, { icon: _jsx("div", { className: "relative", children: _jsx(Bell, { className: "h-5 w-5" }) }), label: "Notifications", href: "/inbox" }));