@churchapps/apphelper
Version:
Library of helper functions for React and NextJS ChurchApps
90 lines • 6.42 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useState } from "react";
import { ApiHelper } from "@churchapps/helpers";
import { Box, Stack, Typography, Paper, List, ListItem, ListItemAvatar, ListItemText, Avatar, Chip, Divider, IconButton, Skeleton, useTheme } from "@mui/material";
import { Notifications as NotificationsIcon, Task as TaskIcon, Assignment as AssignmentIcon, OpenInNew as OpenInNewIcon } from "@mui/icons-material";
import { DateHelper } from "../../helpers";
export const Notifications = (props) => {
const [notifications, setNotifications] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const theme = useTheme();
const loadData = async () => {
setIsLoading(true);
const n = await ApiHelper.get("/notifications/my", "MessagingApi");
setNotifications(n);
setIsLoading(false);
props.onUpdate();
};
React.useEffect(() => { loadData(); }, []); //eslint-disable-line
const getAppUrl = (appName) => {
switch (appName) {
case props.appName.toLowerCase(): return "";
case "chums": return "https://app.chums.org";
case "b1": return "https://" + props.context.userChurch.church.subDomain + ".b1.church";
default: return "";
}
};
const handleClick = (notification) => {
let app = "";
let path = "";
switch (notification.contentType) {
case "task":
app = "chums";
path = "/tasks/" + notification.contentId;
break;
case "assignment":
app = "b1";
path = "/my/plans/" + notification.contentId;
break;
}
const appUrl = getAppUrl(app);
if (appUrl === "") {
props.onNavigate(path);
}
else {
window.open(appUrl + path, "_blank");
}
};
const getNotificationIcon = (contentType) => {
switch (contentType) {
case "task": return _jsx(TaskIcon, {});
case "assignment": return _jsx(AssignmentIcon, {});
default: return _jsx(NotificationsIcon, {});
}
};
const getNotificationList = () => {
if (notifications.length === 0) {
return (_jsxs(Box, { id: "notifications-empty", sx: { textAlign: 'center', py: 4 }, children: [_jsx(NotificationsIcon, { sx: { fontSize: 48, color: 'grey.400', mb: 2 } }), _jsx(Typography, { variant: "h6", color: "textSecondary", children: "No notifications" }), _jsx(Typography, { variant: "body2", color: "textSecondary", children: "You're all caught up!" })] }));
}
return (_jsx(List, { id: "notifications-list", sx: { width: '100%' }, children: notifications.map((notification, index) => {
let datePosted = new Date(notification.timeSent);
const displayDuration = DateHelper.getDisplayDuration(datePosted);
const isUnread = notification.isNew;
return (_jsxs(React.Fragment, { children: [_jsxs(ListItem, { id: `notification-item-${notification.id}`, component: "button", onClick: () => handleClick(notification), sx: {
alignItems: 'flex-start',
py: 2,
cursor: 'pointer',
bgcolor: isUnread ? 'action.hover' : 'transparent',
'&:hover': {
bgcolor: 'action.hover'
},
borderRadius: 1,
mb: 0.5
}, children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, { sx: {
bgcolor: isUnread ? 'primary.main' : 'grey.400',
width: 48,
height: 48
}, children: getNotificationIcon(notification.contentType) }) }), _jsx(ListItemText, { primary: _jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "flex-start", children: [_jsx(Typography, { variant: "body1", sx: {
fontWeight: isUnread ? 600 : 400,
flex: 1,
pr: 1
}, children: notification.message }), _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [isUnread && (_jsx(Chip, { size: "small", label: "New", color: "primary", sx: { height: 20, fontSize: '0.7rem' } })), _jsx(Typography, { variant: "caption", color: "textSecondary", children: displayDuration })] })] }), secondary: notification.link && (_jsx(Box, { sx: { mt: 1 }, children: _jsxs(IconButton, { size: "small", onClick: (e) => {
e.stopPropagation();
window.open(notification.link, '_blank');
}, sx: { p: 0.5 }, children: [_jsx(OpenInNewIcon, { fontSize: "small" }), _jsx(Typography, { variant: "caption", sx: { ml: 0.5 }, children: "View Details" })] }) })) })] }), index < notifications.length - 1 && _jsx(Divider, { variant: "inset", component: "li" })] }, notification.id));
}) }));
};
return (_jsxs(Paper, { id: "notifications-panel", elevation: 0, sx: { height: '100%', display: 'flex', flexDirection: 'column' }, children: [_jsx(Box, { id: "notifications-header", sx: { p: 2, borderBottom: 1, borderColor: 'divider' }, children: _jsx(Typography, { variant: "h6", component: "h2", children: "Notifications" }) }), _jsx(Box, { id: "notifications-content", sx: { flex: 1, overflow: 'auto' }, children: isLoading ? (_jsx(Box, { sx: { p: 2 }, children: [...Array(3)].map((_, index) => (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', mb: 2 }, children: [_jsx(Skeleton, { variant: "circular", width: 48, height: 48, sx: { mr: 2 } }), _jsxs(Box, { sx: { flex: 1 }, children: [_jsx(Skeleton, { variant: "text", width: "80%", height: 24 }), _jsx(Skeleton, { variant: "text", width: "40%", height: 20 })] })] }, index))) })) : (getNotificationList()) })] }));
};
//# sourceMappingURL=Notifications.js.map