Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 734acd9dd5 | |||
| 3f9534b968 | |||
| 13d69efbaf | |||
| 4985256c3a |
@@ -30,38 +30,34 @@ export default function GroupMemberTable({selectedList}) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}>
|
<div className={`w-full p-8 bg-white dark:bg-dark-gray overflow-hidden rounded-2xl section-shadow`}>
|
||||||
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[300px]">
|
<div className="relative w-full overflow-x-auto sm:rounded-lg flex flex-col justify-between min-h-[400px]">
|
||||||
<table className="table-auto min-w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
|
||||||
<tbody>
|
<tbody>
|
||||||
<>
|
<>
|
||||||
<tr className='font-bold text-sm text-dark-gray dark:text-white whitespace-nowrap'>
|
|
||||||
<th>First Name</th>
|
|
||||||
<th>Last Name</th>
|
|
||||||
<th>Email</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className='p-[1px] bg-slate-400 dark:bg-white rounded-full' colSpan="4"></td>
|
|
||||||
</tr>
|
|
||||||
{selectedList && selectedList?.length > 0 ? (
|
{selectedList && selectedList?.length > 0 ? (
|
||||||
// currentSelectedList?.length ? (
|
|
||||||
currentSelectedList.map((value, index) => (
|
currentSelectedList.map((value, index) => (
|
||||||
<tr key={value.uid} className="font-medium text-sm text-dark-gray dark:text-white whitespace-nowrap">
|
<tr key={value.uid} className="bg-white dark:bg-dark-white border-b dark:border-[#5356fb29] hover:bg-gray-50">
|
||||||
<td className="p-1">{value?.firstname}</td>
|
{/* <td className="p-1">{value?.firstname}</td>
|
||||||
<td className="p-1">{value?.lastname}</td>
|
<td className="p-1">{value?.lastname}</td>
|
||||||
<td className="p-1">{value?.email}</td>
|
<td className="p-1">{value?.email}</td>
|
||||||
<td className="p-1 text-right">
|
<td className="p-1 text-right">
|
||||||
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
||||||
|
</td> */}
|
||||||
|
<td className='py-2'>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<h1 className="font-bold text-xl text-dark-gray dark:text-white">
|
||||||
|
{value.firstname && value.firstname} {value.lastname && value.lastname}
|
||||||
|
</h1>
|
||||||
|
<span className="text-sm text-thin-light-gray">
|
||||||
|
{value.email && value.email}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className='py-2 text-right'>
|
||||||
|
<button onClick={()=>{handleDeleteMember(value)}} className='rounded-lg text-sm bg-red-500 hover:bg-red-400 text-white font-bold py-1 px-2.5'>X</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
// ) : (
|
|
||||||
// <tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
|
||||||
// <td className="p-2">
|
|
||||||
// No Members Found
|
|
||||||
// </td>
|
|
||||||
// </tr>
|
|
||||||
// )
|
|
||||||
) : (
|
) : (
|
||||||
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
<tr className="font-bold text-xl text-dark-gray dark:text-white whitespace-nowrap">
|
||||||
<td className="p-2">No Members Found</td>
|
<td className="p-2">No Members Found</td>
|
||||||
|
|||||||
@@ -20,11 +20,42 @@ export default function MemberList({groupList, selectedGroup, setUpdateList}) {
|
|||||||
|
|
||||||
const handleFieldsChange = ({target:{name, value}}) => {
|
const handleFieldsChange = ({target:{name, value}}) => {
|
||||||
setFields(prev => ({...prev, [name]:value}))
|
setFields(prev => ({...prev, [name]:value}))
|
||||||
let error = requestState?.errors?.indexOf(name) //// checks if the input field was in error array and removes it when the input changes
|
// let error = requestState?.errors?.indexOf(name) //// checks if the input field was in error array and removes it when the input changes
|
||||||
if(error >= 0){
|
// if(error >= 0){
|
||||||
let oldErrorArr = requestState.errors
|
// let oldErrorArr = requestState.errors
|
||||||
let newErrorArr = oldErrorArr.splice(error, 1)
|
// let newErrorArr = oldErrorArr.splice(error, 1)
|
||||||
setRequestState(prev => ({...prev, errors:oldErrorArr}))
|
// setRequestState(prev => ({...prev, errors:oldErrorArr}))
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(value == ''){
|
||||||
|
setRequestState({
|
||||||
|
loading: false,
|
||||||
|
status: false,
|
||||||
|
message: '',
|
||||||
|
data: [],
|
||||||
|
errors: [name]
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
let error = requestState?.errors?.indexOf(name) //// checks if the input field was in error array and removes it when the input changes
|
||||||
|
if(error >= 0){
|
||||||
|
let oldErrorArr = requestState.errors
|
||||||
|
let newErrorArr = oldErrorArr.splice(error, 1)
|
||||||
|
setRequestState(prev => ({...prev, errors:oldErrorArr}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(name == 'email'){
|
||||||
|
//checks if email is a valid email address
|
||||||
|
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||||
|
if (!EmailValidator(value)) {
|
||||||
|
setRequestState({
|
||||||
|
loading: false,
|
||||||
|
status: false,
|
||||||
|
message: '',
|
||||||
|
data: [],
|
||||||
|
errors: ['email']
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,26 +64,26 @@ export default function MemberList({groupList, selectedGroup, setUpdateList}) {
|
|||||||
status: false,
|
status: false,
|
||||||
message: '',
|
message: '',
|
||||||
data: [],
|
data: [],
|
||||||
errors: []
|
errors: ['email', 'firstname', 'lastname']
|
||||||
})
|
})
|
||||||
|
|
||||||
const addMember = () => {
|
const addMember = () => {
|
||||||
let errors = Object.keys(fields).filter((item) => { // CHECKS FOR EMPTY STRINGS
|
// let errors = Object.keys(fields).filter((item) => { // CHECKS FOR EMPTY STRINGS
|
||||||
if(typeof item == 'string' && fields[item] === ''){
|
// if(typeof item == 'string' && fields[item] === ''){
|
||||||
return item
|
// return item
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
if(errors.length){
|
// if(errors.length){
|
||||||
setRequestState({
|
// setRequestState({
|
||||||
loading: false,
|
// loading: false,
|
||||||
status: false,
|
// status: false,
|
||||||
message: '',
|
// message: '',
|
||||||
data: [],
|
// data: [],
|
||||||
errors: [...errors]
|
// errors: [...errors]
|
||||||
})
|
// })
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
|
||||||
//checks if email is a valid email address
|
//checks if email is a valid email address
|
||||||
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
let regEx = /^[^0-9][a-zA-Z0-9._%+-]+@[a-zA-Z]+(\.[a-zA-Z]+)+$/;
|
||||||
@@ -155,54 +186,61 @@ export default function MemberList({groupList, selectedGroup, setUpdateList}) {
|
|||||||
<>
|
<>
|
||||||
<h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>{selectedGroup?.name}</h1>
|
<h1 className='mb-5 text-lg lg:text-2xl tracking-wide font-bold text-slate-900 dark:text-slate-100'>{selectedGroup?.name}</h1>
|
||||||
<div className='w-full flex flex-col-reverse lg:flex-col'>
|
<div className='w-full flex flex-col-reverse lg:flex-col'>
|
||||||
<div className='py-3 w-full sm:w-[500px] xl:w-full xxl:w-[500px]'>
|
<div className='py-3 w-full'>
|
||||||
<div className='relative grid grid-cols-1 sm:grid-cols-2 gap-2'>
|
<div className='relative grid grid-cols-1 sm:grid-cols-2 gap-2 place-content-center'>
|
||||||
<div className='h-10 relative'>
|
<div className="input-item">
|
||||||
<input
|
<InputCom
|
||||||
id='firstname'
|
labelClass="tracking-wider"
|
||||||
name='firstname'
|
fieldClass="sm:px-6 px-2"
|
||||||
// className={`peer px-5 w-full h-full rounded-full outline-none placeholder:text-transparent transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80`}
|
value={fields.firstname}
|
||||||
className={`peer px-5 w-full h-full rounded-full outline-none border placeholder:text-slate-600 transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80 ${requestState.errors.includes('firstname') ? 'border-red-500' : 'border-transparent'}`}
|
inputHandler={handleFieldsChange}
|
||||||
type='text'
|
placeholder="First Name"
|
||||||
placeholder='First Name'
|
// label="Firstname"
|
||||||
value={fields.firstname}
|
name="firstname"
|
||||||
onChange={handleFieldsChange}
|
type="text"
|
||||||
|
// iconName="message"
|
||||||
/>
|
/>
|
||||||
{/* <label htmlFor='firstname' className={`text-sm text-black dark:text-slate-500 absolute left-5 -top-4 translate-y-0 peer-focus:-top-3 peer-focus:translate-y-0 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 transition-all duration-500 ${requestState.errors.includes('firstname') ? 'text-red-500' : ''}`}>First Name</label> */}
|
|
||||||
</div>
|
</div>
|
||||||
<div className='h-10 relative'>
|
<div className="input-item">
|
||||||
<input
|
<InputCom
|
||||||
id='lastname'
|
labelClass="tracking-wider"
|
||||||
name='lastname'
|
fieldClass="sm:px-6 px-2"
|
||||||
// className={`peer px-5 w-full h-full rounded-full outline-none placeholder:text-transparent transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80`}
|
value={fields.lastname}
|
||||||
className={`peer px-5 w-full h-full rounded-full outline-none border placeholder:text-slate-600 transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80 ${requestState.errors.includes('lastname') ? 'border-red-500' : 'border-transparent'}`}
|
inputHandler={handleFieldsChange}
|
||||||
type='text'
|
placeholder="Last Name"
|
||||||
placeholder='Last Name'
|
// label="Lastname"
|
||||||
value={fields.lastname}
|
name="lastname"
|
||||||
onChange={handleFieldsChange}
|
type="text"
|
||||||
|
// iconName="message"
|
||||||
/>
|
/>
|
||||||
{/* <label htmlFor='lastname' className={`text-sm text-black dark:text-slate-500 absolute left-5 -top-4 translate-y-0 peer-focus:-top-3 peer-focus:translate-y-0 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 transition-all duration-500 ${requestState.errors.includes('lastname') ? 'text-red-500' : ''}`}>LastName</label> */}
|
|
||||||
</div>
|
</div>
|
||||||
<div className='h-10 relative'>
|
<div className="input-item w-full sm:w-[150%]">
|
||||||
<input
|
<InputCom
|
||||||
id='email'
|
labelClass="tracking-wider"
|
||||||
name='email'
|
fieldClass="sm:px-6 px-2"
|
||||||
// className={`peer px-5 w-full h-full rounded-full outline-none placeholder:text-transparent transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80`}
|
value={fields.email}
|
||||||
className={`peer px-5 w-full h-full rounded-full outline-none border placeholder:text-slate-600 transition-all duration-500 text-black dark:text-black bg-gradient-to-br from-slate-50/80 via-slate-200/80 to-slate-100/80 focus:from-slate-100/80 focus:to-slate-50/80 ${requestState.errors.includes('email') ? 'border-red-500' : 'border-transparent'}`}
|
inputHandler={handleFieldsChange}
|
||||||
type='email'
|
placeholder="Email"
|
||||||
placeholder='Email'
|
// label="Email"
|
||||||
value={fields.email}
|
name="email"
|
||||||
onChange={handleFieldsChange}
|
type="email"
|
||||||
|
// iconName="message"
|
||||||
/>
|
/>
|
||||||
{/* <label htmlFor='email' className={`text-sm text-black dark:text-slate-500 absolute left-5 -top-4 translate-y-0 peer-focus:-top-3 peer-focus:translate-y-0 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 transition-all duration-500 ${requestState.errors.includes('email') ? 'text-red-500' : ''}`}>Email</label> */}
|
|
||||||
</div>
|
</div>
|
||||||
<div className='flex justify-end items-center'>
|
<div className='flex justify-end items-end'>
|
||||||
{requestState.loading ?
|
{requestState.loading ?
|
||||||
<LoadingSpinner size='8' color='sky-blue' />
|
<LoadingSpinner size='8' color='sky-blue' />
|
||||||
:
|
:
|
||||||
<button onClick={addMember} disabled={requestState.loading || requestState.status} className='py-2 px-4 flex justify-center items-center bg-sky-blue hover:bg-sky-600 text-base rounded-full text-white font-bold'>Add Member</button>
|
<button
|
||||||
|
onClick={addMember}
|
||||||
|
disabled={requestState.loading || requestState.status || requestState.errors.length}
|
||||||
|
className={`py-2 px-4 h-[42px] flex justify-center items-center text-base rounded-full text-white font-bold transition-all duration-500 ${requestState.loading || requestState.status || requestState.errors.length ? 'bg-sky-blue/50' : 'bg-sky-blue hover:bg-sky-600'} `}
|
||||||
|
>
|
||||||
|
Add Member
|
||||||
|
</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!requestState.loading && requestState.message &&
|
{!requestState.loading && requestState.message &&
|
||||||
<p className={`text-lg absolute -bottom-7 left-0 ${requestState.status ? 'text-green-500' : 'text-red-500'}`}>{requestState.message}</p>
|
<p className={`text-lg absolute -bottom-7 left-0 ${requestState.status ? 'text-green-500' : 'text-red-500'}`}>{requestState.message}</p>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user