Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
SydZero committed Oct 16, 2024
2 parents 1a2868a + 1876a93 commit 3f16393
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 128 deletions.
Empty file added .env
Empty file.
File renamed without changes.
2 changes: 2 additions & 0 deletions backend/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ public class User
public Guid uuid { get; set; }
public string? log_in_info { get; set; }
public bool isDel { get; set; }

public string? role {get; set;} = "unverified";
}
}
11 changes: 7 additions & 4 deletions backend/Services/UserService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ public async Task<Guid> CreateUserAsync(string log_in_info)

Guid userID = Guid.NewGuid();

command.CommandText = @"INSERT INTO User (uuid, log_in_info) VALUES (@uuid, @log_in_info);";
command.CommandText = @"INSERT INTO User (uuid, log_in_info, role) VALUES (@uuid, @log_in_info, @role);";

command.Parameters.AddWithValue("@uuid", userID);
command.Parameters.AddWithValue("@log_in_info", log_in_info);
command.Parameters.AddWithValue("@role", "unverified");

await command.ExecuteNonQueryAsync();

Expand All @@ -50,11 +51,12 @@ public async Task UpdateUserAsync(User user)
using var connection = await database.OpenConnectionAsync();
using var command = connection.CreateCommand();

command.CommandText = @"UPDATE User SET log_in_info = @log_in_info, isDel = @isDel WHERE uuid = @uuid;";
command.CommandText = @"UPDATE User SET log_in_info = @log_in_info, isDel = @isDel, role = @role WHERE uuid = @uuid;";

command.Parameters.AddWithValue("@uuid", user.uuid);
command.Parameters.AddWithValue("@log_in_info", user.log_in_info);
command.Parameters.AddWithValue("@isDel", user.isDel);
command.Parameters.AddWithValue("@role", user.role);

await command.ExecuteNonQueryAsync();
}
Expand All @@ -81,8 +83,9 @@ private async Task<IReadOnlyList<User>> ReadAllAsync(DbDataReader reader)
var user = new User
{
uuid = reader.GetGuid(0),
log_in_info = reader.GetString(1),
isDel = reader.GetBoolean(2),
log_in_info = reader.IsDBNull(1) ? string.Empty : reader.GetString(1),
isDel = !reader.IsDBNull(2) && reader.GetBoolean(2),
role = reader.IsDBNull(3) ? "unverified" : reader.GetString(3)
};
users.Add(user);
}
Expand Down
26 changes: 23 additions & 3 deletions frontend/src/webPages/LogIn/logIn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,32 @@ interface Profile {
}
})
.then((res) => {
setProfile(res.data);
// navigate('/LoggedIn');
const profileData = res.data;
setProfile(profileData);

// Send the email to the backend to create or retrieve the user
axios.post('http://localhost:8080/api/User/create', JSON.stringify(profileData.email), {
headers: {
'Content-Type': 'application/json'
}
})
.then((response) => {
console.log('User ID:', response.data);
// Navigate to the logged-in page if needed
// navigate('/LoggedIn');
})
.catch((error) => {
console.error('Error creating user:', error);
alert('error catching user');
});
})
.catch((err) => console.log(err));
.catch((err) => {
console.error('Error fetching user profile:', err);
alert('error fetching profile');
});
}
}, [user]);


// log out function to log the user out of google and set the profile array to null
const logOut = () => {
Expand Down
237 changes: 116 additions & 121 deletions frontend/src/webPages/Roles/RoleManagement.tsx
Original file line number Diff line number Diff line change
@@ -1,138 +1,133 @@
import { useEffect, useState } from 'react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Modal from '@mui/material/Modal';
import { Footer } from '../Components/HeaderFooter';

interface User {
id: string;
name: string;
email: string;
role: 'unverified' | 'verified' | 'admin'; // Define the possible roles
uuid: string;
log_in_info: string;
role: string;
}

const RoleManagement = () => {
const [users, setUsers] = useState<User[]>([]);
const [selectedUser, setSelectedUser] = useState<User | null>(null);
const [roleModalOpen, setRoleModalOpen] = useState(false);

const handleRoleModalOpen = (user: User) => {
setSelectedUser(user);
setRoleModalOpen(true);
};
const RoleManagement: React.FC = () => {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const [selectedRoles, setSelectedRoles] = useState<{ [key: string]: string }>({});
const [search, setSearch] = useState<string>(''); // State for search input
const [roleFilter, setRoleFilter] = useState<string>('all'); // State for role filter

const handleRoleModalClose = () => {
setSelectedUser(null);
setRoleModalOpen(false);
// Fetch users from the backend when the component mounts
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await axios.get<User[]>('http://localhost:8080/api/User/all');
setUsers(response.data);
// Initialize selectedRoles with each user's current role
const initialRoles = response.data.reduce((acc, user) => {
acc[user.uuid] = user.role;
return acc;
}, {} as { [key: string]: string });
setSelectedRoles(initialRoles);
} catch (error) {
console.error('Error fetching users:', error);
setError('Failed to fetch users');
} finally {
setLoading(false);
}
};
fetchUsers();
}, []);

