@propknot/shared-ui 1.0.7 → 1.0.9

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 (3) hide show
  1. package/dist/index.js +437 -61
  2. package/dist/index.mjs +462 -55
  3. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1489,7 +1489,6 @@ var CustomThemeProvider = ({ children }) => {
1489
1489
  if (!event.origin.startsWith("http://localhost:")) return;
1490
1490
  const { type, theme } = event.data;
1491
1491
  if (type === "THEME_CHANGE" && theme && ["light", "dark"].includes(theme)) {
1492
- console.log("Embedded app received theme change:", theme);
1493
1492
  setCurrentTheme(theme);
1494
1493
  }
1495
1494
  };
@@ -3320,23 +3319,430 @@ var NotificationManager = () => {
3320
3319
  };
3321
3320
  var NotificationManager_default = NotificationManager;
3322
3321
 
3323
- // src/components/ErrorBoundary/ErrorBoundary.js
3324
- import React14 from "react";
3322
+ // src/components/Notifications/NotificationBell.js
3323
+ import React14, { useState as useState6, useEffect as useEffect5, useCallback as useCallback2 } from "react";
3325
3324
  import {
3325
+ IconButton as IconButton3,
3326
+ Badge as Badge2,
3327
+ Menu as Menu2,
3328
+ MenuItem as MenuItem2,
3326
3329
  Box as Box9,
3327
3330
  Typography as Typography7,
3331
+ Divider as Divider2,
3332
+ Avatar as Avatar2,
3333
+ ListItemText as ListItemText2,
3334
+ ListItemAvatar,
3335
+ List as List2,
3336
+ ListItem as ListItem2,
3328
3337
  Button as Button3,
3338
+ Chip as Chip2,
3339
+ CircularProgress as CircularProgress3,
3340
+ Alert as Alert2
3341
+ } from "@mui/material";
3342
+ import {
3343
+ Notifications as NotificationsIcon,
3344
+ NotificationsNone,
3345
+ CheckCircle as CheckCircle2,
3346
+ Warning as Warning2,
3347
+ Error as ErrorIcon,
3348
+ Info as Info2,
3349
+ Message,
3350
+ Assignment,
3351
+ Payment,
3352
+ Home,
3353
+ Build,
3354
+ Close as Close2,
3355
+ DoneAll,
3356
+ Settings as SettingsIcon
3357
+ } from "@mui/icons-material";
3358
+ import { formatDistanceToNow } from "date-fns";
3359
+ var NotificationBell = ({ api: api2, useSocket: useSocket2, useAuth: useAuth2 }) => {
3360
+ const [anchorEl, setAnchorEl] = useState6(null);
3361
+ const [notifications, setNotifications] = useState6([]);
3362
+ const [unreadCount, setUnreadCount] = useState6(0);
3363
+ const [loading, setLoading] = useState6(false);
3364
+ const [error, setError] = useState6(null);
3365
+ const [page, setPage] = useState6(1);
3366
+ const [hasMore, setHasMore] = useState6(true);
3367
+ const { socket, isConnected } = useSocket2 ? useSocket2() : { socket: null, isConnected: false };
3368
+ const { user } = useAuth2 ? useAuth2() : { user: null };
3369
+ const open = Boolean(anchorEl);
3370
+ const fetchNotifications = useCallback2(async (pageNum = 1, append = false) => {
3371
+ if (!api2) return;
3372
+ setLoading(true);
3373
+ setError(null);
3374
+ try {
3375
+ const response = await api2.get("/notifications", {
3376
+ params: {
3377
+ page: pageNum,
3378
+ limit: 20,
3379
+ sort: "-createdAt"
3380
+ }
3381
+ });
3382
+ const newNotifications = response.data.notifications || [];
3383
+ if (append) {
3384
+ setNotifications((prev) => [...prev, ...newNotifications]);
3385
+ } else {
3386
+ setNotifications(newNotifications);
3387
+ }
3388
+ setHasMore(newNotifications.length === 20);
3389
+ setUnreadCount(response.data.unreadCount || 0);
3390
+ } catch (err) {
3391
+ console.error("Failed to fetch notifications:", err);
3392
+ setError("Failed to load notifications");
3393
+ } finally {
3394
+ setLoading(false);
3395
+ }
3396
+ }, [api2]);
3397
+ const fetchUnreadCount = useCallback2(async () => {
3398
+ if (!api2) return;
3399
+ try {
3400
+ const response = await api2.get("/notifications/unread");
3401
+ setUnreadCount(response.data.count || 0);
3402
+ } catch (err) {
3403
+ console.error("Failed to fetch unread count:", err);
3404
+ }
3405
+ }, [api2]);
3406
+ useEffect5(() => {
3407
+ fetchNotifications();
3408
+ fetchUnreadCount();
3409
+ }, [fetchNotifications, fetchUnreadCount]);
3410
+ useEffect5(() => {
3411
+ if (!socket || !isConnected) return;
3412
+ const handleNewNotification = (notification) => {
3413
+ setNotifications((prev) => [notification, ...prev]);
3414
+ setUnreadCount((prev) => prev + 1);
3415
+ };
3416
+ const handleNotificationRead = (notificationId) => {
3417
+ setNotifications(
3418
+ (prev) => prev.map((n) => n._id === notificationId ? { ...n, read: true } : n)
3419
+ );
3420
+ setUnreadCount((prev) => Math.max(0, prev - 1));
3421
+ };
3422
+ socket.on("notification", handleNewNotification);
3423
+ socket.on("notification:read", handleNotificationRead);
3424
+ return () => {
3425
+ socket.off("notification", handleNewNotification);
3426
+ socket.off("notification:read", handleNotificationRead);
3427
+ };
3428
+ }, [socket, isConnected]);
3429
+ const handleClick = (event) => {
3430
+ setAnchorEl(event.currentTarget);
3431
+ if (notifications.length === 0) {
3432
+ fetchNotifications();
3433
+ }
3434
+ };
3435
+ const handleClose = () => {
3436
+ setAnchorEl(null);
3437
+ };
3438
+ const handleMarkAsRead = async (notificationId) => {
3439
+ if (!api2) return;
3440
+ try {
3441
+ await api2.put(`/notifications/${notificationId}/read`);
3442
+ setNotifications(
3443
+ (prev) => prev.map((n) => n._id === notificationId ? { ...n, read: true, readAt: /* @__PURE__ */ new Date() } : n)
3444
+ );
3445
+ setUnreadCount((prev) => Math.max(0, prev - 1));
3446
+ } catch (err) {
3447
+ console.error("Failed to mark notification as read:", err);
3448
+ }
3449
+ };
3450
+ const handleMarkAllAsRead = async () => {
3451
+ if (!api2) return;
3452
+ try {
3453
+ await api2.put("/notifications/mark-all-read");
3454
+ setNotifications(
3455
+ (prev) => prev.map((n) => ({ ...n, read: true, readAt: /* @__PURE__ */ new Date() }))
3456
+ );
3457
+ setUnreadCount(0);
3458
+ } catch (err) {
3459
+ console.error("Failed to mark all as read:", err);
3460
+ }
3461
+ };
3462
+ const handleNotificationClick = async (notification) => {
3463
+ if (!notification.read) {
3464
+ await handleMarkAsRead(notification._id);
3465
+ }
3466
+ if (notification.actionUrl) {
3467
+ window.location.href = notification.actionUrl;
3468
+ }
3469
+ handleClose();
3470
+ };
3471
+ const handleLoadMore = () => {
3472
+ const nextPage = page + 1;
3473
+ setPage(nextPage);
3474
+ fetchNotifications(nextPage, true);
3475
+ };
3476
+ const getNotificationIcon = (type) => {
3477
+ const iconProps = { fontSize: "small" };
3478
+ switch (type) {
3479
+ case "TICKET_CREATED":
3480
+ case "TICKET_UPDATED":
3481
+ case "TICKET_ASSIGNED":
3482
+ case "TICKET_RESOLVED":
3483
+ case "TICKET_COMMENTED":
3484
+ case "TICKET_STATUS_CHANGED":
3485
+ return /* @__PURE__ */ React14.createElement(Assignment, { ...iconProps });
3486
+ case "MESSAGE_RECEIVED":
3487
+ case "MENTION_RECEIVED":
3488
+ return /* @__PURE__ */ React14.createElement(Message, { ...iconProps });
3489
+ case "PAYMENT_DUE":
3490
+ case "PAYMENT_OVERDUE":
3491
+ return /* @__PURE__ */ React14.createElement(Payment, { ...iconProps });
3492
+ case "PROPERTY_UPDATED":
3493
+ case "LEASE_EXPIRING":
3494
+ return /* @__PURE__ */ React14.createElement(Home, { ...iconProps });
3495
+ case "APPLIANCE_MAINTENANCE_DUE":
3496
+ case "MAINTENANCE_SCHEDULED":
3497
+ return /* @__PURE__ */ React14.createElement(Build, { ...iconProps });
3498
+ case "SYSTEM_ALERT":
3499
+ return /* @__PURE__ */ React14.createElement(Warning2, { ...iconProps });
3500
+ case "SUCCESS":
3501
+ return /* @__PURE__ */ React14.createElement(CheckCircle2, { ...iconProps });
3502
+ case "ERROR":
3503
+ return /* @__PURE__ */ React14.createElement(ErrorIcon, { ...iconProps });
3504
+ case "WARNING":
3505
+ return /* @__PURE__ */ React14.createElement(Warning2, { ...iconProps });
3506
+ case "INFO":
3507
+ default:
3508
+ return /* @__PURE__ */ React14.createElement(Info2, { ...iconProps });
3509
+ }
3510
+ };
3511
+ const getNotificationColor = (type) => {
3512
+ if ((type == null ? void 0 : type.includes("ERROR")) || (type == null ? void 0 : type.includes("OVERDUE"))) return "error.main";
3513
+ if ((type == null ? void 0 : type.includes("WARNING")) || (type == null ? void 0 : type.includes("DUE"))) return "warning.main";
3514
+ if ((type == null ? void 0 : type.includes("SUCCESS")) || (type == null ? void 0 : type.includes("RESOLVED"))) return "success.main";
3515
+ return "primary.main";
3516
+ };
3517
+ const getPriorityChip = (priority) => {
3518
+ if (!priority || priority === "NORMAL" || priority === "LOW") return null;
3519
+ const colors = {
3520
+ HIGH: "warning",
3521
+ URGENT: "error"
3522
+ };
3523
+ return /* @__PURE__ */ React14.createElement(
3524
+ Chip2,
3525
+ {
3526
+ label: priority,
3527
+ size: "small",
3528
+ color: colors[priority] || "default",
3529
+ sx: { ml: 1, height: 20, fontSize: "0.7rem" }
3530
+ }
3531
+ );
3532
+ };
3533
+ return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(
3534
+ IconButton3,
3535
+ {
3536
+ color: "inherit",
3537
+ onClick: handleClick,
3538
+ sx: {
3539
+ ml: 1,
3540
+ "&:hover": {
3541
+ bgcolor: "action.hover"
3542
+ }
3543
+ }
3544
+ },
3545
+ /* @__PURE__ */ React14.createElement(
3546
+ Badge2,
3547
+ {
3548
+ badgeContent: unreadCount,
3549
+ color: "error",
3550
+ max: 99
3551
+ },
3552
+ unreadCount > 0 ? /* @__PURE__ */ React14.createElement(NotificationsIcon, null) : /* @__PURE__ */ React14.createElement(NotificationsNone, null)
3553
+ )
3554
+ ), /* @__PURE__ */ React14.createElement(
3555
+ Menu2,
3556
+ {
3557
+ anchorEl,
3558
+ open,
3559
+ onClose: handleClose,
3560
+ PaperProps: {
3561
+ sx: {
3562
+ width: 420,
3563
+ maxHeight: 600,
3564
+ overflow: "hidden",
3565
+ display: "flex",
3566
+ flexDirection: "column"
3567
+ }
3568
+ },
3569
+ transformOrigin: { horizontal: "right", vertical: "top" },
3570
+ anchorOrigin: { horizontal: "right", vertical: "bottom" }
3571
+ },
3572
+ /* @__PURE__ */ React14.createElement(
3573
+ Box9,
3574
+ {
3575
+ sx: {
3576
+ p: 2,
3577
+ pb: 1.5,
3578
+ display: "flex",
3579
+ alignItems: "center",
3580
+ justifyContent: "space-between",
3581
+ borderBottom: "1px solid",
3582
+ borderColor: "divider"
3583
+ }
3584
+ },
3585
+ /* @__PURE__ */ React14.createElement(Box9, { sx: { display: "flex", alignItems: "center", gap: 1 } }, /* @__PURE__ */ React14.createElement(NotificationsIcon, { color: "primary" }), /* @__PURE__ */ React14.createElement(Typography7, { variant: "h6", sx: { fontWeight: 600 } }, "Notifications"), unreadCount > 0 && /* @__PURE__ */ React14.createElement(
3586
+ Chip2,
3587
+ {
3588
+ label: unreadCount,
3589
+ size: "small",
3590
+ color: "primary",
3591
+ sx: { height: 22, fontSize: "0.75rem" }
3592
+ }
3593
+ )),
3594
+ /* @__PURE__ */ React14.createElement(Box9, null, unreadCount > 0 && /* @__PURE__ */ React14.createElement(
3595
+ Button3,
3596
+ {
3597
+ size: "small",
3598
+ startIcon: /* @__PURE__ */ React14.createElement(DoneAll, null),
3599
+ onClick: handleMarkAllAsRead,
3600
+ sx: { textTransform: "none", fontSize: "0.75rem" }
3601
+ },
3602
+ "Mark all read"
3603
+ ), /* @__PURE__ */ React14.createElement(IconButton3, { size: "small", onClick: handleClose }, /* @__PURE__ */ React14.createElement(Close2, { fontSize: "small" })))
3604
+ ),
3605
+ error && /* @__PURE__ */ React14.createElement(Alert2, { severity: "error", sx: { m: 2 } }, error),
3606
+ /* @__PURE__ */ React14.createElement(
3607
+ Box9,
3608
+ {
3609
+ sx: {
3610
+ flex: 1,
3611
+ overflow: "auto",
3612
+ maxHeight: 450
3613
+ }
3614
+ },
3615
+ loading && notifications.length === 0 ? /* @__PURE__ */ React14.createElement(Box9, { sx: { display: "flex", justifyContent: "center", p: 4 } }, /* @__PURE__ */ React14.createElement(CircularProgress3, { size: 32 })) : notifications.length === 0 ? /* @__PURE__ */ React14.createElement(
3616
+ Box9,
3617
+ {
3618
+ sx: {
3619
+ display: "flex",
3620
+ flexDirection: "column",
3621
+ alignItems: "center",
3622
+ justifyContent: "center",
3623
+ p: 4,
3624
+ textAlign: "center"
3625
+ }
3626
+ },
3627
+ /* @__PURE__ */ React14.createElement(NotificationsNone, { sx: { fontSize: 64, color: "text.secondary", mb: 2 } }),
3628
+ /* @__PURE__ */ React14.createElement(Typography7, { variant: "body1", color: "text.secondary", sx: { fontWeight: 500 } }, "No notifications yet"),
3629
+ /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", color: "text.secondary" }, "You're all caught up!")
3630
+ ) : /* @__PURE__ */ React14.createElement(List2, { sx: { p: 0 } }, notifications.map((notification, index) => /* @__PURE__ */ React14.createElement(React14.Fragment, { key: notification._id }, /* @__PURE__ */ React14.createElement(
3631
+ ListItem2,
3632
+ {
3633
+ button: true,
3634
+ onClick: () => handleNotificationClick(notification),
3635
+ sx: {
3636
+ py: 1.5,
3637
+ px: 2,
3638
+ bgcolor: notification.read ? "transparent" : "action.hover",
3639
+ "&:hover": {
3640
+ bgcolor: notification.read ? "action.hover" : "action.selected"
3641
+ },
3642
+ borderLeft: notification.read ? "none" : "3px solid",
3643
+ borderLeftColor: getNotificationColor(notification.type),
3644
+ transition: "all 0.2s"
3645
+ }
3646
+ },
3647
+ /* @__PURE__ */ React14.createElement(ListItemAvatar, null, /* @__PURE__ */ React14.createElement(
3648
+ Avatar2,
3649
+ {
3650
+ sx: {
3651
+ bgcolor: notification.read ? "grey.300" : getNotificationColor(notification.type),
3652
+ width: 40,
3653
+ height: 40
3654
+ }
3655
+ },
3656
+ getNotificationIcon(notification.type)
3657
+ )),
3658
+ /* @__PURE__ */ React14.createElement(
3659
+ ListItemText2,
3660
+ {
3661
+ primary: /* @__PURE__ */ React14.createElement(Box9, { sx: { display: "flex", alignItems: "center", mb: 0.5 } }, /* @__PURE__ */ React14.createElement(
3662
+ Typography7,
3663
+ {
3664
+ variant: "body2",
3665
+ sx: {
3666
+ fontWeight: notification.read ? 400 : 600,
3667
+ flex: 1
3668
+ }
3669
+ },
3670
+ notification.title
3671
+ ), getPriorityChip(notification.priority)),
3672
+ secondary: /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(
3673
+ Typography7,
3674
+ {
3675
+ variant: "body2",
3676
+ color: "text.secondary",
3677
+ sx: {
3678
+ display: "-webkit-box",
3679
+ WebkitLineClamp: 2,
3680
+ WebkitBoxOrient: "vertical",
3681
+ overflow: "hidden",
3682
+ mb: 0.5
3683
+ }
3684
+ },
3685
+ notification.message
3686
+ ), /* @__PURE__ */ React14.createElement(Typography7, { variant: "caption", color: "text.secondary" }, formatDistanceToNow(new Date(notification.createdAt), { addSuffix: true })))
3687
+ }
3688
+ )
3689
+ ), index < notifications.length - 1 && /* @__PURE__ */ React14.createElement(Divider2, null)))),
3690
+ hasMore && notifications.length > 0 && /* @__PURE__ */ React14.createElement(Box9, { sx: { p: 2, textAlign: "center", borderTop: "1px solid", borderColor: "divider" } }, /* @__PURE__ */ React14.createElement(
3691
+ Button3,
3692
+ {
3693
+ onClick: handleLoadMore,
3694
+ disabled: loading,
3695
+ size: "small",
3696
+ sx: { textTransform: "none" }
3697
+ },
3698
+ loading ? "Loading..." : "Load more"
3699
+ ))
3700
+ ),
3701
+ /* @__PURE__ */ React14.createElement(
3702
+ Box9,
3703
+ {
3704
+ sx: {
3705
+ p: 1.5,
3706
+ borderTop: "1px solid",
3707
+ borderColor: "divider",
3708
+ textAlign: "center"
3709
+ }
3710
+ },
3711
+ /* @__PURE__ */ React14.createElement(
3712
+ Button3,
3713
+ {
3714
+ size: "small",
3715
+ startIcon: /* @__PURE__ */ React14.createElement(SettingsIcon, null),
3716
+ onClick: () => {
3717
+ window.location.href = "/settings?tab=general";
3718
+ handleClose();
3719
+ },
3720
+ sx: { textTransform: "none" }
3721
+ },
3722
+ "Notification Settings"
3723
+ )
3724
+ )
3725
+ ));
3726
+ };
3727
+ var NotificationBell_default = NotificationBell;
3728
+
3729
+ // src/components/ErrorBoundary/ErrorBoundary.js
3730
+ import React15 from "react";
3731
+ import {
3732
+ Box as Box10,
3733
+ Typography as Typography8,
3734
+ Button as Button4,
3329
3735
  Card as Card2,
3330
3736
  CardContent as CardContent2,
3331
- Alert as Alert2,
3737
+ Alert as Alert3,
3332
3738
  Stack as Stack6
3333
3739
  } from "@mui/material";
