@churchapps/apphelper
Version:
Library of helper functions for React and NextJS ChurchApps
79 lines • 7.41 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Button, TextField, Paper, Box, Typography, Stack, IconButton, List, ListItemAvatar, ListItemText, ListItemButton, InputAdornment, Divider, Skeleton } from "@mui/material";
import { ArrowBack as ArrowBackIcon, PersonSearch as PersonSearchIcon } from "@mui/icons-material";
import React, { useEffect, useState } from "react";
import { ApiHelper, Locale } from "../../helpers";
import { AddNote } from "../notes/AddNote";
import { PersonAvatar } from "../PersonAvatar";
export const NewPrivateMessage = (props) => {
const [searchText, setSearchText] = React.useState("");
const [searchResults, setSearchResults] = React.useState([]);
const [selectedPerson, setSelectedPerson] = React.useState(null);
const handleChange = (e) => {
setSearchText(e.currentTarget.value);
};
/*
const handleKeyDown = (e: React.KeyboardEvent<any>) => {
//if (e.key === "Enter") { e.preventDefault(); handleSubmit(null); }
}
*/
const handlePersonSelected = async (person) => {
try {
const existing = await ApiHelper.get("/privateMessages/existing/" + person.id, "MessagingApi");
if (existing?.id) {
existing.person = person;
props.onSelectMessage(existing);
return;
}
}
catch (error) {
// No existing conversation found, continue to create new one
}
setSelectedPerson(person);
};
const handleNoteAdded = () => {
handlePersonSelected(selectedPerson);
};
const createConversation = async () => {
const conv = { allowAnonymousPosts: false, contentType: "privateMessage", contentId: props.context.person.id, title: props.context.person.name.display + " " + Locale.label("wrapper.privateMessage", "Private Message"), visibility: "hidden" };
const result = await ApiHelper.post("/conversations", [conv], "MessagingApi");
const pm = {
fromPersonId: props.context.person.id,
toPersonId: selectedPerson.id,
conversationId: result[0].id
};
const privateMessages = await ApiHelper.post("/privateMessages", [pm], "MessagingApi");
return privateMessages[0].conversationId;
};
useEffect(() => {
if (props.selectedPerson)
handlePersonSelected(props.selectedPerson);
}, [props.selectedPerson]);
const [isSearching, setIsSearching] = useState(false);
const handleSearchSubmit = async (e) => {
if (e !== null)
e.preventDefault();
if (!searchText.trim())
return;
setIsSearching(true);
const term = escape(searchText.trim());
const data = await ApiHelper.get("/people/search?term=" + term, "MembershipApi");
setSearchResults(data);
setIsSearching(false);
};
if (!selectedPerson) {
return (_jsxs(Paper, { elevation: 0, sx: { height: "100%", display: "flex", flexDirection: "column" }, children: [_jsx(Box, { sx: { p: 2, borderBottom: 1, borderColor: "divider" }, children: _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 2, children: [_jsx(IconButton, { onClick: props.onBack, children: _jsx(ArrowBackIcon, {}) }), _jsx(Typography, { variant: "h6", component: "h2", children: Locale.label("wrapper.newPrivateMessage", "New Private Message") })] }) }), _jsx(Box, { sx: { p: 3 }, children: _jsxs(Stack, { spacing: 3, children: [_jsxs(Box, { children: [_jsx(Typography, { variant: "body1", color: "textSecondary", gutterBottom: true, children: Locale.label("wrapper.searchForPerson", "Search for a person to message") }), _jsx(TextField, { fullWidth: true, placeholder: "Search by name...", id: "searchText", "data-testid": "search-input", value: searchText, onChange: handleChange, onKeyDown: (e) => {
e.stopPropagation();
if (e.key === "Enter")
handleSearchSubmit(null);
}, InputProps: {
startAdornment: (_jsx(InputAdornment, { position: "start", children: _jsx(PersonSearchIcon, { color: "action" }) })),
endAdornment: (_jsx(InputAdornment, { position: "end", children: _jsx(Button, { variant: "contained", size: "small", onClick: handleSearchSubmit, disabled: !searchText.trim() || isSearching, children: Locale.label("common.search", "Search") }) }))
}, sx: { mt: 1 } })] }), isSearching && (_jsx(Box, { 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 } }), _jsx(Skeleton, { variant: "text", width: "60%", height: 24 })] }, `skeleton-${index}`))) })), !isSearching && searchResults.length > 0 && (_jsxs(Box, { children: [_jsxs(Typography, { variant: "subtitle2", color: "textSecondary", gutterBottom: true, children: [searchResults.length, " ", searchResults.length === 1 ? "person" : "people", " found"] }), _jsx(List, { sx: { bgcolor: "background.paper", borderRadius: 1 }, children: searchResults.map((person, index) => (_jsxs(React.Fragment, { children: [_jsxs(ListItemButton, { onClick: () => handlePersonSelected(person), sx: { py: 2 }, children: [_jsx(ListItemAvatar, { children: _jsx(PersonAvatar, { person: person, size: "small" }) }), _jsx(ListItemText, { primary: person.name.display, secondary: person.contactInfo?.email || "" })] }), index < searchResults.length - 1 && _jsx(Divider, {})] }, person.id))) })] })), !isSearching && searchText && searchResults.length === 0 && (_jsxs(Box, { sx: { textAlign: "center", py: 4 }, children: [_jsx(PersonSearchIcon, { sx: { fontSize: 48, color: "grey.400", mb: 2 } }), _jsx(Typography, { variant: "h6", color: "textSecondary", children: "No people found" }), _jsx(Typography, { variant: "body2", color: "textSecondary", children: "Try searching with a different name" })] }))] }) })] }));
}
else {
return (_jsxs(Paper, { elevation: 0, sx: { height: "100%", display: "flex", flexDirection: "column" }, children: [_jsx(Box, { sx: { p: 2, borderBottom: 1, borderColor: "divider" }, children: _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 2, children: [_jsx(IconButton, { onClick: props.onBack, children: _jsx(ArrowBackIcon, {}) }), _jsx(Typography, { variant: "h6", component: "h2", children: Locale.label("wrapper.newPrivateMessage", "New Private Message") })] }) }), _jsxs(Box, { sx: { p: 3 }, children: [_jsxs(Stack, { direction: "row", spacing: 2, alignItems: "center", sx: { mb: 3 }, children: [_jsx(PersonAvatar, { person: selectedPerson, size: "medium" }), _jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle1", fontWeight: "medium", children: selectedPerson.name.display }), selectedPerson.contactInfo?.email && (_jsx(Typography, { variant: "body2", color: "textSecondary", children: selectedPerson.contactInfo.email }))] })] }), _jsx(Divider, { sx: { mb: 3 } }), _jsx(AddNote, { context: props.context, conversationId: null, onUpdate: handleNoteAdded, createConversation: createConversation })] })] }));
}
};
//# sourceMappingURL=NewPrivateMessage.js.map