Fix messages

This commit is contained in:
2026-04-26 03:14:54 -04:00
parent 2c7584c00f
commit 2c7085b04b
9 changed files with 981 additions and 409 deletions
+243 -219
View File
@@ -2,10 +2,10 @@
import React, { useEffect, useState } from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
import getImage from "../../utils/getImage";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useMutation } from "@tanstack/react-query";
import { commentsData } from "../../services/services";
import queryKeys from "../../services/queryKeys";
import getCustomTime from "../../utils/getCustomTime";
// import queryKeys from "../../services/queryKeys";
// import getCustomTime from "../../utils/getCustomTime";
export default function Comments() {
// const {data:contacts, isFetching, isError, error} = useQuery({
@@ -65,50 +65,50 @@ export default function Comments() {
const contactsCategory = getContactData?.data?.data?.category; // LIST OF CATEGORY
return (
<>
<BreadcrumbComBS title="Comments" paths={["Dashboard", "Comments"]} />
{getContactData?.isPending ? (
<>
<div className="row">
<div className="col-12">
<p className="text-mute">Loading...</p>
</div>
</div>
</>
) : getContactData?.error ? (
<div className="row">
<div className="col-12">
<p className="text-danger">{getContactData?.error?.message}</p>
</div>
<>
<BreadcrumbComBS title="Comments" paths={["Dashboard", "Comments"]} />
{getContactData?.isPending ? (
<>
<div className="row">
<div className="col-12">
<p className="text-mute">Loading...</p>
</div>
) : (
<div className="row">
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
<div className="col-12">
<div
className="card card-statistics mail-contant"
style={{ minHeight: "200px", borderRadius: "10px" }}
>
<div className="card-body p-0">
<div className="row no-gutters">
<div className="col-md-4 col-xxl-2 col-md-4">
<div className="mail-sidebar">
<div className="row justify-content-center">
<div className="d-none col-12">
<div className="text-center mail-sidebar-title px-4">
<a
href="#"
className="btn btn-primary btn-block py-3 font-weight-bold font-18"
>
<i className="fa fa-plus pl-2"></i>
</a>
</div>
</div>
<div className="col-12">
<div className="px-4 py-4">
<ul className="pl-0">
<li className="py-2">
<a href="#">
</div>
</>
) : getContactData?.error ? (
<div className="row">
<div className="col-12">
<p className="text-danger">{getContactData?.error?.message}</p>
</div>
</div>
) : (
<div className="row">
{/*<div className="vh-100 col-12 flex align-items-center">Coming Soon</div>*/}
<div className="col-12">
<div
className="card card-statistics mail-contant"
style={{ minHeight: "200px", borderRadius: "10px" }}
>
<div className="card-body p-0">
<div className="row no-gutters">
<div className="col-md-4 col-xxl-2 col-md-4">
<div className="mail-sidebar">
<div className="row justify-content-center">
<div className="d-none col-12">
<div className="text-center mail-sidebar-title px-4">
<a
href="#"
className="btn btn-primary btn-block py-3 font-weight-bold font-18"
>
<i className="fa fa-plus pl-2"></i>
</a>
</div>
</div>
<div className="col-12">
<div className="px-4 py-4">
<ul className="pl-0">
<li className="py-2">
<a href="#">
<span className="nav align-items-center">
<span>
<i className="fa fa-envelope-o text-primary pr-4"></i>
@@ -122,84 +122,89 @@ export default function Comments() {
</span>
</span>
</span>
</a>
</li>
{/*<li className="py-2">*/}
{/* <a href="#">*/}
{/* <span*/}
{/* className="nav align-items-center">*/}
{/* <span>*/}
{/* <i className="fa fa-paper-plane-o pr-4"></i>*/}
{/* </span>*/}
{/* <span>*/}
{/* <span>Replied Mail</span>*/}
{/* </span>*/}
{/* </span>*/}
{/* </a>*/}
{/*</li>*/}
</ul>
</a>
</li>
{/*<li className="py-2">*/}
{/* <a href="#">*/}
{/* <span*/}
{/* className="nav align-items-center">*/}
{/* <span>*/}
{/* <i className="fa fa-paper-plane-o pr-4"></i>*/}
{/* </span>*/}
{/* <span>*/}
{/* <span>Replied Mail</span>*/}
{/* </span>*/}
{/* </span>*/}
{/* </a>*/}
{/*</li>*/}
</ul>
<ul className="pl-0 mt-5">
<li
className="py-2"
onClick={() => changeActiveCategoryUID("0")}
style={{ cursor: "pointer" }}
>
<div>
<ul className="pl-0 mt-5">
<li
className="py-2"
onClick={() => changeActiveCategoryUID("0")}
style={{ cursor: "pointer" }}
>
<div>
<span className="nav align-items-center">
<span>
<i
className={`fa fa-circle-o pr-4 ${
activeCategoryUID == "0"
? "text-primary"
: "text-warning"
}`}
className={`fa fa-circle-o pr-4 ${
activeCategoryUID == "0"
? "text-primary"
: "text-warning"
}`}
></i>
</span>
<span>
<span>All</span>
</span>
</span>
</div>
</li>
{contactsCategory &&
contactsCategory.map((item) => (
<li
key={item?.cid}
className="py-2"
onClick={() =>
changeActiveCategoryUID(`${item?.cid}`)
}
style={{ cursor: "pointer" }}
>
<div>
</div>
</li>
{contactsCategory &&
contactsCategory.map((item) => (
<li
key={item?.cid}
className="py-2"
onClick={() =>
changeActiveCategoryUID(`${item?.cid}`)
}
style={{ cursor: "pointer" }}
>
<div>
<span className="nav align-items-center">
<span>
<i
className={`fa fa-circle-o pr-4 ${
activeCategoryUID ==
`${item?.cid}`
? "text-primary"
: "text-warning"
}`}
className={`fa fa-circle-o pr-4 ${
activeCategoryUID ==
`${item?.cid}`
? "text-primary"
: "text-warning"
}`}
></i>
</span>
<span>
<span>{item?.description}</span>
</span>
</span>
</div>
</li>
))}
</ul>
</div>
</div>
</div>
</li>
))}
</ul>
</div>
</div>
</div>
<div className={`${filteredContactData.length > 0 ? 'col-md-8 col-xxl-4' : 'col-md-8 col-xxl-10'} border-md-t`}>
<div className="mail-content border-right border-n h-100" style={{placeContent: 'center'}}>
{/* <div className="mail-search border-bottom">
</div>
</div>
<div
className={`${filteredContactData.length > 0 ? "col-md-8 col-xxl-4" : "col-md-8 col-xxl-10"} border-md-t`}
>
<div
className="mail-content border-right border-n h-100"
style={{ placeContent: "center" }}
>
{/* <div className="mail-search border-bottom">
<div className="row align-items-center mx-0">
<div className="col-12">
<div className="form-group pt-3">
@@ -209,141 +214,160 @@ export default function Comments() {
</div>
</div>
</div> */}
<div className="mail-msg scrollbar scroll_dark">
{ filteredContactData.length ?
filteredContactData?.map((contact, index) => {
const isActive =
contact?.uid == activeContactUID ||
(!activeContactUID && index == 0);
const avtarImage =
contact?.category === undefined
? "avtar/01.jpg"
: "avtar/" + contact.category + ".png";
return (
<div
key={contact?.uid}
onClick={() => changeActiveUID(contact?.uid)}
className={`mail-msg-item ${
isActive && "bg-light"
}`}
>
<a href="#">
<div className="media align-items-center">
<div className="mr-3">
<div className="bg-img">
<img
src={getImage(avtarImage)}
className="img-fluid"
alt="user"
/>
</div>
</div>
<div className="w-100">
<div className="mail-msg-item-titel justify-content-between">
<p>
<div className="mail-msg scrollbar scroll_dark">
{filteredContactData.length ? (
filteredContactData?.map((contact, index) => {
const isActive =
contact?.uid == activeContactUID ||
(!activeContactUID && index == 0);
const avtarImage =
contact?.category === undefined
? "avtar/01.jpg"
: "avtar/" + contact.category + ".png";
return (
<div
key={contact?.uid}
onClick={() => changeActiveUID(contact?.uid)}
className={`mail-msg-item ${
isActive && "bg-light"
}`}
>
<a href="#">
<div className="media align-items-center">
<div className="mr-3">
<div className="bg-img">
<img
src={getImage(avtarImage)}
className="img-fluid"
alt="user"
/>
</div>
</div>
<div className="w-100">
<div className="mail-msg-item-titel justify-content-between">
<p>
<span
style={{
fontSize: "14px",
color: "#148399",
fontWeight: "bolder",
}}
style={{
fontSize: "14px",
color: "#148399",
fontWeight: "bolder",
}}
>
{contact?.sender}
</span>
</p>
{/* <p className="d-none d-xl-block">06:59 <span> PM </span></p> */}
<p className="d-none d-xl-block">
</p>
{/* <p className="d-none d-xl-block">06:59 <span> PM </span></p> */}
<p className="d-none d-xl-block">
<span style={{ fontSize: "14px" }}>
{new Date(
contact?.added
contact?.added,
).toDateString()}
</span>
</p>
</div>
<h5 className="mb-0 my-2">
{contact?.title}
</h5>
<p>
{contact?.message?.length < 100
? contact?.message
: contact?.message.substring(0, 101) +
" ..."}
</p>
<p className="d-xl-none">
</p>
</div>
<h5 className="mb-0 my-2">
{contact?.title}
</h5>
<p>
{contact?.message?.length < 100
? contact?.message
: contact?.message.substring(0, 101) +
" ..."}
</p>
<p className="d-xl-none">
<span>
{new Date(
contact?.added
contact?.added,
).toDateString()}
{/* {getCustomTime(contact.added)} */}
</span>
</p>
</div>
</div>
</a>
</div>
);
})
:
<p className="text-center">Messages will appear here as soon as they are available for selection</p>
}
</div>
</div>
</p>
</div>
</div>
</a>
</div>
);
})
) : (
<p className="text-center">
Messages will appear here as soon as they are
available for selection
</p>
)}
</div>
{filteredContactData.length > 0 &&
<div className="col-xxl-6 border-t border-xxl-t">
<div className="mail-chat py-5 px-5">
<div className="media align-items-center">
<div className="bg-img mr-3">
<img
src={activeContactUID ? getImage("avtar/" + activeDetail[0].category + ".png") : getImage(filteredContactData[0] == undefined ? "avtar/01.jpg": "avtar/" + filteredContactData[0].category + ".png")}
className="img-fluid"
alt="user"
/>
</div>
<div>
<h4 className="mb-0" style={{ color: "#148399" }}>
{activeContactUID
? activeDetail[0]?.sender
: filteredContactData[0]?.sender}
</h4>
<p>
{activeContactUID
? new Date(activeDetail[0]?.added).toDateString()
: new Date(
filteredContactData[0]?.added
).toDateString()}
</p>
</div>
</div>
<div className="mt-4 d-flex justify-content-between">
<div>
<h3>
{activeContactUID
? activeDetail[0]?.title
: filteredContactData[0]?.title}
</h3>
</div>
<div className="d-flex">
{/*<a href="javascript:void(0)"><i className="fa fa-reply font-22 pr-3"></i></a>*/}
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
</div>
</div>
<div>
<p>
{activeContactUID
? activeDetail[0]?.message
: filteredContactData[0]?.message}
</p>
</div>
</div>
</div>
}
</div>
</div>
{filteredContactData.length > 0 && (
<div className="col-xxl-6 border-t border-xxl-t">
<div className="mail-chat py-5 px-5">
<div className="media align-items-center">
<div className="bg-img mr-3">
<img
src={
activeContactUID
? getImage(
"avtar/" +
activeDetail[0].category +
".png",
)
: getImage(
filteredContactData[0] == undefined
? "avtar/01.jpg"
: "avtar/" +
filteredContactData[0].category +
".png",
)
}
className="img-fluid"
alt="user"
/>
</div>
<div>
<h4 className="mb-0" style={{ color: "#148399" }}>
{activeContactUID
? activeDetail[0]?.sender
: filteredContactData[0]?.sender}
</h4>
<p>
{activeContactUID
? new Date(
activeDetail[0]?.added,
).toDateString()
: new Date(
filteredContactData[0]?.added,
).toDateString()}
</p>
</div>
</div>
<div className="mt-4 d-flex justify-content-between">
<div>
<h3>
{activeContactUID
? activeDetail[0]?.title
: filteredContactData[0]?.title}
</h3>
</div>
<div className="d-flex">
{/*<a href="javascript:void(0)"><i className="fa fa-reply font-22 pr-3"></i></a>*/}
{/*<a href="javascript:void(0)"><i className="fa fa-print font-22"></i></a>*/}
</div>
</div>
<div>
<p>
{activeContactUID
? activeDetail[0]?.message
: filteredContactData[0]?.message}
</p>
</div>
</div>
</div>
)}
</div>
</div>
</div>
)}
</>
</div>
</div>
)}
</>
);
}
@@ -1,10 +1,10 @@
import React, {memo, useState} from 'react'
import getImage from "../../../utils/getImage";
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
import React, {useState} from 'react'
//import getImage from "../../../utils/getImage";
import { useQuery, useQueryClient} from '@tanstack/react-query';
import queryKeys from '../../../services/queryKeys';
import {getTemplateConfig} from '../../../services/services';
import {Link} from "react-router-dom";
import siteLinks from "../../../links/siteLinks";
//import {Link} from "react-router-dom";
//import siteLinks from "../../../links/siteLinks";
import UploadModal from './UploadModal';
const TemplateConfigure = ({productData}) => {
@@ -13,7 +13,7 @@ const TemplateConfigure = ({productData}) => {
// /panel/myproduct/template-config
const queryClient = useQueryClient()
//const queryClient = useQueryClient()
const {data: templateData, isFetching, isError, error} = useQuery({
queryKey: queryKeys.myTemplateConfig,
@@ -1,141 +1,196 @@
import {Form, Formik} from "formik";
import { Form, Formik } from "formik";
import * as Yup from "yup";
import {useMutation} from '@tanstack/react-query';
import {setExternalURL} from '../../../services/services';
import { useMutation } from "@tanstack/react-query";
import { setExternalURL } from "../../../services/services";
import { useState } from "react";
import { Link } from "react-router-dom";
const validationSchema = Yup.object().shape({
url: Yup.string().required("URL is required").matches(/^https?:\/\/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-]+\.[a-zA-Z]+/, 'Must be like: https://example.mysite.com'),
})
url: Yup.string()
.required("URL is required")
.matches(
/^https?:\/\/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-]+\.[a-zA-Z]+/,
"Must be like: https://example.mysite.com",
),
});
// const initialValues = {
// url: '',
// };
const URLConfiguration = ({productData}) => {
const URLConfiguration = ({ productData }) => {
const [externalURLChanged, setExternalURLChanged] = useState(true);
const [externalURLChanged, setExternalURLChanged] = useState(true)
const initialValues = {
url: productData?.external_url || "",
};
const initialValues = {
url: productData?.external_url || '',
let defaultUrl = "https://" + productData?.internal_url;
let externalUrl = productData?.external_url;
const handleExternalURLChanged = (e) => {
if (e.target.value == externalUrl) {
setExternalURLChanged(true);
} else {
setExternalURLChanged(false);
}
};
// API to set url
const setURL = useMutation({
mutationFn: (fields) => {
return setExternalURL(fields);
},
onSuccess: (res) => {
if (res.data.resultCode != "0") {
// throw({message: res?.data?.resultDescription})
throw { message: "Something went wrong!" };
}
},
onSettled: () => {
setTimeout(() => {
setURL.reset();
}, 3000);
},
// onError: (err) => {
// console.log('err', err)
// }
});
const handleSubmit = (values) => {
let reqData = {
token: localStorage.getItem("token"), // USER TOKEN
uid: localStorage.getItem("uid"), // USER UID
subscription_uid: productData?.subscription_uid,
external_url: values.url,
};
setURL.mutate(reqData);
};
let defaultUrl = 'https://' + productData?.internal_url
let externalUrl = productData?.external_url
const handleExternalURLChanged = (e) => {
if(e.target.value == externalUrl){
setExternalURLChanged(true)
}else{
setExternalURLChanged(false)
}
}
// API to set url
const setURL = useMutation({
mutationFn: (fields) => {
return setExternalURL(fields)
},
onSuccess: (res) => {
if (res.data.resultCode != '0') {
// throw({message: res?.data?.resultDescription})
throw({message: 'Something went wrong!'})
}
},
onSettled: () => {
setTimeout(() => {
setURL.reset()
}, 3000)
}
// onError: (err) => {
// console.log('err', err)
// }
})
const handleSubmit = (values) => {
let reqData = {
token: localStorage.getItem('token'), // USER TOKEN
uid: localStorage.getItem('uid'), // USER UID
subscription_uid: productData?.subscription_uid,
external_url: values.url
}
setURL.mutate(reqData)
}
return <>
<div className="card card-statistics">
<div className="card-header">
<div className="card-heading">
<h4 className="card-title" style={{textTransform: 'none'}}>{defaultUrl}</h4>
</div>
</div>
{/*<div className="card-body">*/}
{/* <div className="form-group">*/}
{/* /!*<label htmlFor="exampleInputEmail1">Email address</label>*!/*/}
{/* <input type="email" className="form-control"*/}
{/* aria-describedby="defaultUrlHelp" value={defaultUrl} readOnly={true} />*/}
{/* </div>*/}
{/*</div>*/}
return (
<>
<div className="card card-statistics">
<div className="card-header">
<div className="card-heading">
<h4 className="card-title" style={{ textTransform: "none" }}>
{defaultUrl}
</h4>
</div>
</div>
{/*<div className="card-body">*/}
{/* <div className="form-group">*/}
{/* /!*<label htmlFor="exampleInputEmail1">Email address</label>*!/*/}
{/* <input type="email" className="form-control"*/}
{/* aria-describedby="defaultUrlHelp" value={defaultUrl} readOnly={true} />*/}
{/* </div>*/}
{/*</div>*/}
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => {
return (
<Form className='w-full'>
<div className="card card-statistics" style={{backgroundColor: '#b6e5ef'}}>
<div className="card-header">
<div className="card-heading">
<h4 className="card-title" style={{textTransform: 'none'}}>Set your own URL</h4>
</div>
</div>
<div className="card-body">
<div className="form-group">
<label htmlFor="exampleInputEmail1">Enter your full URL <span
className={`${(props.errors.url && props.touched.url) && 'text-danger'}`}>{props.errors.url}</span></label>
<input value={props.values.url} onChange={(e)=>{props.handleChange(e); handleExternalURLChanged(e)}} type="text"
className="form-control" id="url" aria-describedby="url"
placeholder="https://example.mysite.com"/>
</div>
<div style={{width: '100%', textAlign: 'right'}}>
<button
type="submit"
disabled={setURL.isPending || externalURLChanged}
className="btn btn-primary"
>
{setURL.isPending ? 'Loading...' : 'Submit'}
</button>
</div>
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleSubmit}
>
{(props) => {
return (
<Form className="w-full">
<div
className="card card-statistics"
style={{ backgroundColor: "#b6e5ef" }}
>
<div className="card-header">
<div className="card-heading">
<h4
className="card-title"
style={{ textTransform: "none" }}
>
Set your own URL
</h4>
</div>
</div>
<div className="card-body">
<div className="form-group">
<label htmlFor="exampleInputEmail1">
Enter your full URL{" "}
<span
className={`${props.errors.url && props.touched.url && "text-danger"}`}
>
{props.errors.url}
</span>
</label>
<input
value={props.values.url}
onChange={(e) => {
props.handleChange(e);
handleExternalURLChanged(e);
}}
type="text"
className="form-control"
id="url"
aria-describedby="url"
placeholder="https://example.mysite.com"
/>
</div>
<div style={{ width: "100%", textAlign: "right" }}>
<button
type="submit"
disabled={setURL.isPending || externalURLChanged}
className="btn btn-primary"
>
{setURL.isPending ? "Loading..." : "Submit"}
</button>
</div>
</div>
{setURL.error &&
<div className="col-12">
<p className='text-danger'>{setURL.error.message}</p>
</div>
}
{setURL.isSuccess &&
<div className="col-12">
<p className='text-success'>{'Completed successfully'}</p>
</div>
}
<div style={{backgroundColor: '#94b8c0', borderRadius: '10px', padding: '10px'}}>
Final steps to configure your URL:<br/>
DNS:<br/>
DNS:<br/>
DNS:<br/>
</div>
</div>
</Form>
);
}}
</Formik>
{setURL.error && (
<div className="col-12">
<p className="text-danger">{setURL.error.message}</p>
</div>
)}
{setURL.isSuccess && (
<div className="col-12">
<p className="text-success">{"Completed successfully"}</p>
</div>
)}
<div
style={{
backgroundColor: "#148399",
borderRadius: "10px",
padding: "10px",
color: "white",
fontWeight: "bolder",
fontSize: "14px",
}}
>
To link your domain to your website, update your DNS record to
point to our hosting provider.
<br />
<hr />
Enter the following DNS servers in your domain settings
<br />
{process.env.REACT_APP_DNS1}
<br />
{process.env.REACT_APP_DNS2}
<hr />
<Link
target="_blank"
to={process.env.REACT_APP_DNS_LINK}
style={{ color: "#f6f5f6" }}
>
Click here for detailed instructions.
</Link>
<hr />
After updating your DNS settings, click Start Verification.
You will receive a status notification within 24 hours.
</div>
</div>
</Form>
);
}}
</Formik>
</>
}
);
};
export default URLConfiguration
export default URLConfiguration;
+1 -1
View File
@@ -1,6 +1,6 @@
import React, { useMemo, useState } from "react";
import BreadcrumbComBS from "../breadcrumb/BreadcrumbComBS";
import getImage from "../../utils/getImage";
//import getImage from "../../utils/getImage";
import queryKeys from "../../services/queryKeys";
import { useQuery } from "@tanstack/react-query";
import { profileDetails } from "../../services/services";