diff --git a/backend/fastAPI.py b/backend/fastAPI.py
index de9a602..849fe1a 100644
--- a/backend/fastAPI.py
+++ b/backend/fastAPI.py
@@ -97,4 +97,9 @@ def get_selected_user():
@app.post("/add_user/{user_name}/{user_password}")
def add_new_user(user_name: str, user_password: str):
"""Adds a new user with the given name and password."""
- return users.add_user(user_name, user_password)
\ No newline at end of file
+ return users.add_user(user_name, user_password)
+
+@app.delete("/delete_user/{user_name}/{user_password}")
+def delete_user(user_name: str, user_password: str):
+ """Deletes a user with the given name and password."""
+ return users.delete_user(user_name, user_password)
\ No newline at end of file
diff --git a/backend/users.py b/backend/users.py
index dc81ec7..0ab4679 100644
--- a/backend/users.py
+++ b/backend/users.py
@@ -1,12 +1,23 @@
import json
import os
-BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # Get current script directory
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
SELECTED_USER_FILE = "selected_user.json"
-# print(os.path.abspath(os.path.join(BASE_DIR, "../database/users_db.json")))
USER_DB_FILE = os.path.abspath(os.path.join(BASE_DIR, "../database/users_db.json"))
+DEVICE_DB_FILE = os.path.abspath(os.path.join(BASE_DIR, "../backend/devices.json"))
+# print(os.path.abspath(os.path.join(BASE_DIR, "../backend/devices.json")))
updates = []
+def load_devices():
+ """Load smart home devices data from devices.json."""
+ if os.path.exists(DEVICE_DB_FILE):
+ with open(DEVICE_DB_FILE, "r") as f:
+ try:
+ data = json.load(f)
+ return [str(device["id"]) for device in data.get("smart_home_devices", [])]
+ except json.JSONDecodeError:
+ return []
+
def load_users():
"""Load user data from users_db.json."""
if os.path.exists(USER_DB_FILE):
@@ -27,10 +38,11 @@ def save_users(users):
def add_user(user_name: str, user_password: str):
"""Adds a new user with correct role and allocated devices."""
users = load_users()
+ available_devices = load_devices()
if not users:
user_role = "super_user"
- allocated_devices = ["1", "2", "3", "4", "5", "6"]
+ allocated_devices = available_devices
else:
user_role = "sub_user"
allocated_devices = []
@@ -45,17 +57,22 @@ def add_user(user_name: str, user_password: str):
"user_role": user_role
}
+ print(new_user)
+
users.append(new_user)
save_users(users)
- message = f"New user added: {user_name} ({user_role})"
+ message = f"New user added: {user_name} with role {'Super User' if user_role == 'super_user' else 'Sub User'}"
updates.append(message)
return {"success": message, "user": new_user}
def delete_user(user_name: str, user_password: str):
- """Deletes a user from the system if the given password matches. If deleting the super user, assign the position to the next user"""
+ """Deletes a user from the system if the given password matches. If deleting the super user, assign the position to the next user.
+ Re-indexes user IDs to maintain sequential order.
+ """
users = load_users()
+ available_devices = load_devices()
user_to_delete = next((u for u in users if u["user_name"] == user_name), None)
if not user_to_delete:
@@ -68,13 +85,16 @@ def delete_user(user_name: str, user_password: str):
users.remove(user_to_delete)
message = f"User {user_name} deleted."
-
+
if user_to_delete["user_role"] == "super_user" and users:
next_super_user = min(users, key=lambda u: u["user_id"])
next_super_user["user_role"] = "super_user"
- next_super_user["allocated_devices"] = ["1", "2", "3", "4", "5", "6"]
+ next_super_user["allocated_devices"] = available_devices
message += f" {next_super_user['user_name']} is now the super user."
+ for index, user in enumerate(users, start=1):
+ user["user_id"] = index
+
save_users(users)
updates.append(message)
return {"success": message}
@@ -98,6 +118,35 @@ def get_selected_user():
selected_user = data.get("selected_user", "")
return {"selected_user": selected_user}
+## USERS DEVICE MANAGEMENT ##
+def create_selected_user_devices_json():
+ """Create a JSON file with the selected users allocated devices"""
+ selected_user_data = get_selected_user()
+ selected_user_name = selected_user_data.get("selected_user")
+
+ if not selected_user_name:
+ return {"error": "No user selected."}
+
+ users = load_users()
+ devices = load_devices(full_details=True)
+
+ selected_user = next((u for u in users if u["user_name"] == selected_user_name), None)
+
+ if not selected_user:
+ return {"error": f"User {selected_user_name} not found."}
+
+ allocated_device_ids = set(selected_user.get("allocated_devices", []))
+
+ allocated_devices = [device for device in devices if str(device["id"]) in allocated_device_ids]
+
+ if not allocated_devices:
+ message = f"No devices allocated to {selected_user_name}."
+ updates.append(message)
+ return {"error": f"No devices allocated to {selected_user_name}."}
+
+ with open(SELECTED_USER_FILE, "w") as f:
+ json.dump({"user"})
+
def getUpdates():
global updates
messages = updates[:]
@@ -105,4 +154,5 @@ def getUpdates():
return messages
# DEBUGGING SHIT DONT MIND
-# load_users()
\ No newline at end of file
+# load_users()
+# add_user("Aditya S", "0000")
\ No newline at end of file
diff --git a/database/users_db.json b/database/users_db.json
index a69b845..55e0cbd 100644
--- a/database/users_db.json
+++ b/database/users_db.json
@@ -10,7 +10,9 @@
"3",
"4",
"5",
- "6"
+ "6",
+ "7",
+ "8"
],
"user_role": "super_user"
},
@@ -20,6 +22,13 @@
"user_password": "1415",
"allocated_devices": [],
"user_role": "sub_user"
+ },
+ {
+ "user_id": 3,
+ "user_name": "Ann E",
+ "user_password": "9999",
+ "allocated_devices": [],
+ "user_role": "sub_user"
}
]
}
\ No newline at end of file
diff --git a/frontend/src/app/users/page.jsx b/frontend/src/app/users/page.jsx
index 22b9a6d..fa1da7a 100644
--- a/frontend/src/app/users/page.jsx
+++ b/frontend/src/app/users/page.jsx
@@ -112,13 +112,40 @@ const Users = () => {
const [newUsername, setNewUsername] = useState("");
const [newPassword, setNewPassword] = useState("");
const [error, setError] = useState("");
+ const [userToDelete, setUserToDelete] = useState(null);
+ const [deletePassword, setDeletePassword] = useState("");
+ const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
+ const [deleteError, setDeleteError] = useState("");
+
+ const handleDeleteClick = (user) => {
+ setUserToDelete(user);
+ setDeletePassword("");
+ setDeleteError("");
+ setDeleteDialogOpen(true);
+ };
+
+ const fetchUsers = async () => {
+ try {
+ const response = await fetch("http://localhost:8000/user_data");
+ const data = await response.json();
+ setUsers(data.users || []);
+ } catch (error) {
+ console.error("Error fetching users:", error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ fetchUsers();
+ }, []);
const handleNewUserSubmit = async () => {
if (newUsername.trim() === "" || newPassword.length !== 4 || isNaN(newPassword)) {
setError("Username must not be empty and password must be a 4-digit number.");
return;
}
-
+
try {
const response = await fetch(
`http://localhost:8000/add_user/${encodeURIComponent(newUsername)}/${encodeURIComponent(newPassword)}`,
@@ -126,46 +153,59 @@ const Users = () => {
method: "POST",
}
);
-
+
if (!response.ok) {
const errorMessage = await response.text();
setError(`Failed to add user: ${errorMessage}`);
return;
}
-
- const newUser = await response.json();
-
- setUsers((prevUsers) => [...prevUsers, newUser]);
-
+
setOpenNewUserDialog(false);
setNewUsername("");
setNewPassword("");
setError("");
+
+ fetchUsers();
} catch (error) {
console.error("Error adding user:", error);
setError("An error occurred while adding the user.");
}
};
- const router = useRouter();
+ const handleConfirmDelete = async () => {
+ if (!userToDelete || deletePassword.length !== 4 || isNaN(deletePassword)) {
+ setDeleteError("Please enter a valid 4-digit password.");
+ return;
+ }
- const theme = getTheme(darkMode ? "dark" : "light");
+ try {
+ const response = await fetch(
+ `http://localhost:8000/delete_user/${encodeURIComponent(userToDelete.user_name)}/${encodeURIComponent(deletePassword)}`,
+ {
+ method: "DELETE",
+ }
+ );
- useEffect(() => {
- const fetchUsers = async () => {
- try {
- const response = await fetch("http://localhost:8000/user_data");
- const data = await response.json();
- setUsers(data.users || []);
- } catch (error) {
- console.error("Error fetching users:", error);
- } finally {
- setLoading(false);
+ if (!response.ok) {
+ const errorMessage = await response.text();
+ setDeleteError(`Failed to delete user: ${errorMessage}`);
+ return;
}
- };
- fetchUsers();
- }, []);
+ // Fetch users again to update the UI correctly
+ await fetchUsers();
+
+ setDeleteDialogOpen(false);
+ setUserToDelete(null);
+ } catch (error) {
+ console.error("Error deleting user:", error);
+ setDeleteError("An error occurred while deleting the user.");
+ }
+ };
+
+ const router = useRouter();
+
+ const theme = getTheme(darkMode ? "dark" : "light");
const handleUserClick = (user) => {
setSelectedUser(user);
@@ -266,8 +306,8 @@ const Users = () => {
sx={{
bgcolor: "background.paper",
color: "text.primary",
- p: 2,
textAlign: "center",
+ p: 2,
boxShadow: 6,
borderRadius: 3,
cursor: "pointer",
@@ -293,9 +333,9 @@ const Users = () => {
position: "absolute",
bottom: 8,
right: 8,
- color: "text.secondary",
+ color: "primary.main",
}}
- onClick={() => handleDeleteUser(user.user_name)}
+ onClick={() => handleDeleteClick(user)}
>
@@ -390,6 +430,37 @@ const Users = () => {
+
+