import React, { useContext, useEffect, useRef, useState } from "react"; import axios from "axios"; import { AiOutlineInfoCircle, AiOutlineDelete } from "react-icons/ai"; import { BiSend } from "react-icons/bi"; import { BsChatText } from "react-icons/bs"; import { User } from "../index"; import { getSiblings } from "../utils"; import "../styles/Comments.css"; export default function Messages({ place, infos, lastMessage, admin }) { const [user] = useContext(User); const [messages, setMessages] = useState([]); const [newComment, setNewComment] = useState(""); const [loading, setLoading] = useState(true); const input = useRef(); const chat = useRef(); let width = window.innerWidth > 0 ? window.innerWidth : screen.width; width = width > 600; const Submit = (ev) => { if (newComment.replace(/\s/g, "").length) { ev.preventDefault(); axios .post( `${process.env.REACT_APP_BASE_URL_BACK}/${encodeURIComponent(place)}/comments`, { content: newComment }, { withCredentials: true }, ) .then((res) => { setMessages((old_messages) => [...old_messages, res.data]); updateValue(""); }) .catch((e) => { console.log(e); alert("Une erreur est survenue"); updateValue(""); }); } }; const Delete = (ev) => { if (infos && admin) { ev.preventDefault(); axios .delete(`${process.env.REACT_APP_BASE_URL_BACK}/news/${ev.target.id}`, { withCredentials: true, }) .then(() => { setLoading(true); }) .catch((e) => { alert("Une erreur est survenue"); console.log(e); }); } }; const updateValue = (value) => { setNewComment(value); if (input.current) { input.current.style.height = ""; input.current.style.height = `${input.current.scrollHeight + 5}px`; } }; const OpenSideBar = (ev) => { if (!width && ev.target.parentNode.parentNode.className == "comments-side-bar") { ev.preventDefault(); ev.stopPropagation(); let sidebar = ev.target.parentNode.parentNode; if (!parseInt(sidebar.style.width, 10)) { let siblings = getSiblings(sidebar); for (let sibling of siblings) { sibling.style.width = 0; } if (ev.target.id == "comments-icon-left") { let otherIcon = document.getElementById("comments-icon-right"); otherIcon.style.cssText = "background-color: none"; } else if (ev.target.id == "comments-icon-right") { let otherIcon = document.getElementById("comments-icon-left"); otherIcon.style.cssText = "background-color: none"; } sidebar.style.width = "100%"; ev.target.style.cssText = "background-color: white; color: black"; } else { let mainPage = document.getElementById("restaurant-main-page"); mainPage.style.width = "100%"; sidebar.style.width = 0; ev.target.style.cssText = "background-color: none; color: white"; } } }; useEffect(() => { axios .get( `${process.env.REACT_APP_BASE_URL_BACK}/${encodeURIComponent(place)}/${ infos ? "news" : "comments" }${admin ? "?admin=true" : ""}`, ) .then((res) => { setMessages(res.data); setLoading(false); if (!width && infos && res.data.length) { let otherIcon = document.getElementById("comments-icon-left"); otherIcon.style.cssText = "border: 1px solid red"; } }) .catch((e) => { console.log(e); setLoading(false); }); }, [place, loading]); useEffect(() => { if (chat.current) { if (infos) { chat.current.scrollTop = 0; } else { let position = chat.current.scrollHeight - chat.current.clientHeight; chat.current.scrollTop = position; } } }, [chat.current, messages.length]); useEffect(() => { if (input.current) { input.current.style.height = ""; input.current.style.height = `${input.current.scrollHeight + 5}px`; } }, [newComment]); useEffect(() => { if (lastMessage?.data) { let new_message = JSON.parse(lastMessage.data); if (new_message.type == "news" && infos) { setMessages((old_messages) => [new_message.comment, ...old_messages]); } else if ( !infos && new_message.type == "comment" && new_message.comment.username != user.name ) { setMessages((old_messages) => [...old_messages, new_message.comment]); } } }, [lastMessage]); return ( <div className={`comments-side-bar${admin ? "comments-full-size" : ""}`}> {!admin && ( <div className="comments-title"> {infos ? ( <> <AiOutlineInfoCircle id="comments-icon-left" onClick={OpenSideBar} /> Infos </> ) : ( <> <BsChatText id="comments-icon-right" onClick={OpenSideBar} /> Commentaires </> )} </div> )} <div ref={chat} className={`comments-scroll-bar ${infos && "infos-scroll-bar"}`}> {!messages.length ? ( loading ? ( <div className={`comments-loading ${infos && "infos-loading"}`}>Chargement...</div> ) : ( <div className="no-comments"> <div> Il n'y a{" "} {infos ? `aucune information particulière concernant ${place}` : `aucun commentaire sur ${place}`} </div> </div> ) ) : ( messages.map((message, index) => { let [date, hour] = message.published_at.split(/[T\s]/); let [year, month, day] = date.split("-"); return ( <div key={index} className="comment"> <div className={`comment-title${infos ? "-infos" : ""}`}> {admin && ( <AiOutlineDelete id={message.id} onClick={Delete} className="comment-delete-button" /> )} {infos ? message.title : message.username} </div> <div className="comment-content">{message.content}</div> <div className="comment-date"> {`À ${hour.substring(0, 5)} le ${day}/${month}/${year}`} </div> </div> ); }) )} </div> {!infos && user && ( <div className="comment-input-container"> <textarea className="comments-input" ref={input} value={newComment} onChange={(ev) => updateValue(ev.target.value)} placeholder="Ajouter un commentaire" onKeyDown={(ev) => { if (ev.key === "Enter" && ev.shiftKey == false) { ev.preventDefault(); Submit(ev); } }} /> <button className="comment-input-button" onClick={Submit}> <BiSend /> </button> </div> )} </div> ); }