3334
3740
  import {
3335
3741
  Refresh as Refresh2,
3336
3742
  BugReport,
3337
- Home
3743
+ Home as Home2
3338
3744
  } from "@mui/icons-material";
3339
- var ErrorBoundary = class extends React14.Component {
3745
+ var ErrorBoundary = class extends React15.Component {
3340
3746
  constructor(props) {
3341
3747
  super(props);
3342
3748
  this.state = {
@@ -3377,8 +3783,8 @@ var ErrorBoundary = class extends React14.Component {
3377
3783
  if (this.state.hasError) {
3378
3784
  const isNavigationError = (_b = (_a = this.state.error) == null ? void 0 : _a.message) == null ? void 0 : _b.includes("getBoundingClientRect");
3379
3785
  const isDOMError = ((_d = (_c = this.state.error) == null ? void 0 : _c.message) == null ? void 0 : _d.includes("null")) || ((_f = (_e = this.state.error) == null ? void 0 : _e.message) == null ? void 0 : _f.includes("undefined"));
3380
- return /* @__PURE__ */ React14.createElement(
3381
- Box9,
3786
+ return /* @__PURE__ */ React15.createElement(
3787
+ Box10,
3382
3788
  {
3383
3789
  sx: {
3384
3790
  display: "flex",
@@ -3389,32 +3795,32 @@ var ErrorBoundary = class extends React14.Component {
3389
3795
  p: 3
3390
3796
  }
3391
3797
  },
3392
- /* @__PURE__ */ React14.createElement(Card2, { sx: { maxWidth: 600, width: "100%" } }, /* @__PURE__ */ React14.createElement(CardContent2, null, /* @__PURE__ */ React14.createElement(Stack6, { spacing: 3, alignItems: "center" }, /* @__PURE__ */ React14.createElement(BugReport, { sx: { fontSize: 64, color: "error.main" } }), /* @__PURE__ */ React14.createElement(Typography7, { variant: "h5", component: "h2", textAlign: "center" }, "Oops! Something went wrong"), /* @__PURE__ */ React14.createElement(Alert2, { severity: "error", sx: { width: "100%" } }, /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2" }, isNavigationError && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement("strong", null, "UI Component Error:"), " A component tried to access an element before it was ready. This is usually temporary."), isDOMError && !isNavigationError && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement("strong", null, "DOM Error:"), " A component couldn't find an expected element. This might be due to rapid state changes."), !isNavigationError && !isDOMError && /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement("strong", null, "Application Error:"), " An unexpected error occurred while rendering the component."))), process.env.NODE_ENV === "development" && this.state.error && /* @__PURE__ */ React14.createElement(Alert2, { severity: "warning", sx: { width: "100%" } }, /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", component: "div" }, /* @__PURE__ */ React14.createElement("strong", null, "Debug Info:"), /* @__PURE__ */ React14.createElement("br", null), /* @__PURE__ */ React14.createElement("code", { style: { fontSize: "0.75rem", wordBreak: "break-word" } }, this.state.error.toString()))), /* @__PURE__ */ React14.createElement(Stack6, { direction: "row", spacing: 2 }, /* @__PURE__ */ React14.createElement(
3393
- Button3,
3798
+ /* @__PURE__ */ React15.createElement(Card2, { sx: { maxWidth: 600, width: "100%" } }, /* @__PURE__ */ React15.createElement(CardContent2, null, /* @__PURE__ */ React15.createElement(Stack6, { spacing: 3, alignItems: "center" }, /* @__PURE__ */ React15.createElement(BugReport, { sx: { fontSize: 64, color: "error.main" } }), /* @__PURE__ */ React15.createElement(Typography8, { variant: "h5", component: "h2", textAlign: "center" }, "Oops! Something went wrong"), /* @__PURE__ */ React15.createElement(Alert3, { severity: "error", sx: { width: "100%" } }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2" }, isNavigationError && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("strong", null, "UI Component Error:"), " A component tried to access an element before it was ready. This is usually temporary."), isDOMError && !isNavigationError && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("strong", null, "DOM Error:"), " A component couldn't find an expected element. This might be due to rapid state changes."), !isNavigationError && !isDOMError && /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement("strong", null, "Application Error:"), " An unexpected error occurred while rendering the component."))), process.env.NODE_ENV === "development" && this.state.error && /* @__PURE__ */ React15.createElement(Alert3, { severity: "warning", sx: { width: "100%" } }, /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2", component: "div" }, /* @__PURE__ */ React15.createElement("strong", null, "Debug Info:"), /* @__PURE__ */ React15.createElement("br", null), /* @__PURE__ */ React15.createElement("code", { style: { fontSize: "0.75rem", wordBreak: "break-word" } }, this.state.error.toString()))), /* @__PURE__ */ React15.createElement(Stack6, { direction: "row", spacing: 2 }, /* @__PURE__ */ React15.createElement(
3799
+ Button4,
3394
3800
  {
3395
3801
  variant: "contained",
3396
- startIcon: /* @__PURE__ */ React14.createElement(Refresh2, null),
3802
+ startIcon: /* @__PURE__ */ React15.createElement(Refresh2, null),
3397
3803
  onClick: this.handleRetry,
3398
3804
  color: "primary"
3399
3805
  },
3400
3806
  "Try Again"
3401
- ), /* @__PURE__ */ React14.createElement(
3402
- Button3,
3807
+ ), /* @__PURE__ */ React15.createElement(
3808
+ Button4,
3403
3809
  {
3404
3810
  variant: "outlined",
3405
- startIcon: /* @__PURE__ */ React14.createElement(Refresh2, null),
3811
+ startIcon: /* @__PURE__ */ React15.createElement(Refresh2, null),
3406
3812
  onClick: this.handleReload
3407
3813
  },
3408
3814
  "Reload Page"
3409
- ), this.props.onNavigateHome && /* @__PURE__ */ React14.createElement(
3410
- Button3,
3815
+ ), this.props.onNavigateHome && /* @__PURE__ */ React15.createElement(
3816
+ Button4,
3411
3817
  {
3412
3818
  variant: "outlined",
3413
- startIcon: /* @__PURE__ */ React14.createElement(Home, null),
3819
+ startIcon: /* @__PURE__ */ React15.createElement(Home2, null),
3414
3820
  onClick: this.props.onNavigateHome
3415
3821
  },
3416
3822
  "Go Home"
3417
- )), /* @__PURE__ */ React14.createElement(Typography7, { variant: "body2", color: "text.secondary", textAlign: "center" }, "If this problem persists, try refreshing the page or clearing your browser cache. The error has been logged for debugging."))))
3823
+ )), /* @__PURE__ */ React15.createElement(Typography8, { variant: "body2", color: "text.secondary", textAlign: "center" }, "If this problem persists, try refreshing the page or clearing your browser cache. The error has been logged for debugging."))))
3418
3824
  );
3419
3825
  }
3420
3826
  return this.props.children;
@@ -3423,7 +3829,7 @@ var ErrorBoundary = class extends React14.Component {
3423
3829
  var ErrorBoundary_default = ErrorBoundary;
3424
3830
 
3425
3831
  // src/contexts/SocketContext.js
3426
- import React15, { createContext as createContext5, useContext as useContext5, useEffect as useEffect5, useState as useState6 } from "react";
3832
+ import React16, { createContext as createContext5, useContext as useContext5, useEffect as useEffect6, useState as useState7 } from "react";
3427
3833
  import { io } from "socket.io-client";
3428
3834
  var SocketContext = createContext5();
3429
3835
  var useSocket = () => {
@@ -3434,15 +3840,15 @@ var useSocket = () => {
3434
3840
  return context;
3435
3841
  };
3436
3842
  var SocketProvider = ({ children }) => {
3437
- const [socket, setSocket] = useState6(null);
3438
- const [isConnected, setIsConnected] = useState6(false);
3439
- const [tenantToken, setTenantToken] = useState6(null);
3843
+ const [socket, setSocket] = useState7(null);
3844
+ const [isConnected, setIsConnected] = useState7(false);
3845
+ const [tenantToken, setTenantToken] = useState7(null);
3440
3846
  const { user } = useAuth();
3441
- useEffect5(() => {
3847
+ useEffect6(() => {
3442
3848
  const token = localStorage.getItem("tenantToken");
3443
3849
  setTenantToken(token);
3444
3850
  }, []);
3445
- useEffect5(() => {
3851
+ useEffect6(() => {
3446
3852
  if (user || tenantToken) {
3447
3853
  const userType = user ? "property_manager" : "tenant";
3448
3854
  const authToken = user ? localStorage.getItem("token") : tenantToken;
@@ -3469,15 +3875,15 @@ var SocketProvider = ({ children }) => {
3469
3875
  socket,
3470
3876
  isConnected
3471
3877
  };
3472
- return /* @__PURE__ */ React15.createElement(SocketContext.Provider, { value }, children);
3878
+ return /* @__PURE__ */ React16.createElement(SocketContext.Provider, { value }, children);
3473
3879
  };
3474
3880
 
3475
3881
  // src/hooks/useNotifications.js
3476
- import { useCallback as useCallback2 } from "react";
3882
+ import { useCallback as useCallback3 } from "react";
3477
3883
  import { Refresh as Refresh3, CloudUpload as CloudUpload2, Download, ContentCopy } from "@mui/icons-material";
3478
3884
  var useNotifications = () => {
3479
3885
  const notification = useNotification();
3480
- const notifyApiSuccess = useCallback2((operation, entityName) => {
3886
+ const notifyApiSuccess = useCallback3((operation, entityName) => {
3481
3887
  const messages = {
3482
3888
  create: `${entityName} created successfully`,
3483
3889
  update: `${entityName} updated successfully`,
@@ -3488,7 +3894,7 @@ var useNotifications = () => {
3488
3894
  };
3489
3895
  return notification.showSuccess(messages[operation] || `${operation} completed successfully`);
3490
3896
  }, [notification]);
3491
- const notifyApiError = useCallback2((operation, entityName, error) => {
3897
+ const notifyApiError = useCallback3((operation, entityName, error) => {
3492
3898
  var _a, _b;
3493
3899
  const baseMessages = {
3494
3900
  create: `Failed to create ${entityName}`,
@@ -3505,7 +3911,7 @@ var useNotifications = () => {
3505
3911
  { persistent: true }
3506
3912
  );
3507
3913
  }, [notification]);
3508
- const notifyFileUploadStart = useCallback2((fileName) => {
3914
+ const notifyFileUploadStart = useCallback3((fileName) => {
3509
3915
  return notification.showProgress(`Uploading ${fileName}...`, 0, {
3510
3916
  title: "File Upload",
3511
3917
  actions: [{
@@ -3515,10 +3921,10 @@ var useNotifications = () => {
3515
3921
  }]
3516
3922
  });
3517
3923
  }, [notification]);
3518
- const notifyFileUploadProgress = useCallback2((notificationId, progress, fileName) => {
3924
+ const notifyFileUploadProgress = useCallback3((notificationId, progress, fileName) => {
3519
3925
  notification.updateProgress(notificationId, progress, `Uploading ${fileName}... ${Math.round(progress)}%`);
3520
3926
  }, [notification]);
3521
- const notifyFileUploadComplete = useCallback2((notificationId, fileName) => {
3927
+ const notifyFileUploadComplete = useCallback3((notificationId, fileName) => {
3522
3928
  notification.updateNotification(notificationId, {
3523
3929
  type: "success",
3524
3930
  message: `${fileName} uploaded successfully`,
@@ -3528,7 +3934,7 @@ var useNotifications = () => {
3528
3934
  actions: []
3529
3935
  });
3530
3936
  }, [notification]);
3531
- const notifyFileUploadError = useCallback2((notificationId, fileName, error) => {
3937
+ const notifyFileUploadError = useCallback3((notificationId, fileName, error) => {
3532
3938
  notification.updateNotification(notificationId, {
3533
3939
  type: "error",
3534
3940
  message: `Failed to upload ${fileName}: ${error}`,
@@ -3541,7 +3947,7 @@ var useNotifications = () => {
3541
3947
  }]
3542
3948
  });
3543
3949
  }, [notification]);
3544
- const notifyValidationError = useCallback2((errors) => {
3950
+ const notifyValidationError = useCallback3((errors) => {
3545
3951
  const errorCount = Array.isArray(errors) ? errors.length : Object.keys(errors).length;
3546
3952
  const message = errorCount === 1 ? "Please fix the validation error" : `Please fix ${errorCount} validation errors`;
3547
3953
  return notification.showWarning(message, {
@@ -3549,7 +3955,7 @@ var useNotifications = () => {
3549
3955
  duration: 6e3
3550
3956
  });
3551
3957
  }, [notification]);
3552
- const notifyConfirmAction = useCallback2((message, onConfirm, onCancel = null) => {
3958
+ const notifyConfirmAction = useCallback3((message, onConfirm, onCancel = null) => {
3553
3959
  return notification.showAction(message, [
3554
3960
  {
3555
3961
  label: "Confirm",
@@ -3568,13 +3974,13 @@ var useNotifications = () => {
3568
3974
  title: "Confirmation Required"
3569
3975
  });
3570
3976
  }, [notification]);
3571
- const notifyLoading = useCallback2((message) => {
3977
+ const notifyLoading = useCallback3((message) => {
3572
3978
  return notification.showLoading(message);
3573
3979
  }, [notification]);
3574
- const stopLoading = useCallback2((notificationId) => {
3980
+ const stopLoading = useCallback3((notificationId) => {
3575
3981
  notification.removeNotification(notificationId);
3576
3982
  }, [notification]);
3577
- const notifyNetworkError = useCallback2(() => {
3983
+ const notifyNetworkError = useCallback3(() => {
3578
3984
  return notification.showError("Network connection lost. Please check your internet connection.", {
3579
3985
  title: "Connection Error",
3580
3986
  persistent: true,
@@ -3586,10 +3992,10 @@ var useNotifications = () => {
3586
3992
  }]
3587
3993
  });
3588
3994
  }, [notification]);
3589
- const notifyNetworkReconnected = useCallback2(() => {
3995
+ const notifyNetworkReconnected = useCallback3(() => {
3590
3996
  return notification.showSuccess("Connection restored");
3591
3997
  }, [notification]);
3592
- const notifyMaintenance = useCallback2((message, scheduledTime) => {
3998
+ const notifyMaintenance = useCallback3((message, scheduledTime) => {
3593
3999
  return notification.showWarning(message, {
3594
4000
  title: "Scheduled Maintenance",
3595
4001
  persistent: true,
@@ -3600,13 +4006,13 @@ var useNotifications = () => {
3600
4006
  }]
3601
4007
  });
3602
4008
  }, [notification]);
3603
- const notifyPermissionDenied = useCallback2((action = "perform this action") => {
4009
+ const notifyPermissionDenied = useCallback3((action = "perform this action") => {
3604
4010
  return notification.showError(`You don't have permission to ${action}`, {
3605
4011
  title: "Access Denied",
3606
4012
  duration: 6e3
3607
4013
  });
3608
4014
  }, [notification]);
3609
- const notifyDataOutOfSync = useCallback2((onRefresh) => {
4015
+ const notifyDataOutOfSync = useCallback3((onRefresh) => {
3610
4016
  return notification.showWarning("Data may be outdated", {
3611
4017
  title: "Sync Warning",
3612
4018
  actions: [{
@@ -3639,7 +4045,7 @@ var useNotifications = () => {
3639
4045
  };
3640
4046
 
3641
4047
  // src/hooks/useUnifiedNotifications.js
3642
- import { useEffect as useEffect6, useContext as useContext6, useCallback as useCallback3 } from "react";
4048
+ import { useEffect as useEffect7, useContext as useContext6, useCallback as useCallback4 } from "react";
3643
4049
 
3644
4050
  // src/utils/unifiedNotifications.js
3645
4051
  var NOTIFICATION_TYPES = {
@@ -4009,17 +4415,17 @@ var setSocketContext = (context) => unifiedNotificationManager.setSocketContext(
4009
4415
  var useUnifiedNotifications = () => {
4010
4416
  const toastContext = useNotification();
4011
4417
  const socketContext = useSocket();
4012
- useEffect6(() => {
4418
+ useEffect7(() => {
4013
4419
  if (toastContext) {
4014
4420
  setToastContext(toastContext);
4015
4421
  }
4016
4422
  }, [toastContext]);
4017
- useEffect6(() => {
4423
+ useEffect7(() => {
4018
4424
  if (socketContext) {
4019
4425
  setSocketContext(socketContext);
4020
4426
  }
4021
4427
  }, [socketContext]);
4022
- const initializePushNotifications = useCallback3(async () => {
4428
+ const initializePushNotifications = useCallback4(async () => {
4023
4429
  try {
4024
4430
  await requestNotificationPermission();
4025
4431
  await subscribeToPushNotifications();
@@ -4029,21 +4435,21 @@ var useUnifiedNotifications = () => {
4029
4435
  return false;
4030
4436
  }
4031
4437
  }, []);
4032
- const showSuccess = useCallback3((message, title, options = {}) => {
4438
+ const showSuccess = useCallback4((message, title, options = {}) => {
4033
4439
  return notifySuccess(message, title, {
4034
4440
  channels: [NOTIFICATION_CHANNELS.TOAST],
4035
4441
  sound: true,
4036
4442
  ...options
4037
4443
  });
4038
4444
  }, []);
4039
- const showError = useCallback3((message, title, options = {}) => {
4445
+ const showError = useCallback4((message, title, options = {}) => {
4040
4446
  return notifyError(message, title, {
4041
4447
  channels: [NOTIFICATION_CHANNELS.TOAST, NOTIFICATION_CHANNELS.BROWSER],
4042
4448
  persistent: true,
4043
4449
  ...options
4044
4450
  });
4045
4451
  }, []);
4046
- const showWarning = useCallback3((message, title, options = {}) => {
4452
+ const showWarning = useCallback4((message, title, options = {}) => {
4047
4453
  return notify({
4048
4454
  message,
4049
4455
  title,
@@ -4052,7 +4458,7 @@ var useUnifiedNotifications = () => {
4052
4458
  ...options
4053
4459
  });
4054
4460
  }, []);
4055
- const showInfo = useCallback3((message, title, options = {}) => {
4461
+ const showInfo = useCallback4((message, title, options = {}) => {
4056
4462
  return notify({
4057
4463
  message,
4058
4464
  title,
@@ -4061,7 +4467,7 @@ var useUnifiedNotifications = () => {
4061
4467
  ...options
4062
4468
  });
4063
4469
  }, []);
4064
- const notifyTicket = useCallback3((ticket, changeType, options = {}) => {
4470
+ const notifyTicket = useCallback4((ticket, changeType, options = {}) => {
4065
4471
  return notifyTicketUpdate(ticket, changeType, {
4066
4472
  channels: [
4067
4473
  NOTIFICATION_CHANNELS.TOAST,
@@ -4071,7 +4477,7 @@ var useUnifiedNotifications = () => {
4071
4477
  ...options
4072
4478
  });
4073
4479
  }, []);
4074
- const notifyNewMessage = useCallback3((senderName, messageContent, propertyAddress, options = {}) => {
4480
+ const notifyNewMessage = useCallback4((senderName, messageContent, propertyAddress, options = {}) => {
4075
4481
  return notifyMessage(senderName, messageContent, propertyAddress, {
4076
4482
  channels: [
4077
4483
  NOTIFICATION_CHANNELS.BROWSER,
@@ -4081,7 +4487,7 @@ var useUnifiedNotifications = () => {
4081
4487
  ...options
4082
4488
  });
4083
4489
  }, []);
4084
- const notifySystemAlert = useCallback3((message, title, options = {}) => {
4490
+ const notifySystemAlert = useCallback4((message, title, options = {}) => {
4085
4491
  return notify({
4086
4492
  message,
4087
4493
  title,
@@ -4096,7 +4502,7 @@ var useUnifiedNotifications = () => {
4096
4502
  ...options
4097
4503
  });
4098
4504
  }, []);
4099
- const showLoading = useCallback3((message, options = {}) => {
4505
+ const showLoading = useCallback4((message, options = {}) => {
4100
4506
  return notify({
4101
4507
  message,
4102
4508
  type: NOTIFICATION_TYPES.LOADING,
@@ -4105,7 +4511,7 @@ var useUnifiedNotifications = () => {
4105
4511
  ...options
4106
4512
  });
4107
4513
  }, []);
4108
- const notifyImportant = useCallback3((message, title, options = {}) => {
4514
+ const notifyImportant = useCallback4((message, title, options = {}) => {
4109
4515
  return notify({
4110
4516
  message,
4111
4517
  title,
@@ -4120,7 +4526,7 @@ var useUnifiedNotifications = () => {
4120
4526
  ...options
4121
4527
  });
4122
4528
  }, []);
4123
- const notifyBatch = useCallback3(async (notifications) => {
4529
+ const notifyBatch = useCallback4(async (notifications) => {
4124
4530
  const results = [];
4125
4531
  for (const notification of notifications) {
4126
4532
  try {
@@ -4946,6 +5352,7 @@ export {
4946
5352
  NOTIFICATION_CHANNELS,
4947
5353
  NOTIFICATION_TYPES,
4948
5354
  Navbar_default as Navbar,
5355
+ NotificationBell_default as NotificationBell,
4949
5356
  NotificationManager_default as NotificationManager,
4950
5357
  NotificationPatterns,
4951
5358
  NotificationProvider,