Skip to content

Commit

Permalink
UI Enhancements and Table structure changes
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielEmmanuel1 committed Nov 20, 2024
1 parent 1a5f7ee commit 44993e0
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 180 deletions.
107 changes: 107 additions & 0 deletions src/components/pages/dashboard/admins/ActivityTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React, { useState } from "react";
import { Activity } from "../channels/ActivityTableData";

interface ActivityTableProps {
data: Activity[];
}

const ActivityTable: React.FC<ActivityTableProps> = ({ data }) => {
const [isModalOpen, setModalOpen] = useState(false);

const toggleModal = () => {
setModalOpen(!isModalOpen);
};

// Split data into two parts
const visibleData = data.slice(0, 5); // First 5 items
const modalData = data.slice(); // Remaining items

return (
<div>
{/* Table */}
<div className="overflow-x-auto border border-gray-200">
<table className="w-full border-collapse bg-white text-left text-sm">
<thead className="bg-[#03cf7a7b] border-2 border-[#03CF79] text-black">
<tr>
<th className="px-6 py-3 border-b font-medium">Channel Name</th>
<th className="px-6 py-3 border-b font-medium">Reach</th>
<th className="px-6 py-3 border-b font-medium">Timestamp</th>
</tr>
</thead>
<tbody>
{visibleData.map((activity, index) => (
<tr
key={index}
className="hover:bg-gray-50 border-b text-gray-700"
>
<td className="px-6 py-3">{activity.channelName}</td>
<td className="px-6 py-3 underline tracking-wider">
{activity.reach}
</td>
<td className="px-6 py-3">{activity.timestamp}</td>
</tr>
))}
</tbody>
</table>
</div>

{/* View More Button */}
{modalData.length > 0 && (
<div
className="flex justify-end"
onClick={toggleModal}
>
<p className="text-[#03CF79] py-3 w-fit text-right cursor-pointer hover:text-[#03cf7a9d]">View More</p>
</div>
)}

{/* Modal */}
{isModalOpen && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
<div className="bg-white w-11/12 md:w-3/4 lg:w-1/2 rounded-lg shadow-lg p-6 relative px-8">
{/* Close Button */}
<button
className="absolute top-3 right-3 text-gray-500 hover:text-black"
onClick={toggleModal}
>
</button>

{/* Modal Table */}
<div className="overflow-x-auto border border-gray-200">
<table className="w-full border-collapse bg-white text-left text-sm">
<thead className="bg-[#03cf7a7b] border-2 border-[#03CF79] text-black">
<tr>
<th className="px-6 py-3 border-b font-medium">
Channel Name
</th>
<th className="px-6 py-3 border-b font-medium">Reach</th>
<th className="px-6 py-3 border-b font-medium">
Timestamp
</th>
</tr>
</thead>
<tbody>
{modalData.map((activity, index) => (
<tr
key={index}
className="hover:bg-gray-50 border-b text-gray-700"
>
<td className="px-6 py-3">{activity.channelName}</td>
<td className="px-6 py-3 underline tracking-wider">
{activity.reach}
</td>
<td className="px-6 py-3">{activity.timestamp}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
)}
</div>
);
};

export default ActivityTable;
198 changes: 30 additions & 168 deletions src/components/pages/dashboard/admins/ManageAdmins.tsx
Original file line number Diff line number Diff line change
@@ -1,84 +1,27 @@
import React, { useState, useContext } from "react";
import { AuthContext } from "@/context/AuthContext";
import { activityData } from "../channels/ActivityTableData";
import { pendingChannelsData } from "../channels/pendingChannelData";
import AdminTable from "@/components/tables/AdminTable";
import DeleteModal from "@/components/modals/actionPrompts/DeleteModal";
import ViewMoreModal from "../channels/ViewMoreModal";
import PendingChannels from "@/components/pages/dashboard/admins/PendingChannelData";
import ActivityTable from "@/components/pages/dashboard/admins/ActivityTable";
import { activityData } from "../channels/ActivityTableData";
import axios from "axios";
import apiUrl from "@/data/axios";

const ManageAdmins: React.FC = () => {
const { userData } = useContext(AuthContext);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [activeModalData, setActiveModalData] = useState<string>("");
const [isViewMoreActivityOpen, setIsViewMoreActivityOpen] = useState(false);
const [isViewMorePendingOpen, setIsViewMorePendingOpen] = useState(false);
const [visibleActivityItems, setVisibleActivityItems] = useState(5);
const [visiblePendingItems, setVisiblePendingItems] = useState(5);


const API_URL = apiUrl("production");

const openDeleteModal = (channelName: string) => {
setActiveModalData(channelName);
setIsDeleteModalOpen(true);
};

const closeDeleteModal = () => setIsDeleteModalOpen(false);

const activityTableHeadings: string[] = [
"Channel Name",
"Reach",
"Timestamp"
];

const pendingTableHeadings: string[] = [
const pendingTableHeadings = [
"Email Address",
"Channel Name",
"Category",
"Actions"
"Actions",
];

const displayedActivities = activityData.slice(0, 5);
const displayedPendingChannels = pendingChannelsData.slice(0, 5);

const modalActivities = activityData.slice(0, visibleActivityItems);
const modalPendingChannels = pendingChannelsData.slice(0, visiblePendingItems);

const handleActivityScroll = (e: React.UIEvent<HTMLDivElement>) => {
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
if (scrollHeight - scrollTop <= clientHeight * 1.5) {
if (visibleActivityItems < activityData.length) {
setVisibleActivityItems(prev => Math.min(prev + 5, activityData.length));
}
}
};

const handlePendingScroll = (e: React.UIEvent<HTMLDivElement>) => {
const { scrollTop, scrollHeight, clientHeight } = e.currentTarget;
if (scrollHeight - scrollTop <= clientHeight * 1.5) {
if (visiblePendingItems < pendingChannelsData.length) {
setVisiblePendingItems(prev => Math.min(prev + 5, pendingChannelsData.length));
}
}
};

const handleDelete = async (channelName: string) => {
try {
const response = await axios.delete(`${API_URL}/api/channel/${channelName}`);
if (response.status === 200) {
alert(`Deleted channel ${channelName} successfully.`);
closeDeleteModal();
} else {
alert(`Failed to delete channel ${channelName}.`);
}
} catch (error) {
console.error(error);
alert(`An error occurred while deleting channel ${channelName}.`);
}
};

const handleResend = async (email: string) => {
try {
const response = await axios.post(
Expand All @@ -90,7 +33,6 @@ const ManageAdmins: React.FC = () => {
},
}
);

if (response.status === 200) {
alert("Invitation resent successfully.");
} else {
Expand All @@ -102,121 +44,41 @@ const ManageAdmins: React.FC = () => {
}
};

const resetModalState = () => {
setVisibleActivityItems(15);
setVisiblePendingItems(15);
const openDeleteModal = (channelName: string) => {
setActiveModalData(channelName);
setIsDeleteModalOpen(true);
};

const handleModalClose = (type: 'activity' | 'pending') => {
if (type === 'activity') {
setIsViewMoreActivityOpen(false);
} else {
setIsViewMorePendingOpen(false);
const closeDeleteModal = () => setIsDeleteModalOpen(false);

const handleDelete = async (channelName: string) => {
try {
const response = await axios.delete(`${API_URL}/api/channel/${channelName}`);
if (response.status === 200) {
alert(`Deleted channel ${channelName} successfully.`);
closeDeleteModal();
} else {
alert(`Failed to delete channel ${channelName}.`);
}
} catch (error) {
console.error(error);
alert(`An error occurred while deleting channel ${channelName}.`);
}
resetModalState();
};

return (
<section className="text-base min-h-full" id="mda">
<h4 className="font-semibold text-base py-3">Activity</h4>
{/* Activity Tale */}
<div className="rounded-sm border border-gray-200 mb-6">
<div className="overflow-y-auto max-h-[480px] rounded-sm">
<AdminTable headers={activityTableHeadings}>
<>
{displayedActivities.map((activity, index) => (
<tr key={index} className="hover:bg-gray-100 text-sm">
<td className="border border-gray-200 px-6 py-3 w-1/3">
{activity.channelName}
</td>
<td className="border border-gray-200 px-6 py-3 w-1/3">
{activity.reach}
</td>
<td className="border border-gray-200 px-6 py-3 w-1/3">
{activity.timestamp}
</td>
</tr>
))}
</>
</AdminTable>
</div>
</div>
{activityData.length > 5 && (
<div className="flex justify-end p-4">
<button
onClick={() => setIsViewMoreActivityOpen(true)}
className="text-blue-500 hover:text-blue-700 text-sm font-medium"
>
View More
</button>
</div>
)}

{/* Pending Channels Table */}
<h4 className="font-semibold text-base py-3">Pending Channels</h4>
<div className="rounded-sm border border-gray-200">
<div className="overflow-y-auto max-h-[480px] rounded-sm">
<AdminTable headers={pendingTableHeadings}>
<>
{displayedPendingChannels.map((channel, index) => (
<tr key={index} className="hover:bg-gray-100 text-sm">
<td className="border border-gray-200 px-6 py-3">
{channel.email}
</td>
<td className="border border-gray-200 px-6 py-3">
{channel.channelName}
</td>
<td className="border border-gray-200 px-6 py-3">
{channel.category}
</td>
<td className="border border-gray-200 px-6 py-3">
<button
onClick={() => handleResend(channel.email)}
className="mr-4 text-black bg-green-400 px-4 py-1 hover:text-white"
>
Resend
</button>
<button
onClick={() => openDeleteModal(channel.channelName)}
className="text-black bg-red-600 px-4 py-1 hover:text-white"
>
Delete
</button>
</td>
</tr>
))}
</>
</AdminTable>
</div>
<div className="mb-6">
<h4 className="font-semibold text-lg mb-4">Activity Table</h4>
<ActivityTable data={activityData} />
</div>
{pendingChannelsData.length > 5 && (
<div className="flex justify-end p-4">
<button
onClick={() => setIsViewMorePendingOpen(true)}
className="text-blue-500 hover:text-blue-700 text-sm font-medium"
>
View More
</button>
</div>
)}

{/* View More Modals */}
<ViewMoreModal
isOpen={isViewMoreActivityOpen}
onClose={() => handleModalClose('activity')}
data={modalActivities}
type="activity"
onScroll={handleActivityScroll}
/>

<ViewMoreModal
isOpen={isViewMorePendingOpen}
onClose={() => handleModalClose('pending')}
data={modalPendingChannels}
type="pending"
onDelete={handleDelete}
{/* Pending Channels */}
<PendingChannels
pendingChannels={pendingChannelsData}
onResend={handleResend}
onScroll={handlePendingScroll}
onDelete={openDeleteModal}
headings={pendingTableHeadings}
/>

{/* Delete Modal */}
Expand Down
Loading

0 comments on commit 44993e0

Please sign in to comment.