Compare commits

...

8 Commits

6 changed files with 155 additions and 55 deletions
@@ -170,7 +170,7 @@ const MarketPopUp = ({ details, onClose, situation, marketInt }) => {
<hr className="mb-1" /> <hr className="mb-1" />
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">
{content?.text} {content?.text}
<strong>{content?.bold}</strong> <strong>{thePrice}</strong>
</span> </span>
<hr className="mt-1" /> <hr className="mt-1" />
</> </>
+3 -1
View File
@@ -1,11 +1,13 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useLocation } from "react-router-dom";
import Layout from "../Partials/Layout"; import Layout from "../Partials/Layout";
import MyJobTable from "./MyJobTable"; import MyJobTable from "./MyJobTable";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import AddJobPage from "../../views/AddJobPage"; import AddJobPage from "../../views/AddJobPage";
export default function MyJobs(props) { export default function MyJobs(props) {
const [popUp, setPopUp] = useState(false); let { state } = useLocation();
const [popUp, setPopUp] = useState(state?.popup ? true : false);
const popUpHandler = () => { const popUpHandler = () => {
setPopUp((prev) => !prev); setPopUp((prev) => !prev);
}; };
@@ -4,8 +4,6 @@ import Layout from "../Partials/Layout";
import CommonHead from "../UserHeader/CommonHead"; import CommonHead from "../UserHeader/CommonHead";
import usersService from "../../services/UsersService"; import usersService from "../../services/UsersService";
import { handlePagingFunc } from "../Pagination/HandlePagination";
import PaginatedList from "../Pagination/PaginatedList";
import LoadingSpinner from "../Spinners/LoadingSpinner"; import LoadingSpinner from "../Spinners/LoadingSpinner";
import OthersInterestedTable from "./OthersInterestedTable"; import OthersInterestedTable from "./OthersInterestedTable";
@@ -15,25 +13,64 @@ export default function ManageInterestOffer(props) {
let [redirectTime, setRedirectTime] = useState(5) let [redirectTime, setRedirectTime] = useState(5)
let [messageToSend, setMessageToSend] = useState('')
let [tab, setTab] = useState("info"); //message STATE FOR SWITCHING BETWEEN TABS let [tab, setTab] = useState("info"); //message STATE FOR SWITCHING BETWEEN TABS
let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: '', processType: ''}) let [requestStatus, setRequestStatus] = useState({loading: false, status: false, message: '', processType: ''})
const messageList = {data: [1,2,3,4,5,6]} // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL let [messageListReload, setMessageListReload] = useState(false) // STATE TO DETERMINE WHEN MESSAGE LIST WILL RELOAD
const [currentPage, setCurrentPage] = useState(0);
const indexOfFirstItem = Number(currentPage);
const indexOfLastItem = Number(indexOfFirstItem) + Number(process.env.REACT_APP_ITEM_PER_PAGE);
const currentMessageList = messageList?.data?.slice(indexOfFirstItem, indexOfLastItem);
const handlePagination = (e) => { const [messageList, setMessageList] = useState({loading: true, data: []}) // TO BE REMOVED AND REPLACE WITH REAL MESSAGE FROM API CALL
handlePagingFunc(e, setCurrentPage);
};
const [selectTab, setValue] = useState("today"); const [selectTab, setValue] = useState("today");
const filterHandler = (value) => { const filterHandler = (value) => {
setValue(value); setValue(value);
}; };
//FUNCTION TO HANDLE ON CHANGE MESSAGE IN TEXTAREA
const onMessageChange = ({target:{value}}) => {
if(messageToSend.length > 149){
setRequestStatus({loading: false, status: false, message: 'max of 150 characters', processType: 'sendmessage'})
}else{
setRequestStatus({loading: false, status: false, message: '', processType: 'sendmessage'})
}
setMessageToSend(value)
}
//FUNCTION TO SEND MESSAGE TO CLIENT
const sendMessage = () => {
let reqData = { // API PAYLOADS
msg_type: 'MRKTINT',
yourmessage: messageToSend,
offer_uid: props.offerDetails.offer_uid,
interest_uid: props.offerDetails.interest_uid
}
setRequestStatus(prev => ({...prev, loading: true, processType: 'sendmessage'}))
if(!messageToSend){
setRequestStatus({loading: false, status: false, message: 'Please enter message to send', processType: 'sendmessage'})
return
}
if(messageToSend.length > 149){
return
}
apiCall.offerInterestMsg(reqData).then(res=>{
if(res.status != 200 || res.data.internal_return < 0){
setRequestStatus({loading: false, status: false, message: 'message not sent, try again', processType: 'sendmessage'})
return
}
setRequestStatus({loading: false, status: true, message: 'message sent', processType: 'sendmessage'})
setMessageToSend('') // sets message to empty strings
setMessageListReload(prev => !prev) //A FUNCTION TO MAKE MESSAGE LIST RELOAD
}).catch(error => {
setRequestStatus({loading: false, status: false, message: 'Opps, an error occured', processType: 'sendmessage'})
}).finally(()=>{
setTimeout(() => {
setRequestStatus({loading: false, status: false, message: '', processType: ''})
}, 5000);
})
}
//FUNCTION TO ACCEPT/REJECT OFFER INTEREST //FUNCTION TO ACCEPT/REJECT OFFER INTEREST
const interestOfferProcess = ({target:{name}}) => { const interestOfferProcess = ({target:{name}}) => {
setRequestStatus(prev => ({...prev, loading: true, processType: name})) setRequestStatus(prev => ({...prev, loading: true, processType: name}))
@@ -65,9 +102,20 @@ export default function ManageInterestOffer(props) {
}) })
} }
useEffect(()=>{ useEffect(()=>{ //API to get Offer Interest message list
// run API to get message to replace message array above, add reload variable as dependence array let reqData = { // API PAYLOADS
},[]) msg_type: 'MRKTINT',
offer_uid: props.offerDetails.offer_uid,
interest_uid: props.offerDetails.interest_uid
}
setMessageList(prev => ({...prev, loading: true}))
apiCall.offerInterestListMsg(reqData).then(res=>{
setMessageList({loading: false, data:res?.data?.result_list})
}).catch(err => {
setMessageList(prev => ({...prev, loading: false}))
console.log('Failed', err)
})
},[messageListReload])
return ( return (
<Layout> <Layout>
<CommonHead <CommonHead
@@ -180,45 +228,67 @@ export default function ManageInterestOffer(props) {
</div> </div>
: :
<div className="message-details w-full border-t"> <div className="message-details w-full border-t">
<div className="my-0 w-full flex items-center gap-5"> <p className="my-1 text-base text-dark-gray dark:text-white tracking-wide">To: <span className="font-bold">{props.offerDetails?.client_name}</span></p>
<div className="w-3/4"> <div className="w-full flex items-center gap-5">
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">Message to dummy name</p> <div className="w-full">
<textarea rows={2} autoFocus={true} className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none" /> <textarea
value={messageToSend}
onChange={onMessageChange}
rows={2} autoFocus={true}
className="p-2 text-base font-bold text-dark-gray dark:text-white dark:bg-dark-gray border tracking-wide w-full resize-none rounded-md outline-none"
/>
</div> </div>
<div className="w-1/4 flex flex-col justify-center items-center"> <div className="flex justify-end items-center">
<button {requestStatus.loading && requestStatus.processType == 'sendmessage' ?
type="button" <LoadingSpinner color='sky-blue' size='10' />
className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white" :
> <button
<span className="text-white">Send</span> type="button"
</button> onClick={sendMessage}
disabled={requestStatus.loading}
// className="px-2 py-1 h-11 flex justify-center items-center btn-gradient text-base rounded-full text-white"
className="w-[100px] h-[50px] bg-sky-blue text-center text-lg font-semibold text-white rounded-md shadow-md flex justify-center items-center"
>
Send
</button>
}
</div> </div>
</div> </div>
{/* message list */}
<div className="min-h-[100px] max-h-[200px] overflow-y-auto">
{currentMessageList.map((item, index)=>(
<div key={index} className="my-2 w-full flex items-center gap-1">
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">2023-04-06-from { }<span className="font-normal">Dummy name</span></p>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">I am testing message</p>
</div>
))}
</div>
{/* PAGINATION BUTTON */} {/* ERROR DISPLAY FOR MESSAGE SENDING */}
<PaginatedList <div className="w-full">
onClick={handlePagination} {/* error or success display */}
prev={currentPage == 0 ? true : false} {requestStatus.message != "" && requestStatus.processType == 'sendmessage' &&
next={ (!requestStatus.status ? (
currentPage + Number(process.env.REACT_APP_ITEM_PER_PAGE) >= <div
messageList?.data?.length className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
? true >
: false {requestStatus.message}
} </div>
data={messageList?.data} ) : (
start={indexOfFirstItem} requestStatus.status && (
stop={indexOfLastItem} <div
/> className={`relative p-4 my-4 text-green-700 bg-slate-200 border-slate-800 mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
{/* END OF PAGINATION BUTTON */} >
{requestStatus.message}
</div>
)
))}
</div>
{/* END OF ERROR DISPLAY FOR MESSAGE SENDING */}
{/* message list */}
<div className="my-1 min-h-[100px] max-h-[200px] border-t overflow-y-scroll">
{ messageList.loading ?
<LoadingSpinner color='sky-blue' size='16' />
: messageList?.data?.map((item, index)=>(
<div key={index} className="my-2 w-full flex items-center gap-1">
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.added.split(' ')[0]}-from { }<span className="font-normal">{item.sender || 'Dummy name'}</span></p>
<p className="text-base font-bold text-dark-gray dark:text-white tracking-wide">{item.msg}</p>
</div>
))
}
</div>
</div> </div>
} }
</div> </div>
@@ -263,7 +333,7 @@ export default function ManageInterestOffer(props) {
{/* ERROR DISPLAY */} {/* ERROR DISPLAY */}
<div className="w-full"> <div className="w-full">
{/* error or success display */} {/* error or success display */}
{requestStatus.message != "" && requestStatus.processType != 'sendmeassge' && {requestStatus.message != "" && requestStatus.processType != 'sendmessage' &&
(!requestStatus.status ? ( (!requestStatus.status ? (
<div <div
className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`} className={`relative p-4 my-4 text-[#912741] bg-[#fcd9e2] border-[#fbc6d3] mb-4 rounded-[0.475rem] text-md font-light leading-[19.5px] text-[13px]`}
+4 -2
View File
@@ -225,9 +225,10 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
<ul className="flex flex-col space-y-6"> <ul className="flex flex-col space-y-6">
<ListItem <ListItem
title="Add Job" title="Add Job"
route="/add-job" route="/myjobs"
iconName="people-two" iconName="people-two"
sidebar={sidebar} sidebar={sidebar}
state={"Add Job"}
/> />
</ul> </ul>
</div> </div>
@@ -301,11 +302,12 @@ export default function MobileSidebar({ sidebar, action, logoutModalHandler, myJ
); );
} }
const ListItem = ({ sidebar, route, title, bubble }) => { const ListItem = ({ sidebar, route, title, bubble, state }) => {
return ( return (
<li className="item group"> <li className="item group">
<NavLink <NavLink
to={route} to={route}
state={state && {popup: true}}
className={`nav-item flex items-center ${ className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""), ((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center") sidebar ? "justify-start space-x-3.5" : "justify-center")
+4 -2
View File
@@ -249,9 +249,10 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
<ul className="flex flex-col space-y-6"> <ul className="flex flex-col space-y-6">
<ListItem <ListItem
title="Add Job" title="Add Job"
route="/add-job" route="/myjobs"
iconName="people-two" iconName="people-two"
sidebar={sidebar} sidebar={sidebar}
state={"Add Job"}
/> />
</ul> </ul>
</div> </div>
@@ -325,11 +326,12 @@ export default function Sidebar({ sidebar, action, logoutModalHandler, myJobList
); );
} }
const ListItem = ({ sidebar, route, title, bubble, iconName }) => { const ListItem = ({ sidebar, route, title, bubble, iconName, state }) => {
return ( return (
<li className={`item group`}> <li className={`item group`}>
<NavLink <NavLink
to={route} to={route}
state={state && {popup: true}}
className={`nav-item flex items-center ${ className={`nav-item flex items-center ${
((navData) => (navData.isActive ? "active" : ""), ((navData) => (navData.isActive ? "active" : ""),
sidebar ? "justify-start space-x-3.5" : "justify-center") sidebar ? "justify-start space-x-3.5" : "justify-center")
+24
View File
@@ -729,6 +729,30 @@ class usersService {
}; };
return this.postAuxEnd("/paylistcard", postData); return this.postAuxEnd("/paylistcard", postData);
} }
// END POINT TO SEND OFFER INTEREST MESSAGE
offerInterestMsg(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13037,
...reqData
};
return this.postAuxEnd("/offerinterestmsg", postData);
}
// END POINT TO GET OFFER INTEREST MESSAGE
offerInterestListMsg(reqData) {
var postData = {
uid: localStorage.getItem("uid"),
member_id: localStorage.getItem("member_id"),
sessionid: localStorage.getItem("session_token"),
action: 13037,
...reqData
};
return this.postAuxEnd("/offerinterestlistmsg", postData);
}
/* /*
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(username)
- 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password) - 20:27:30.118 FLOG_MAX [757411]: REQ_STRING(password)