add_user_conv impl
This commit is contained in:
@@ -1,23 +1,27 @@
|
||||
import { useHotel } from "../HotelContext";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useRef } from "react";
|
||||
|
||||
//import {fetchMessage} from .
|
||||
|
||||
import "./chatWidget.css"
|
||||
|
||||
export default function ChatWidget({convlist}) {
|
||||
const [messages, setMessages] = useState([]);
|
||||
const { fetchMessages, sendMessage } = useHotel();
|
||||
const [activeConvId, setActiveConvId] = useState(null);
|
||||
const { fetchMessages, sendMessage,
|
||||
usersById, clientId, fetchConvUsers,
|
||||
addUserToConv
|
||||
} = useHotel();
|
||||
|
||||
const [activeConvId, setActiveConvId] = useState(null);
|
||||
const [showAddUsers, setShowAddUsers] = useState(false);
|
||||
|
||||
const handleOpenConv = async (conv_id) => {
|
||||
setActiveConvId(conv_id);
|
||||
const msg = await fetchMessages({ conv_id });
|
||||
setMessages(msg);
|
||||
};
|
||||
|
||||
return (
|
||||
console.log("client id in chat widget");
|
||||
|
||||
return (
|
||||
<div className="chatWidget">
|
||||
<div className="convlist">
|
||||
{convlist.map(conv => (
|
||||
@@ -25,12 +29,39 @@ export default function ChatWidget({convlist}) {
|
||||
key={conv.id}
|
||||
id={conv.id}
|
||||
title={conv.title}
|
||||
onOpenConv={handleOpenConv}
|
||||
onOpenConv={setActiveConvId}
|
||||
/>
|
||||
))}
|
||||
|
||||
<div className="convUtils">
|
||||
<button
|
||||
disabled={!activeConvId}
|
||||
onClick={() => setShowAddUsers(v => !v)}
|
||||
>
|
||||
Add users
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<MessagesBox messages={messages} />
|
||||
{showAddUsers && activeConvId && (
|
||||
<AddUsersMenu
|
||||
convId={activeConvId}
|
||||
usersById={usersById}
|
||||
fetchConvUsers={fetchConvUsers}
|
||||
onValidate={addUserToConv}
|
||||
onClose={() => setShowAddUsers(false)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{activeConvId && (
|
||||
<MessagesBox
|
||||
conv_id={activeConvId}
|
||||
fetchMessages={fetchMessages}
|
||||
usersById={usersById}
|
||||
clientId={clientId}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SenderBox
|
||||
conv_id={activeConvId}
|
||||
onSend={sendMessage}
|
||||
@@ -41,9 +72,11 @@ export default function ChatWidget({convlist}) {
|
||||
}
|
||||
|
||||
function SenderBox({ conv_id, onSend, disabled }) {
|
||||
|
||||
const [text, setText] = useState("");
|
||||
|
||||
const handleSend = () => {
|
||||
console.log("conv_Id: ",conv_id)
|
||||
if (!text.trim() || !conv_id) return;
|
||||
|
||||
onSend({
|
||||
@@ -55,17 +88,78 @@ function SenderBox({ conv_id, onSend, disabled }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="senderbox">
|
||||
<div hidden={disabled} className="senderbox">
|
||||
<input
|
||||
value={text}
|
||||
onChange={e => setText(e.target.value)}
|
||||
placeholder="Type a message…"
|
||||
/>
|
||||
<button disabled={disabled} onClick={handleSend}>Send</button>
|
||||
<button onClick={handleSend}>Send</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function AddUsersMenu({ convId, usersById, fetchConvUsers, onValidate, onClose }) {
|
||||
const [selected, setSelected] = useState(new Set());
|
||||
|
||||
//new function to fetch already present users in the conv
|
||||
//let current = fetchConvUsers(convId);
|
||||
|
||||
const toggleUser = (id) => {
|
||||
setSelected(prev => {
|
||||
const next = new Set(prev);
|
||||
next.has(id) ? next.delete(id) : next.add(id);
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
const handleValidate = () => {
|
||||
if (selected.size === 0) return;
|
||||
|
||||
onValidate({
|
||||
conv_id: convId,
|
||||
users: [...selected],
|
||||
});
|
||||
|
||||
onClose();
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
console.log("fetching conv users ar :", convId);
|
||||
const ids = await fetchConvUsers({ conv_id: convId });
|
||||
setSelected(new Set(ids));
|
||||
}
|
||||
load();
|
||||
}, [convId, fetchConvUsers]);
|
||||
|
||||
return (
|
||||
<div className="addUsersMenu">
|
||||
<h3>Add users</h3>
|
||||
|
||||
<ul>
|
||||
{Object.entries(usersById).map(([id, name]) => (
|
||||
<li key={id}>
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={selected.has(Number(id))}
|
||||
onChange={() => toggleUser(Number(id))}
|
||||
/>
|
||||
{name}
|
||||
</label>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<button onClick={handleValidate}>Validate</button>
|
||||
<button onClick={onClose}>Cancel</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ConvCard({id, title, onOpenConv}) {
|
||||
return(
|
||||
@@ -77,21 +171,43 @@ function ConvCard({id, title, onOpenConv}) {
|
||||
)
|
||||
}
|
||||
|
||||
function MessagesBox({ messages }) {
|
||||
function MessagesBox({ conv_id, fetchMessages, usersById, clientId }) {
|
||||
|
||||
const [messages, setMessages] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
const msg = await fetchMessages({ conv_id });
|
||||
setMessages(msg);
|
||||
}
|
||||
load();
|
||||
}, [conv_id]);
|
||||
|
||||
if (!messages || messages.length === 0) {
|
||||
return <div className="messagesbox empty">No messages</div>
|
||||
}
|
||||
console.log("FETCH RESULT =", messages);
|
||||
//console.log("FETCH RESULT =", messages);
|
||||
return (
|
||||
|
||||
<div className="messagebox">
|
||||
{messages.map(msg => (
|
||||
<div key = {msg.id} className = "msg">
|
||||
<p><strong>Sender:</strong> {msg.sender_id}</p>
|
||||
<p>{msg.content}</p>
|
||||
<small>{msg.sent_at}</small>
|
||||
</div>
|
||||
))}
|
||||
{messages
|
||||
.slice() // don’t mutate state
|
||||
.sort((a, b) => new Date(a.sent_at) - new Date(b.sent_at))
|
||||
.map(msg => {
|
||||
const isMine = msg.sender_id === clientId
|
||||
|
||||
return(
|
||||
<div key = {msg.id}
|
||||
className={`msg ${isMine ? "msg--mine" : "msg--theirs"}`}>
|
||||
<p>
|
||||
<strong>Sender:</strong>{" "}
|
||||
{usersById[msg.sender_id] ?? "Unknown user"}
|
||||
</p>
|
||||
<p>{msg.content}</p>
|
||||
<small>{msg.sent_at}</small>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user