Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useEffect, useState } from "react";
- import { useAuth } from "./authContext"
- import axios from "axios";
- import { Plus, Edit, Trash2, Users, Ambulance } from "lucide-react";
- import WebSocketDemo from "./websocket";
- function AdminPortal() {
- const { role } = useAuth();
- const [users, setUsers] = useState([]);
- const [loading, setLoading] = useState(false);
- const [showAddForm, setShowAddForm] = useState(false);
- const [firstName, setFirstName] = useState("");
- const [lastName, setLastName] = useState("");
- const [age, setAge] = useState("");
- const [password, setPassword] = useState("");
- const [phone, setPhone] = useState("");
- const [email, setEmail] = useState("");
- const [usePhone, setUsePhone] = useState(true);
- const [user, setUser] = useState("");
- const getMembers = async () => {
- const token = localStorage.getItem("token");
- setLoading(true);
- try {
- const response = await axios.get(
- "http://127.0.0.1:8000/users/organization/",
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- }
- );
- setUsers(response.data);
- } catch (error) {
- console.error("Error fetching users:", error);
- } finally {
- setLoading(false);
- }
- };
- const addUser = async (e) => {
- e.preventDefault();
- const token = localStorage.getItem("token");
- const payload = {
- first_name: firstName,
- last_name: lastName,
- age: Number(age),
- role : (role == "HealthAdmin" ? "Doctor": "Driver"),
- password,
- ...(usePhone ? { phone_number: phone.replace(/^0/, "+233") } : { email }),
- };
- console.log(payload)
- try {
- const response = await axios.post(
- "http://127.0.0.1:8000/users/organization/",
- payload,
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- }
- );
- getMembers();
- setShowAddForm(false);
- } catch (error) {
- console.error("Error adding user:", error);
- }
- };
- const deleteUser = async (username) => {
- const token = localStorage.getItem("token");
- console.log(users);
- try {
- await axios.delete(
- `http://127.0.0.1:8000/users/organization/${username}/`,
- {
- headers: {
- 'Authorization': `Bearer ${token}`,
- 'Content-Type': 'application/json'
- }
- }
- );
- setUsers(users.filter(user => user.email !== username || user.phone_number !== username));
- getMembers();
- } catch (error) {
- console.error("Error deleting user:", error);
- }
- };
- useEffect(() => {
- getMembers();
- if(localStorage.getItem('user')) {
- const u = JSON.parse(localStorage.getItem('user'));
- setUser(u);
- console.log(u.email);
- }
- }, []);
- return (
- <div className="min-h-screen bg-gradient-to-br from-gray-900 via-gray-800 to-gray-700 p-6">
- <WebSocketDemo/>
- <div className="max-w-6xl mx-auto">
- {/* Header */}
- <div className="bg-gray-900 rounded-lg shadow-lg p-6 mb-6 border-b-4 border-red-500 flex items-center justify-between">
- <div className="flex items-center gap-3">
- <Ambulance className="w-8 h-8 text-red-500" />
- <div>
- <h1 className="text-2xl font-bold text-white">{(user) ? user.first_name + " " + user.last_name:""} </h1>
- <p className="text-gray-400">{role}</p>
- </div>
- </div>
- <button
- onClick={() => setShowAddForm(!showAddForm)}
- className="flex items-center gap-2 bg-red-500 text-white px-4 py-2 rounded-lg hover:bg-red-600 transition-colors shadow-md font-semibold"
- >
- <Plus className="w-4 h-4" />
- Add User
- </button>
- </div>
- {/* Add User Form */}
- {showAddForm && (
- <div className="bg-gray-800 rounded-lg shadow-lg p-6 mb-6 border border-gray-700">
- <h2 className="text-lg font-semibold mb-4 text-white">Add New User</h2>
- <button onClick={() => setUsePhone(!usePhone)} className="text-blue-400 mb-2">
- Create user {usePhone ? "using email":"using phone"}
- </button>
- <form onSubmit={addUser} className="grid grid-cols-1 md:grid-cols-2 gap-4">
- {usePhone ?
- <input
- type="phone"
- placeholder="phone"
- value={phone}
- onChange={(e) => setPhone(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400"
- required
- /> :
- <input
- type="email"
- placeholder="Email"
- value={email}
- onChange={(e) => setEmail(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400"
- required
- />
- }
- <input
- type="password"
- placeholder="Password"
- value={password}
- onChange={(e) => setPassword(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-400"
- required
- />
- <input
- type="text"
- placeholder="First Name"
- value={firstName}
- onChange={ (e) => setFirstName(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400"
- />
- <input
- type="text"
- placeholder="Last Name"
- value={lastName}
- onChange={(e) => setLastName(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400"
- />
- <input
- type="number"
- placeholder="Age"
- value={age}
- onChange={(e) => setAge(e.target.value)}
- className="px-3 py-2 bg-gray-700 text-white border border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-400"
- />
- <div className="md:col-span-2 flex gap-2">
- <button
- type="submit"
- className="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition-colors font-semibold shadow-md"
- >
- Add User
- </button>
- <button
- type="button"
- onClick={() => setShowAddForm(false)}
- className="bg-gray-500 text-white px-4 py-2 rounded-lg hover:bg-gray-600 transition-colors font-semibold shadow-md"
- >
- Cancel
- </button>
- </div>
- </form>
- </div>
- )}
- {/* Users Table */}
- <div className="bg-gray-800 rounded-lg shadow-lg overflow-hidden border border-gray-700">
- <div className="px-6 py-4 border-b border-gray-700">
- <h2 className="text-lg font-semibold text-white">Organization Users ({users.length})</h2>
- </div>
- {loading ? (
- <div className="p-6 text-center">
- <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-red-500 mx-auto"></div>
- <p className="mt-2 text-gray-400">Loading users...</p>
- </div>
- ) : (
- <div className="overflow-x-auto">
- <table className="w-full">
- <thead className="bg-gray-900">
- <tr>
- <th className="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">User</th>
- <th className="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Email/Number</th>
- <th className="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Role</th>
- <th className="px-6 py-3 text-left text-xs font-medium text-gray-400 uppercase tracking-wider">Actions</th>
- </tr>
- </thead>
- <tbody className="bg-gray-800 divide-y divide-gray-700">
- {users.map((user) => (
- <tr key={user.id} className="hover:bg-gray-700">
- <td className="px-6 py-4 whitespace-nowrap">
- <div>
- <div className="text-sm font-medium text-white">
- {user.first_name} {user.last_name}
- </div>
- <div className="text-sm text-gray-400">@{user.username}</div>
- </div>
- </td>
- <td className="px-6 py-4 whitespace-nowrap text-sm text-white">
- {(user.email) ? user.email : user.phone_number}
- </td>
- <td className="px-6 py-4 whitespace-nowrap">
- <span className="px-2 py-1 text-xs rounded-full bg-blue-900 text-blue-300">
- {user.role || 'User'}
- </span>
- </td>
- <td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
- <div className="flex gap-2">
- <button className="text-blue-400 hover:text-blue-200 p-1">
- <Edit className="w-4 h-4" />
- </button>
- <button
- onClick={() => deleteUser(user.email ? user.email : user.phone_number)}
- className="text-red-400 hover:text-red-200 p-1"
- >
- <Trash2 className="w-4 h-4" />
- </button>
- </div>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
- </div>
- )}
- </div>
- </div>
- </div>
- );
- }
- export default AdminPortal;
Advertisement
Add Comment
Please, Sign In to add comment