Skip to content

Commit

Permalink
implemented ability to deactivate student account
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiebones committed Mar 28, 2021
1 parent 5d85673 commit 2f5f6e6
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 4 deletions.
12 changes: 11 additions & 1 deletion client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import CustomNavbar from "./components/common/customNavbar";
import AdminViewTransaction from "./components/adminViewTransaction";
import GlobalStyle from "./globalStyles";
import CreateStaffUserAccountByAdmin from "./components/adminCreateUserAccount";
import SearchUserAccount from "./components/searchStudentAccount";
/**
imports of page components ends here
*/
Expand Down Expand Up @@ -256,6 +257,16 @@ const App = (props) => {
authorizedRole={["super-admin", "admin"]}
{...props}
/>
<AuthorizedComponent
path="/admin/student_account"
exact
component={SearchUserAccount}
authenticated={authenticated}
currentUser={currentUser}
authorizedRole={["super-admin", "admin"]}
{...props}
/>

<AuthorizedComponent
path="/admin/view_transactions"
exact
Expand All @@ -265,7 +276,6 @@ const App = (props) => {
authorizedRole={["super-admin", "admin"]}
{...props}
/>

<AuthorizedComponent
path="/admin/create_staff_account"
exact
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/adminCreateUserAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const AdminCreateUserAccount = () => {
</div>
<form onSubmit={createUserAccountFunction}>
<div className="form-group">
<label htmlFor="name">Email</label>
<label htmlFor="email">Email</label>
<input
type="email"
className="form-control"
Expand Down
8 changes: 8 additions & 0 deletions client/src/components/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@ const Navbar = ({ authenticated, currentUser }) => {
>
Create Staff Account
</StyledLink>

<StyledLink
exact
to="/admin/student_account"
className="nav-link"
>
View Student Accounts
</StyledLink>
</div>
</li>
</React.Fragment>
Expand Down
78 changes: 78 additions & 0 deletions client/src/components/reuseableComponents/usersTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from "react";
import styled from "styled-components";
import { CapFirstLetterOfEachWord } from "../../modules/utils";

const UsersTableStyles = styled.div`
.even {
background-color: #bdba4b;
}
`;

const UserTable = ({ users, activateUser, submitted }) => {
const activateDeactivateUser = (userId) => {
activateUser(userId);
};
return (
<UsersTableStyles>
<table className="table table-striped table-bordered">
<thead>
<tr>
<th scope="col" className="text-center">
Name
</th>
<th scope="col" className="text-center">
Reg Number
</th>
<th scope="col" className="text-center">
Email
</th>

<th scope="col" className="text-center">
Account Status
</th>
</tr>
</thead>
<tbody>
{users.map(({ email, name, regNumber, active, id }) => {
return (
<tr key={regNumber} className="even">
<td>
<p>{CapFirstLetterOfEachWord(name)}</p>
</td>
<td>
<p>{regNumber.toUpperCase()}</p>
</td>
<td>
<p>
<span>{email}</span>
</p>
</td>
<td>
{active ? (
<button
disabled={submitted}
className="btn btn-sm btn-danger"
onClick={() => activateDeactivateUser(id)}
>
{submitted ? "please wait....." : "deactivate"}
</button>
) : (
<button
disabled={submitted}
className="btn btn-sm btn-success"
onClick={() => activateDeactivateUser(id)}
>
{submitted ? "please wait....." : "activate"}
</button>
)}
</td>
</tr>
);
})}
</tbody>
</table>
</UsersTableStyles>
);
};

export default UserTable;
132 changes: 132 additions & 0 deletions client/src/components/searchStudentAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React, { useState, useEffect } from "react";
import { useLazyQuery, useMutation } from "@apollo/client";
import { ActivateDeactivateUser } from "../graphql/mutation";
import { SearchUserAccount } from "../graphql/queries";
import styled from "styled-components";
import Loading from "./common/loading";
import UsersTable from "./reuseableComponents/usersTable";

const SearchRecordsStyles = styled.div``;

const SearchStudentAccount = () => {
const [regNumber, setRegNumber] = useState("");
const [users, setUsers] = useState([]);
const [errors, setErrors] = useState(null);
const [noData, setNoData] = useState(false);
const [submitted, setSubmitted] = useState(false);

const [searchFunc, searchResult] = useLazyQuery(SearchUserAccount);
const [activateFunction, activateResult] = useMutation(
ActivateDeactivateUser
);

useEffect(() => {
if (searchResult.data) {
const users = searchResult.data.searchStudentAccount;

if (users.length > 0) {
setUsers(users);
setNoData(false);
} else {
setNoData(true);
setUsers([]);
}
}
if (searchResult.error) {
setErrors(searchResult.error);
}
}, [searchResult.data, searchResult.error]);

useEffect(() => {
if (activateResult.data) {
setSubmitted(!submitted);
window.alert("successful");
}
if (activateResult.error) {
setSubmitted(!submitted);
setErrors(activateResult.error);
}
}, [activateResult.data, activateResult.error]);

const performSearchInput = (e) => {
const value = e.target.value;
setRegNumber(value);
if (value.length > 1) {
//perform query search here
setTimeout(
searchFunc({
variables: {
regNumber: value,
},
}),
500
);
}
};
const activateUser = async (userId) => {
const confirmOperation = window.confirm("please confirm your action");
if (!confirmOperation) return;
try {
setSubmitted(!submitted);
await activateFunction({
variables: {
userId: userId,
},
refetchQueries: [
{
query: SearchUserAccount,
variables: {
regNumber: regNumber,
},
},
],
});
} catch (error) {}
};
return (
<SearchRecordsStyles>
<div className="row">
<div className="col-md-12">
<div className="text-center">
{searchResult.loading && <Loading />}
{errors && <p className="lead text-danger">{errors.message}</p>}
</div>
</div>
</div>
<div className="row">
<div className="col-md-6 offset-md-3">
<form>
<div className="form-group">
<label htmlFor="regNumber">Reg Number</label>
<input
type="text"
className="form-control"
name="regNumber"
aria-describedby="regNumber"
value={regNumber}
onChange={performSearchInput}
/>
</div>
</form>
</div>
</div>
<div className="row">
<div className="col-md-12">
<div className="text-center">
{noData && <p className="lead">Your query returned no result!</p>}

{users.length > 0 && (
<UsersTable
users={users}
activateUser={activateUser}
submitted={submitted}
/>
)}
</div>
</div>
</div>
</SearchRecordsStyles>
);
};

export default SearchStudentAccount;
11 changes: 9 additions & 2 deletions client/src/graphql/mutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,6 @@ const ConfirmStudentTransaction = gql`
}
`;

//createStaffUserAccountByAdmin

const CreateStaffUserAccountByAdmin = gql`
mutation createStaffUserAccountByAdmin(
$email: String!
Expand All @@ -373,7 +371,16 @@ const CreateStaffUserAccountByAdmin = gql`
}
`;

//

const ActivateDeactivateUser = gql`
mutation activateDeactivateUser($userId: String!) {
activateDeactivateUser(userId: $userId)
}
`;

export {
ActivateDeactivateUser,
SendSMSToStudents,
EditHall,
ChangeBedStatus,
Expand Down
15 changes: 15 additions & 0 deletions client/src/graphql/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,22 @@ const GetAdminDashboardStats = gql`
}
`;

//searchStudentAccount

const SearchUserAccount = gql`
query searchStudentAccount($regNumber: String!) {
searchStudentAccount(regNumber: $regNumber) {
email
regNumber
active
name
id
}
}
`;

export {
SearchUserAccount,
GetAdminDashboardStats,
GetSMSCreditAvailable,
GetHostelById,
Expand Down
Loading

0 comments on commit 2f5f6e6

Please sign in to comment.