Skip to content

Commit

Permalink
Admin User Visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
A-Hazzard committed Nov 5, 2024
1 parent a3a87ab commit c55ba8a
Showing 1 changed file with 177 additions and 109 deletions.
286 changes: 177 additions & 109 deletions components/UserManagement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
TableHeader,
TableRow,
Pagination,
Card,
} from "@nextui-org/react";
import {
collection,
Expand Down Expand Up @@ -49,11 +50,14 @@ const UserManagement = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
const [currentUserUid, setCurrentUserUid] = useState<string | null>(null);
const [modalVisible, setModalVisible] = useState(false);
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [isMakingAdmin, setIsMakingAdmin] = useState(true);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(0);
const [walletBalance, setWalletBalance] = useState<number | null>(null);
const [totalProfit, setTotalProfit] = useState<number | null>(null);
const [balanceModalVisible, setBalanceModalVisible] = useState(false);
const [isConfirmingAdminToggle, setIsConfirmingAdminToggle] = useState(false);

useEffect(() => {
const unsubscribeAuth = auth.onAuthStateChanged((user) => {
Expand Down Expand Up @@ -202,13 +206,12 @@ const UserManagement = () => {
const handleAdminToggle = async (user: User) => {
setSelectedUser(user);
setIsMakingAdmin(!user.isAdmin);
setModalVisible(true);
setIsConfirmingAdminToggle(true);
};

useEffect(() => {
console.log("selectedUser", selectedUser);
console.log("modalVisible", modalVisible);
}, [selectedUser, modalVisible]);
}, [selectedUser, isConfirmingAdminToggle]);

const confirmAdminToggle = async () => {
if (!selectedUser?.email) {
Expand Down Expand Up @@ -249,7 +252,7 @@ const UserManagement = () => {
toast.success(
`User ${isMakingAdmin ? "made" : "removed as"} admin successfully`
);
setModalVisible(false);
setIsConfirmingAdminToggle(false);
} catch (error) {
console.error("Error updating admin status:", error);
toast.error("Failed to update admin status");
Expand All @@ -262,117 +265,182 @@ const UserManagement = () => {
setCurrentPage(page);
};

const fetchUserFinancials = async (email: string) => {
try {
const walletDocRef = doc(db, "wallets", email);
const walletDoc = await getDoc(walletDocRef);
const profitDocRef = doc(db, "profits", email);
const profitDoc = await getDoc(profitDocRef);

if (walletDoc.exists()) {
setWalletBalance(walletDoc.data()?.balance);
} else {
setWalletBalance(null);
}

if (profitDoc.exists()) {
setTotalProfit(profitDoc.data()?.profit);
} else {
setTotalProfit(null);
}
} catch (error) {
console.error("Error fetching user financials:", error);
}
};

const handleUserClick = (user: User) => {
fetchUserFinancials(user.email);
setBalanceModalVisible(true);
};

if (loading) {
return <Spinner size="lg" />;
}

return (
<div className="max-w-7xl mx-auto px-4 py-6 text-light">
<ToastContainer />

<div className="bg-darker p-6 rounded-xl border border-readonly/30">
<h2 className="text-xl font-bold mb-6">User Management</h2>
<Table
aria-label="User management table"
className="rounded-lg shadow-md"
classNames={{
th: "bg-readonly text-light",
td: "text-gray"
}}
>
<TableHeader>
<TableColumn>Username</TableColumn>
<TableColumn>Email</TableColumn>
<TableColumn>Created At</TableColumn>
<TableColumn>Status</TableColumn>
<TableColumn>Actions</TableColumn>
</TableHeader>
<TableBody>
{users
.filter((user) => user.uid !== currentUserUid)
.map((user) => (
<TableRow key={user.uid}>
<TableCell className="font-semibold text-light">{user.displayName}</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{formatDate(user.createdAt)}</TableCell>
<TableCell>
<span className={`px-2 py-1 rounded-full text-xs ${
user.isDisabled
? 'bg-red-500/20 text-red-500'
: 'bg-green-500/20 text-green-500'
}`}>
{user.isDisabled ? "Disabled" : "Active"}
</span>
</TableCell>
<TableCell>
<div className="flex gap-2">
<Button
size="sm"
className={user.isDisabled ? "bg-green-500/20 text-green-500" : "bg-orange/20 text-orange"}
onClick={() => handleToggleDisable(user.uid, user.isDisabled)}
<ToastContainer />

<div className="bg-darker p-6 rounded-xl border border-readonly/30">
<h2 className="text-xl font-bold mb-6">User Management</h2>
<Table
aria-label="User management table"
className="rounded-lg shadow-md"
classNames={{
th: "bg-readonly text-light",
td: "text-gray"
}}
>
<TableHeader>
<TableColumn>Username</TableColumn>
<TableColumn>Email</TableColumn>
<TableColumn>Created At</TableColumn>
<TableColumn>Status</TableColumn>
<TableColumn>Actions</TableColumn>
</TableHeader>
<TableBody>
{users
.filter((user) => user.uid !== currentUserUid)
.map((user) => (
<TableRow key={user.uid}>
<TableCell
className="font-semibold text-light cursor-pointer"
onClick={() => handleUserClick(user)}
>
{user.isDisabled ? "Enable" : "Disable"}
</Button>
<Button
size="sm"
className="bg-red-500/20 text-red-500"
onClick={() => handleDeleteUser(user.uid)}
>
Delete
</Button>
<Button
size="sm"
className={user.isAdmin ? "bg-orange/20 text-orange" : "bg-blue-500/20 text-blue-500"}
onClick={() => handleAdminToggle(user)}
>
{user.isAdmin ? "Remove Admin" : "Make Admin"}
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>

<Pagination
total={totalPages}
initialPage={1}
page={currentPage}
onChange={handlePageChange}
className="flex justify-center mt-4"
/>

<Modal
closeButton
isOpen={modalVisible}
onClose={() => setModalVisible(false)}
classNames={{
base: "bg-darker border border-readonly/30",
header: "border-b border-readonly/30",
body: "text-light py-6",
footer: "border-t border-readonly/30"
}}
>
<ModalContent>
<ModalHeader>
<h2 className="text-xl font-bold">{isMakingAdmin ? "Make Admin" : "Remove Admin"}</h2>
</ModalHeader>
<ModalBody>
<p>Are you sure you want to {isMakingAdmin ? "make" : "remove"} {selectedUser?.displayName} as an admin?</p>
</ModalBody>
<ModalFooter>
<Button variant="light" className="bg-readonly text-gray" onClick={() => setModalVisible(false)}>
Cancel
</Button>
<Button className="bg-orange hover:bg-orange/90" onClick={confirmAdminToggle}>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>

{user.displayName}
</TableCell>
<TableCell>{user.email}</TableCell>
<TableCell>{formatDate(user.createdAt)}</TableCell>
<TableCell>
<span className={`px-2 py-1 rounded-full text-xs ${
user.isDisabled
? 'bg-red-500/20 text-red-500'
: 'bg-green-500/20 text-green-500'
}`}>
{user.isDisabled ? "Disabled" : "Active"}
</span>
</TableCell>
<TableCell>
<div className="flex gap-2">
<Button
size="sm"
className={user.isDisabled ? "bg-green-500/20 text-green-500" : "bg-orange/20 text-orange"}
onClick={() => handleToggleDisable(user.uid, user.isDisabled)}
>
{user.isDisabled ? "Enable" : "Disable"}
</Button>
<Button
size="sm"
className="bg-red-500/20 text-red-500"
onClick={() => handleDeleteUser(user.uid)}
>
Delete
</Button>
<Button
size="sm"
className={user.isAdmin ? "bg-orange/20 text-orange" : "bg-blue-500/20 text-blue-500"}
onClick={() => handleAdminToggle(user)}
>
{user.isAdmin ? "Remove Admin" : "Make Admin"}
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>

<Pagination
total={totalPages}
initialPage={1}
page={currentPage}
onChange={handlePageChange}
className="flex justify-center mt-4"
/>

<Modal
closeButton
isOpen={isConfirmingAdminToggle}
onClose={() => setIsConfirmingAdminToggle(false)}
classNames={{
base: "bg-darker border border-readonly/30",
header: "border-b border-readonly/30",
body: "text-light py-6",
footer: "border-t border-readonly/30"
}}
>
<ModalContent>
<ModalHeader>
<h2 className="text-xl font-bold">Confirm Admin Toggle</h2>
</ModalHeader>
<ModalBody>
<p>Are you sure you want to {isMakingAdmin ? "make" : "remove"} {selectedUser?.displayName} as an admin?</p>
</ModalBody>
<ModalFooter>
<Button variant="light" className="bg-readonly text-gray" onClick={() => setIsConfirmingAdminToggle(false)}>
Cancel
</Button>
<Button variant="solid" onClick={confirmAdminToggle}>
Confirm
</Button>
</ModalFooter>
</ModalContent>
</Modal>

<Modal
closeButton
isOpen={balanceModalVisible}
onClose={() => setBalanceModalVisible(false)}
classNames={{
base: "bg-darker border border-readonly/30",
header: "border-b border-readonly/30",
body: "text-light py-6",
footer: "border-t border-readonly/30"
}}
>
<ModalContent>
<ModalHeader>
<h2 className="text-xl text-light font-bold">User Finances</h2>
</ModalHeader>
<ModalBody>
<Card className="p-4 mb-4">
<h3 className="text-lg font-semibold">Wallet Balance</h3>
<p>{walletBalance !== null ? `$${walletBalance.toFixed(2)}` : "Not Deposit Has Been Made"}</p>
</Card>
<Card className="p-4">
<h3 className="text-lg font-semibold">Total Profits</h3>
<p>{totalProfit !== null ? `$${totalProfit.toFixed(2)}` : "Not Profit Has Been Made"}</p>
</Card>
</ModalBody>
<ModalFooter>
<Button variant="light" className="bg-readonly text-gray" onClick={() => setBalanceModalVisible(false)}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</div>
);
};

Expand Down

0 comments on commit c55ba8a

Please sign in to comment.