UNPKG

@crazy-web/feedback

Version:

A feedback form handler package that shows a popup based on allowed URLs.

251 lines (246 loc) 13.7 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.updatedSelectedCardComments = exports.commentSubmit = exports.onFeedbackCardClick = exports.renderComments = exports.renderFeedbackDetails = void 0; const config_1 = require("../core/lib/config"); const fetchIdeasComments_1 = require("../core/usecases/fetchIdeasComments"); const submitIdeaComment_1 = require("../core/usecases/submitIdeaComment"); const checkIsDarkMode_1 = require("./reuseables/checkIsDarkMode"); const closeIcon_1 = require("./reuseables/closeIcon"); const comentBox_1 = require("./reuseables/comentBox"); const featureCard_1 = require("./reuseables/featureCard"); const renderFeedbackDetails = (selectedCard, data) => { const { config, orgData } = data; const { primaryColor = config_1.configData === null || config_1.configData === void 0 ? void 0 : config_1.configData.primaryColor, theme = config_1.configData === null || config_1.configData === void 0 ? void 0 : config_1.configData.theme } = config !== null && config !== void 0 ? config : {}; const isDarkMode = (0, checkIsDarkMode_1.checkIsDarkMode)({ theme }); const { userData } = orgData; const sliderBackgroundColor = isDarkMode ? "#1B1D21" : "#F8F9FA"; const sliderBorderColor = isDarkMode ? "#313337" : "#E5E7EB"; const backgroundColor = "#fff"; const textColor = "#474747"; const commentHeadingColor = isDarkMode ? "#D2D3E0" : "#303540"; const fieldBg = isDarkMode ? "#222429" : "#FFFFFF"; const fieldTextColor = isDarkMode ? "#FAFAFA" : "#303540"; const fieldBorder = isDarkMode ? "1px solid #52526F40" : "1px solid #E5E7EB"; return ` <div id="prodio-feedback-details-comment" class="prodio-feedback-card-animate prodio-feedback-hidden-scrollbar" style="position:fixed;top:0;right:0;height:100%;width:400px;z-index:13;background-color:${sliderBackgroundColor};overflow-y:auto;padding:15px;" > <span type="button" id="close-feedback-btn" style="cursor: pointer; z-index: 25; width: max-content;position:absolute;right:25px;top:25px;"> ${(0, closeIcon_1.renderCloseIcon)({ stroke: isDarkMode ? "#9FA1A7" : "#718096", size: "20" })} </span> ${(0, featureCard_1.FeatureCards)(selectedCard, 2, "detail", primaryColor, 1, isDarkMode)} <hr style="height:0.2px;border:none; background: ${sliderBorderColor};margin:15px -15px 0 -15px;"/> <div style="display:flex;flex-direction:column;gap:10px;padding:10px 0px 20px 0px;"> <h3 id="prodio-ideas-comment-count-${selectedCard.id}" style="font-weight:700;font-size:18px;color:${commentHeadingColor};margin:0;padding:0;margin-bottom:5px;">Add a comment</h3> <div style="display:flex;gap:8px; width:100%;"> <div style="display:flex;flex-direction:column;gap:20px; width:100%;"> <textarea type="text" id="prodio-ideas-comment" placeholder="Add a comment..." autocomplete="off" style="padding: 6px 8px;font-size:14px; border-radius: 5px;border: ${fieldBorder}; outline: none; background: ${fieldBg}; color: ${fieldTextColor};" rows="2" ></textarea> <button id="prodio-ideas-comment-submit" style="padding: 5px 20px;border: none; width:max-content; background-color: ${primaryColor}; border-radius: 5px; color: #fff; font-size: 14px; cursor: pointer;"> Submit </button> </div> </div> </div> <hr style="height:0.2px;border:none; background: ${sliderBorderColor};margin:0 0 15px 0"/> <h3 id="prodio-ideas-comment-count-${selectedCard.id}" style="font-weight:700;font-size:18px;color:${commentHeadingColor};margin:0;padding:0;margin-bottom:20px;">Comments (${selectedCard.comments})</h3> <div id="prodio-ideas-comment-list" style="display:flex;flex-direction:column;gap:15px;"></div> </div> `; }; exports.renderFeedbackDetails = renderFeedbackDetails; // export const renderComments = async (resetData: boolean = false, selectedCard: any) => { // let currentPage = 1; // let isFetching = false; // let hasMoreData = true; // const container = document.getElementById("prodio-feedback-details-comment"); // const commentsContainer = document.getElementById("prodio-ideas-comment-list") // if (!container || !commentsContainer) return; // if (resetData) { // currentPage = 1; // hasMoreData = true; // commentsContainer.innerHTML = ""; // Clear previous feedbacks // } // const loadMoreComments = async () => { // if (isFetching || !hasMoreData) return; // isFetching = true; // const res = await fetchIdeasComments({ feedbackId: selectedCard?.id, page: currentPage }); // const comments = res?.data || []; // if (comments.length > 0) { // const fragment = document.createDocumentFragment(); // comments.forEach((comment: any, index: number) => { // const card = document.createElement("div"); // card.innerHTML = renderCommentBox(comment); // card.setAttribute("data-comment", JSON.stringify(comment)); // Store ID for delegation // fragment.appendChild(card); // }); // commentsContainer.appendChild(fragment); // Append all at once // currentPage++; // Move to next page // } else { // hasMoreData = false; // Stop fetching if no more data // } // isFetching = false; // }; // await loadMoreComments(); // Load initial feedbacks // const handleScroll = async () => { // const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 20; // if (nearBottom) { // await loadMoreComments(); // } // }; // setTimeout(() => { // container.addEventListener("scroll", handleScroll); // }, 100); // } // <span style="aspect-ratio:1;display:flex;justify-content:center;align-items:center;width:30px;height:30px;background-color:${generateRandomColors({ string: userData?.name })};color:white;font-size:14px;border-radius:50px;"> ${userData?.name ? userData?.name[0] : "A"}</span> const renderComments = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (resetData = false, selectedCard, primaryColor, isDarkMode) { let currentPage = 1; let isFetching = false; let hasMoreData = true; const container = document.getElementById("prodio-feedback-details-comment"); const commentsContainer = document.getElementById("prodio-ideas-comment-list"); if (!container || !commentsContainer) return; // Remove existing comments if reset is requested if (resetData) { currentPage = 1; hasMoreData = true; commentsContainer.innerHTML = ""; // Clear previous feedbacks } // Add loading spinner only on first render let loadingIndicator = commentsContainer.querySelector(".prodio-spinner-container"); if (!loadingIndicator) { loadingIndicator = document.createElement("div"); loadingIndicator.classList.add("prodio-spinner-container"); loadingIndicator.innerHTML = `<div class="prodio-spinner"></div>`; commentsContainer.appendChild(loadingIndicator); } const loadMoreComments = () => __awaiter(void 0, void 0, void 0, function* () { if (isFetching || !hasMoreData) return; isFetching = true; // Show loader only for the first render, hide it after data is fetched if (currentPage === 1) loadingIndicator.style.display = "flex"; try { const res = yield (0, fetchIdeasComments_1.fetchIdeasComments)({ feedbackId: selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.id, page: currentPage }); const comments = (res === null || res === void 0 ? void 0 : res.data) || []; if (comments.length > 0) { const fragment = document.createDocumentFragment(); comments.forEach((comment) => { const card = document.createElement("div"); card.innerHTML = (0, comentBox_1.renderCommentBox)(comment, primaryColor, isDarkMode); card.setAttribute("data-comment", JSON.stringify(comment)); fragment.appendChild(card); }); commentsContainer.appendChild(fragment); currentPage++; } else { hasMoreData = false; // Show "No comments found" only if it's the first page if (currentPage === 1) { commentsContainer.innerHTML = "<div class='prodio-no-data'>No comments found.</div>"; } } } catch (error) { console.error("Error fetching comments:", error); } finally { isFetching = false; loadingIndicator.style.display = "none"; // Hide loader after fetching first batch } }); yield loadMoreComments(); // Load initial comments const handleScroll = () => __awaiter(void 0, void 0, void 0, function* () { const nearBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 20; if (nearBottom) { yield loadMoreComments(); } }); setTimeout(() => { container.addEventListener("scroll", handleScroll); }, 100); }); exports.renderComments = renderComments; const onFeedbackCardClick = (selectedCard, data, primaryColor, isDarkMode) => { document.addEventListener("click", (event) => { const target = event.target; const feedbackDetails = document.getElementById("feedback-details"); const card = target.closest(".prodio-feedback-card"); const closeBtn = target.closest("#close-feedback-btn"); // Checks if span or any of its children is clicked if (card && feedbackDetails && !selectedCard) { const feedbackData = JSON.parse(card.getAttribute("data-feedback") || "{}"); selectedCard = feedbackData; feedbackDetails.style.display = "block"; feedbackDetails.innerHTML = (0, exports.renderFeedbackDetails)(feedbackData, data); (0, exports.renderComments)(false, selectedCard, primaryColor, isDarkMode); (0, exports.commentSubmit)(selectedCard, data, primaryColor, isDarkMode); (0, comentBox_1.handleDeleteIdeasComment)(selectedCard, primaryColor, isDarkMode); } if (closeBtn && feedbackDetails) { feedbackDetails.style.display = "none"; selectedCard = null; } }); }; exports.onFeedbackCardClick = onFeedbackCardClick; const commentSubmit = (selectedCard, data, primaryColor, isDarkMode) => { var _a; (_a = document.getElementById("prodio-ideas-comment-submit")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", () => __awaiter(void 0, void 0, void 0, function* () { const submitButton = document.getElementById("prodio-ideas-comment-submit"); const contentInput = document.getElementById("prodio-ideas-comment"); const content = contentInput.value; if (content) { const { orgData } = data; const { userData } = orgData; const { id, name } = userData; submitButton.disabled = true; submitButton.classList.add("prodio-disabled-btn"); const dataToSend = { issue_id: selectedCard === null || selectedCard === void 0 ? void 0 : selectedCard.id, content: content, user_id: id, user_name: name }; (0, submitIdeaComment_1.submitIdeaComment)(dataToSend).then((res) => { (0, exports.renderComments)(true, selectedCard, primaryColor, isDarkMode); contentInput.value = ""; submitButton.disabled = false; submitButton.classList.remove("prodio-disabled-btn"); (0, exports.updatedSelectedCardComments)(selectedCard, "increment", primaryColor, isDarkMode); }); } })); }; exports.commentSubmit = commentSubmit; const updatedSelectedCardComments = (selectedCard, type, primaryColor, isDarkMode) => { const updatedValue = type === "increment" ? selectedCard.comments + 1 : selectedCard.comments - 1; const count = document.getElementById(`prodio-ideas-comment-count-${selectedCard.id}`); if (count) { count.innerHTML = `Comments (${updatedValue})`; } selectedCard.comments = updatedValue; const cardToUpdate = document.querySelector(`[data-feedback-id="${selectedCard.id}"]`); const updatedFeedback = Object.assign(Object.assign({}, selectedCard), { comments: updatedValue }); if (cardToUpdate) { cardToUpdate.innerHTML = (0, featureCard_1.FeatureCards)(updatedFeedback, 0, "card", primaryColor, 1, isDarkMode); cardToUpdate.setAttribute("data-feedback", JSON.stringify(updatedFeedback)); } }; exports.updatedSelectedCardComments = updatedSelectedCardComments;