// Fetch users from the backend
useEffect(() => {
const fetchUsers = async () => {
try {
const response = await axios.get<User[]>('http://localhost:5173/api/User/all'); // Adjust the endpoint as needed
setUsers(response.data);
} catch (error) {
console.error('Error fetching users:', error);
}
};
const handleRoleChange = (uuid: string, newRole: string) => {
setSelectedRoles((prevRoles) => ({
...prevRoles,
[uuid]: newRole,
}));
};

fetchUsers();
}, []);
const updateRole = async (uuid: string) => {
try {
const user = users.find((u) => u.uuid === uuid);
if (!user) return;

// Update user role
const updateUserRole = async (userId: string, newRole: 'unverified' | 'verified' | 'admin') => {
try {
await axios.patch(`/api/users/${userId}`, { role: newRole }); // Adjust the endpoint as needed
setUsers(prevUsers =>
prevUsers.map(user =>
user.id === userId ? { ...user, role: newRole } : user
)
);
handleRoleModalClose();
} catch (error) {
console.error('Error updating user role:', error);
}
};
const updatedUser = {
...user,
role: selectedRoles[uuid],
};

const style = {
position: 'absolute' as 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
await axios.put(`http://localhost:8080/api/User/update`, updatedUser);
alert('Role updated successfully!');
} catch (error) {
console.error('Error updating role:', error);
alert('Failed to update role');
}
};

const filteredUsers = users.filter((user) =>
user.log_in_info.toLowerCase().includes(search.toLowerCase()) &&
(roleFilter === 'all' || user.role === roleFilter)
);

return (
<section>
<Box sx={{ width: '100%', maxWidth: 700, mb: 4 }}>
<Typography variant="h2" sx={{ color: 'black' }}>
Role Management
</Typography>
</Box>

<div>
{users.map(user => (
<Box key={user.id} sx={{ bgcolor: '#C3D7EE', padding: 2, marginBottom: 2 }}>
<Typography variant="h6">{user.name}</Typography>
<Typography variant="body1">Email: {user.email}</Typography>
<Typography variant="body2">Role: {user.role}</Typography>
<Button
variant='contained'
onClick={() => handleRoleModalOpen(user)}
sx={{ width: '50%' }}
>
Change Role
</Button>
</Box>
))}
</div>
if (loading) {
return <div>Loading users...</div>;
}

<Modal open={roleModalOpen} onClose={handleRoleModalClose}>
<Box sx={style}>
<Typography variant="h4">Change Role</Typography>
{selectedUser && (
<>
<Typography variant="body1">User: {selectedUser.name}</Typography>
<Typography variant="body2">Current Role: {selectedUser.role}</Typography>

<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'verified')}
sx={{ margin: '8px' }}
>
Set to Verified
</Button>
<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'admin')}
sx={{ margin: '8px' }}
>
Set to Admin
</Button>
<Button
variant="contained"
onClick={() => updateUserRole(selectedUser.id, 'unverified')}
sx={{ margin: '8px' }}
>
Set to Unverified
</Button>
</>
)}
</Box>
</Modal>
if (error) {
return <div>{error}</div>;
}

<div>
<Footer />
</div>
</section>
);
return (
<div>
<h1>Role Management</h1>
<div style={{ marginBottom: '10px' }}>
<input
type="text"
placeholder="Search by email"
value={search}
onChange={(e) => setSearch(e.target.value)}
style={{ marginRight: '10px', padding: '5px', width: '200px' }}
/>
<select
value={roleFilter}
onChange={(e) => setRoleFilter(e.target.value)}
style={{ padding: '5px' }}
>
<option value="all">All</option>
<option value="unverified">Unverified</option>
<option value="verified">Verified</option>
<option value="admin">Admin</option>
</select>
</div>
<table>
<thead>
<tr>
<th>Email</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{filteredUsers.map((user) => (
<tr key={user.uuid}>
<td>{user.log_in_info}</td>
<td>
<select
value={selectedRoles[user.uuid]}
onChange={(e) => handleRoleChange(user.uuid, e.target.value)}
>
<option value="unverified">Unverified</option>
<option value="verified">Verified</option>
<option value="admin">Admin</option>
</select>
</td>
<td>
<button onClick={() => updateRole(user.uuid)}>Update Role</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};

export default RoleManagement;

0 comments on commit 3f16393

Please sign in to comment.