From bdad718c92ee17586297e6b301a6baa9c8ef7915 Mon Sep 17 00:00:00 2001 From: JaiPandey425 Date: Tue, 29 Jul 2025 19:05:48 +0530 Subject: [PATCH] contact-edit and delete --- .../accounts/TransactionDataTable.tsx | 7 +++ src/components/contacts/Contacts.tsx | 61 +++++++++++++------ src/components/contacts/ContactsFormModal.tsx | 41 ++++++++++--- 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/src/components/accounts/TransactionDataTable.tsx b/src/components/accounts/TransactionDataTable.tsx index 908909c..9589d74 100644 --- a/src/components/accounts/TransactionDataTable.tsx +++ b/src/components/accounts/TransactionDataTable.tsx @@ -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('null'); const [selectedTransactions, setSelectedTransactions] = useState([]); const [activeAccountId, setActiveAccountId] = useState( @@ -39,6 +41,11 @@ const TransactionDataTable = () => { setCurrentEmailId(userDetails?.email) }, []); + + const handleTransactionClick = (transactionId) => { + navigate(`/accounts/${activeAccountId}/transactions/${transactionId}`) + } + return ( <> {transactions.length > 0 && ( diff --git a/src/components/contacts/Contacts.tsx b/src/components/contacts/Contacts.tsx index da45268..0942e70 100644 --- a/src/components/contacts/Contacts.tsx +++ b/src/components/contacts/Contacts.tsx @@ -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([]); 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,17 +43,27 @@ 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) { - - } + 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", @@ -72,16 +97,16 @@ const Contacts = () => { transition: Bounce, }); setShowModal(false) - fetchContacts(); + fetchContacts(); } // return res; } catch (err) { console.error("Error creating contact", err); toast.error("Failed to create contact", { - position: "top-center", - autoClose: 1500, - transition: Bounce, - }); + position: "top-center", + autoClose: 1500, + transition: Bounce, + }); throw err; } finally { setCreateAndInviteLoader(false); @@ -142,13 +167,13 @@ const Contacts = () => { {openMenuId === contact.id && (
diff --git a/src/components/contacts/ContactsFormModal.tsx b/src/components/contacts/ContactsFormModal.tsx index ea6416a..fcc25cc 100644 --- a/src/components/contacts/ContactsFormModal.tsx +++ b/src/components/contacts/ContactsFormModal.tsx @@ -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> + actionStatus: string, + editJsonData: any } -const ContactFormModal = ({ onSubmit, loading, setShowModal }: Props) => { +const ContactFormModal = ({ onSubmit, loading, setShowModal, actionStatus, editJsonData }: Props) => { const [formData, setFormData] = useState({ 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) => { 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) => {
- {formData.phones.map((phone, index) => ( + {formData?.phones?.map((phone, index) => (
{ SAVING... ) : ( - 'SAVE CONTACT' + `${actionStatus?.toUpperCase() || 'SAVE'} CONTACT` )} +