Compare commits
2 Commits
e14e59e759
...
ae53054426
| Author | SHA1 | Date |
|---|---|---|
|
|
ae53054426 | |
|
|
bdad718c92 |
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'
|
|||
import { PiDotsThreeOutlineVerticalFill } from 'react-icons/pi';
|
||||
import api from '../../config/api';
|
||||
import { Transaction } from '../transactions/Transactions';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ const formatDate = (timestamp: number) => {
|
|||
};
|
||||
|
||||
const TransactionDataTable = () => {
|
||||
const navigate = useNavigate()
|
||||
const [currentEmailId, setCurrentEmailId] = useState<string | null>('null');
|
||||
const [selectedTransactions, setSelectedTransactions] = useState<number[]>([]);
|
||||
const [activeAccountId, setActiveAccountId] = useState<string | null>(
|
||||
|
|
@ -39,6 +41,11 @@ const TransactionDataTable = () => {
|
|||
setCurrentEmailId(userDetails?.email)
|
||||
}, []);
|
||||
|
||||
|
||||
const handleTransactionClick = (transactionId) => {
|
||||
navigate(`/accounts/${activeAccountId}/transactions/${transactionId}`)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{transactions.length > 0 && (
|
||||
|
|
|
|||
|
|
@ -1,18 +1,28 @@
|
|||
import { useEffect, useState, useRef } from 'react';
|
||||
import { FaEllipsisV } from 'react-icons/fa';
|
||||
import api from '../../config/api';
|
||||
import ContactFormModal from './ContactsFormModal';
|
||||
import ContactFormModal, { ContactData } from './ContactsFormModal';
|
||||
import { Bounce, toast } from 'react-toastify';
|
||||
import { IoMdAdd } from 'react-icons/io';
|
||||
|
||||
type ContactSchema = [{
|
||||
id: number,
|
||||
firstName: string
|
||||
lastName: string
|
||||
email: string
|
||||
}]
|
||||
|
||||
const Contacts = () => {
|
||||
const activeAccountId = JSON.parse(sessionStorage.getItem('activeAccountId') || 'null');
|
||||
const [contacts, setContacts] = useState([]);
|
||||
const [contacts, setContacts] = useState<ContactSchema>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [openMenuId, setOpenMenuId] = useState(null);
|
||||
const blurTimeoutRef = useRef(null);
|
||||
const [createAndInviteLoader, setCreateAndInviteLoader] = useState(false);
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const [editJsonData, setEditJsonData] = useState({})
|
||||
const [actionStatus, setActionStatus] = useState("")
|
||||
console.log("editJsonData", editJsonData)
|
||||
|
||||
const fetchContacts = async () => {
|
||||
try {
|
||||
|
|
@ -33,16 +43,26 @@ const Contacts = () => {
|
|||
|
||||
const handleEdit = (contactId) => {
|
||||
console.log('Edit contact:', contactId);
|
||||
let jsonEditData = contacts.find((prev) => prev.id === contactId)
|
||||
setEditJsonData(jsonEditData)
|
||||
setActionStatus("Edit")
|
||||
setShowModal((prev) => !prev)
|
||||
setOpenMenuId(null);
|
||||
};
|
||||
|
||||
const handleDelete = async(contactId) => {
|
||||
const handleDelete = async (contactId) => {
|
||||
console.log('Delete contact:', contactId);
|
||||
setOpenMenuId(null);
|
||||
try {
|
||||
let res = await api.delete(`/api/accounts/{accountId}/contacts/{contactId}`)
|
||||
if (res?.data) {
|
||||
|
||||
try {
|
||||
let res = await api.delete(`/api/accounts/${activeAccountId}/contacts/${contactId}`)
|
||||
if (res?.data) {
|
||||
toast.error("Contact delete successfully!", {
|
||||
position: "top-center",
|
||||
autoClose: 1500,
|
||||
transition: Bounce,
|
||||
});
|
||||
fetchContacts()
|
||||
setOpenMenuId(null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
|
|
@ -61,10 +81,15 @@ const Contacts = () => {
|
|||
}, 100);
|
||||
};
|
||||
|
||||
const handleContactSubmit = async (data: ContactData) => {
|
||||
const handleContactSubmit = async (data: ContactData, type: "") => {
|
||||
try {
|
||||
let res ;
|
||||
setCreateAndInviteLoader(true);
|
||||
const res = await api.post(`/api/accounts/${activeAccountId}/contacts`, [data]);
|
||||
if (type === 'Edit') {
|
||||
res = await api.put(`/api/accounts/${activeAccountId}/contacts`, [data])
|
||||
}else{
|
||||
res = await api.post(`/api/accounts/${activeAccountId}/contacts`, [data]);
|
||||
}
|
||||
if (res.status === 200) {
|
||||
toast.success('Contact created successfully!', {
|
||||
position: "top-center",
|
||||
|
|
@ -142,13 +167,13 @@ const Contacts = () => {
|
|||
{openMenuId === contact.id && (
|
||||
<div className="absolute top-full right-0 mt-1 bg-white border border-gray-200 rounded shadow-lg z-20 min-w-[100px]">
|
||||
<button
|
||||
onClick={() => handleEdit(contact.id)}
|
||||
onMouseDown={() => handleEdit(contact.id)}
|
||||
className="block w-full text-left px-4 py-2 text-sm hover:bg-gray-100 text-blue-600"
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={() => handleDelete(contact.id)}
|
||||
onMouseDown={() => handleDelete(contact.id)}
|
||||
className="block w-full text-left px-4 py-2 text-sm hover:bg-gray-100 text-red-600"
|
||||
>
|
||||
Delete
|
||||
|
|
@ -164,7 +189,7 @@ const Contacts = () => {
|
|||
</table>
|
||||
{showModal &&
|
||||
<ContactFormModal onSubmit={handleContactSubmit}
|
||||
loading={createAndInviteLoader} setShowModal={setShowModal}/>
|
||||
loading={createAndInviteLoader} setShowModal={setShowModal} actionStatus={actionStatus} editJsonData={editJsonData} />
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// ContactForm.tsx
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FaSpinner } from 'react-icons/fa';
|
||||
|
||||
export interface ContactData {
|
||||
|
|
@ -17,9 +17,11 @@ interface Props {
|
|||
onSubmit: (data: ContactData) => void;
|
||||
loading: boolean;
|
||||
setShowModal: () => React.Dispatch<React.SetStateAction<boolean>>
|
||||
actionStatus: string,
|
||||
editJsonData: any
|
||||
}
|
||||
|
||||
const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
||||
const ContactFormModal = ({ onSubmit, loading, setShowModal, actionStatus, editJsonData }: Props) => {
|
||||
const [formData, setFormData] = useState<ContactData>({
|
||||
email: '',
|
||||
firstName: '',
|
||||
|
|
@ -32,6 +34,21 @@ const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
|||
|
||||
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
||||
|
||||
useEffect(() => {
|
||||
if (actionStatus === 'Edit' && editJsonData) {
|
||||
setFormData({
|
||||
email: editJsonData.email,
|
||||
firstName: editJsonData.firstName,
|
||||
lastName: editJsonData.lastName,
|
||||
title: editJsonData.title,
|
||||
company: editJsonData.company,
|
||||
website: editJsonData.website,
|
||||
phones: editJsonData.phones,
|
||||
})
|
||||
}
|
||||
}, [actionStatus, editJsonData])
|
||||
|
||||
|
||||
const handleChange = (field: keyof ContactData, value: string) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
if (errors[field]) {
|
||||
|
|
@ -115,13 +132,22 @@ const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
|||
|
||||
const handleSubmit = async () => {
|
||||
const validationErrors = validate();
|
||||
let type = 'Add'
|
||||
let payload = formData
|
||||
if (Object.keys(validationErrors).length > 0) {
|
||||
setErrors(validationErrors);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await onSubmit(formData);
|
||||
if (actionStatus === 'Edit') {
|
||||
type = 'Edit'
|
||||
payload = {
|
||||
...formData,
|
||||
contactId: editJsonData.id
|
||||
}
|
||||
}
|
||||
await onSubmit(payload, type);
|
||||
|
||||
|
||||
setFormData({
|
||||
email: '',
|
||||
|
|
@ -158,7 +184,7 @@ const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
|||
<label className="text-sm font-medium text-[var(--greyTextCol)] mb-1">{label}</label>
|
||||
<input
|
||||
type={field === 'email' ? 'email' : 'text'}
|
||||
value={formData[field as keyof ContactData] as string}
|
||||
value={(formData[field as keyof ContactData] as string) || ''}
|
||||
onChange={(e) => handleChange(field as keyof ContactData, e.target.value)}
|
||||
required={true}
|
||||
className="px-3 py-1.5 border border-gray-400 rounded-md focus:outline-none focus:ring-1 focus:ring-[var(--primary)] text-sm"
|
||||
|
|
@ -172,7 +198,7 @@ const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
|||
<div>
|
||||
<label className="text-sm font-medium text-[var(--greyTextCol)] mb-1">Phone Numbers</label>
|
||||
<div className="space-y-2">
|
||||
{formData.phones.map((phone, index) => (
|
||||
{formData?.phones?.map((phone, index) => (
|
||||
<div key={index} className="flex flex-col gap-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<input
|
||||
|
|
@ -229,8 +255,9 @@ const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => {
|
|||
SAVING...
|
||||
</>
|
||||
) : (
|
||||
'SAVE CONTACT'
|
||||
`${actionStatus?.toUpperCase() || 'SAVE'} CONTACT`
|
||||
)}
|
||||
|
||||
</button>
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue