BACKEND DONE FOR ALL APPS
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 298 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,176 @@
|
||||
/* Global styles for body and background */
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* Container starts hidden */
|
||||
.container {
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Container styling to match your previous design */
|
||||
.left_block, .right_block {
|
||||
background-color: rgba(83, 92, 145, 0.71);
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.left_block {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.right_block {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 2rem;
|
||||
font-size: 2rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Enable scrolling in the departments container */
|
||||
#departments-container {
|
||||
max-height: 50vh; /* Limit the height of the container */
|
||||
overflow-y: auto; /* Enable vertical scrolling */
|
||||
}
|
||||
|
||||
/* Scrollbar styling for departments container */
|
||||
#departments-container::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
#departments-container::-webkit-scrollbar-track {
|
||||
background: #1B1A55;
|
||||
}
|
||||
|
||||
#departments-container::-webkit-scrollbar-thumb {
|
||||
background: #535C91;
|
||||
border: 2px solid #1B1A55;
|
||||
}
|
||||
|
||||
#departments-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
/* Form styling */
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 1rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
padding: 0.8rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #ccc;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button[type="submit"], #createDepartmentButton {
|
||||
background-color: #23BDEE;
|
||||
color: white;
|
||||
padding: 0.8rem;
|
||||
font-size: 1rem;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
button[type="submit"]:hover, #createDepartmentButton:hover {
|
||||
background-color: #1da1cb;
|
||||
}
|
||||
|
||||
/* Department card styling */
|
||||
.department-card {
|
||||
background-color: #ffffff;
|
||||
color: #333;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.department-card button {
|
||||
padding: 0.5rem 1rem;
|
||||
margin-left: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.modify-button {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
background-color: #f44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Modal styles */
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: white;
|
||||
margin: 15% auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: #aaa;
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.close:hover, .close:focus {
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Footer style */
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 9vh 3vh 5vh;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.login-form-title {
|
||||
margin: 0 0 5vh 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-form-title h2 {
|
||||
color: #FFFFFF;
|
||||
font-size: 5vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.login-form hr {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.login-form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 70%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-weight: bold;
|
||||
width: 35%;
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin-top: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
.login-form-footer {
|
||||
margin-top: 3vh;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
button[name="submit"] {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button[name="signup"] {
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ceo-validation-form {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
background: #1B1A55;
|
||||
border-radius: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ceo-validation-form h2 {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.ceo-validation-form p {
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 1rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.form-actions button {
|
||||
padding: 10px 20px;
|
||||
margin: 0 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 80%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#back_button {
|
||||
background-color: #f44336;
|
||||
width: 35%;
|
||||
height: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#submit_button {
|
||||
background-color: #4CAF50;
|
||||
width: 35%;
|
||||
height: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.left_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.left_block_top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.left_block_top h1 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.left_block_top img {
|
||||
margin: 0 3vw 0 5vw;
|
||||
width: 8vw;
|
||||
height: 8vw;
|
||||
}
|
||||
|
||||
.left_block_content {
|
||||
margin: 2rem 0 2rem 0;
|
||||
}
|
||||
|
||||
.left_block_buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0 1rem 0 1rem;
|
||||
width: 15vw;
|
||||
height: 10vh;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
outline: none;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
.left_block_footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.right_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
display: flex;
|
||||
margin: 1rem 2rem 2rem 3rem;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
height: 40vh; /* Fixed height */
|
||||
width: 80%; /* Full width */
|
||||
overflow: auto; /* Enable scrolling */
|
||||
font-size: 1.2rem;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notifications::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.notifications::-webkit-scrollbar-track {
|
||||
background: #1B1A55;
|
||||
}
|
||||
|
||||
.notifications::-webkit-scrollbar-thumb {
|
||||
background: #535C91;
|
||||
border: 2px solid #1B1A55;
|
||||
}
|
||||
|
||||
.notifications::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
|
||||
button[name="logout"] {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 10vw;
|
||||
height: 5vh;
|
||||
background-color: #F44336;
|
||||
}
|
||||
|
||||
button[name="alert"] {
|
||||
margin: 0.7rem;
|
||||
background-color: #F44336;
|
||||
}
|
||||
|
||||
button[name="notification"] {
|
||||
margin: 0.7rem;
|
||||
background-color: #23BDEE;
|
||||
}
|
||||
|
||||
button[name="menu_button"] {
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
}
|
||||
|
||||
/* Disclaimer Modal Styles */
|
||||
#disclaimer-modal {
|
||||
display: none; /* Initially hidden */
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
background-color: #f44336; /* Red color for cancel */
|
||||
}
|
||||
|
||||
.submit-button {
|
||||
background-color: #4CAF50; /* Green color foQQr submit */
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center; /* Center the text for all child elements */
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.profile-form {
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 13vh 3vh 5vh;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.profile-form-title {
|
||||
margin-bottom: 5vh;
|
||||
}
|
||||
|
||||
.profile-form hr {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.profile-form-title h2 {
|
||||
color: #FFFFFF;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
font-size: 5vh;
|
||||
}
|
||||
|
||||
.profile-form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.profile-form-footer {
|
||||
margin-top: 7vh;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 70%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-weight: bold;
|
||||
width: 35%;
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin-top: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
button[name="submit"] {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button[name="login"] {
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
margin-right: 5rem;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 9vh 3vh 5vh;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.login-form-title {
|
||||
margin: 0 0 5vh 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-form-title h2 {
|
||||
color: #FFFFFF;
|
||||
font-size: 5vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.login-form hr {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.login-form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 70%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-weight: bold;
|
||||
width: 35%;
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin-top: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
.login-form-footer {
|
||||
margin-top: 3vh;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
button[name="submit"] {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button[name="signup"] {
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.left_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.left_block_top {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.left_block_top_left {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.left_block_top_left hr {
|
||||
margin: 0 0 1rem 0;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.left_block_top_right {
|
||||
width: 10vw;
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
|
||||
padding: 0 2vh 0 2vh;
|
||||
background-color: #1B1A55;
|
||||
margin: 0 0 0 5vw;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.left_block_content {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: center;
|
||||
margin: 2rem 0 2rem 0;
|
||||
}
|
||||
|
||||
.left_block_buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0 1rem 0 1rem;
|
||||
width: 10vw;
|
||||
height: 5vh;
|
||||
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
outline: none;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
.left_block_footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.right_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 2rem 4rem 2rem 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.choose_user_form_title {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
justify-content: left;
|
||||
align-content: start;
|
||||
}
|
||||
|
||||
.choose_user_form_title hr {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.choose_user_form_content {
|
||||
display: flex;
|
||||
margin: 1rem 7rem 2rem 0.5rem;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
|
||||
height: 20vh; /* Fixed height */
|
||||
width: 100%; /* Full width */
|
||||
overflow: auto; /* Enable scrolling */
|
||||
|
||||
font-size: 1.2rem;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.choose_user_form_content::-webkit-scrollbar {
|
||||
width: 10px; /* Reduced width of the scrollbar by 2px */
|
||||
}
|
||||
|
||||
.choose_user_form_content::-webkit-scrollbar-track {
|
||||
background: #1B1A55; /* Updated track color */
|
||||
}
|
||||
|
||||
.choose_user_form_content::-webkit-scrollbar-thumb {
|
||||
background: #535C91; /* Updated handle color */
|
||||
border: 2px solid #1B1A55; /* Adding a border to effectively reduce the thumb size */
|
||||
}
|
||||
|
||||
.choose_user_form_content::-webkit-scrollbar-thumb:hover {
|
||||
background: #555; /* Updated handle color on hover */
|
||||
}
|
||||
|
||||
button[name="back"] {
|
||||
background-color: #23BDEE;
|
||||
}
|
||||
|
||||
button[name="submit"] {
|
||||
background-color: #F44336;
|
||||
}
|
||||
|
||||
button[name="select_file"] {
|
||||
margin: 0;
|
||||
width: 8vw;
|
||||
background-color: #1B1A55;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.step {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
opacity: 0; /* Make steps invisible by default */
|
||||
visibility: hidden; /* Hide steps by default */
|
||||
transition: opacity 0.5s ease, visibility 0.5s ease; /* Smooth transition */
|
||||
}
|
||||
|
||||
.step.active {
|
||||
opacity: 1; /* Show the active step */
|
||||
visibility: visible; /* Make it visible */
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
line-height: 2.5rem;
|
||||
margin-bottom: 10rem;
|
||||
}
|
||||
|
||||
.signup-form {
|
||||
background-color: #535C91;
|
||||
opacity: 71;
|
||||
padding: 9vh 3vh 5vh;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.9);
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.signup-form-title {
|
||||
margin: 0 0 5vh 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.signup-form-title h2 {
|
||||
color: #FFFFFF;
|
||||
font-size: 5vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.signup-form hr {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.signup-form-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 70%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-weight: bold;
|
||||
width: 35%;
|
||||
font-size: 1rem;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
margin-top: 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
.signup-form-footer {
|
||||
margin-top: 3vh;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
button[name="back"] {
|
||||
background-color: #F44336;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button[name="continue"] {
|
||||
background-color: #2196F3;
|
||||
color: white;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
.fade-in {
|
||||
animation: fadeInAnimation 0.5s ease-in forwards;
|
||||
}
|
||||
|
||||
.fade-out {
|
||||
animation: fadeOutAnimation 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeInAnimation {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOutAnimation {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 6px solid #f3f3f3;
|
||||
border-top: 6px solid #2196F3;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-section p {
|
||||
font-size: 1.5rem;
|
||||
color: white;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/* Global styles for body and background */
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
/* Container starts hidden */
|
||||
.container {
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Container styling to match your previous design */
|
||||
.user-management-container {
|
||||
background-color: rgba(83, 92, 145, 0.71);
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: 10px 10px 15px rgba(0, 0, 0, 0.2);
|
||||
color: white;
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
/* User card styling */
|
||||
.user-card {
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
border-radius: 10px;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
.user-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* User name */
|
||||
.user-name {
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* User department */
|
||||
.user-department {
|
||||
font-size: 1.2rem;
|
||||
color: #555;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Delete button */
|
||||
.delete-button {
|
||||
padding: 10px 20px;
|
||||
background-color: #f44336;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.delete-button:hover {
|
||||
background-color: #d32f2f;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Footer buttons */
|
||||
button {
|
||||
margin: 0 1rem 0 1rem;
|
||||
width: 10vw;
|
||||
height: 5vh;
|
||||
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
|
||||
color: white;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
outline: none;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
filter: brightness(85%);
|
||||
}
|
||||
|
||||
button[name="back"] {
|
||||
background-color: #23BDEE;
|
||||
}
|
||||
|
||||
/* Footer class */
|
||||
.footer {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
/* Scrollable user container */
|
||||
#users-container {
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#users-container::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
#users-container::-webkit-scrollbar-track {
|
||||
background: #1B1A55;
|
||||
}
|
||||
|
||||
#users-container::-webkit-scrollbar-thumb {
|
||||
background: #535C91;
|
||||
border: 2px solid #1B1A55;
|
||||
}
|
||||
|
||||
#users-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #555;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
body, html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: "Roboto", sans-serif;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
|
||||
background-image: url('../assets/background.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
color: #1B1A55;
|
||||
font-size: 4vh;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 6px solid #f3f3f3;
|
||||
border-top: 6px solid #2196F3;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-section p {
|
||||
font-size: 1.5rem;
|
||||
color: white;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<!-- Reuse the same CSS files as UC Not Found -->
|
||||
<link href="../css/welcome.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/helpers.js"></script>
|
||||
<title>Welcome</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>BACKUP FETCHER</h1>
|
||||
</div>
|
||||
<div class="loading-section">
|
||||
<div class="spinner"></div>
|
||||
<p>Backup is not searched, please wait...</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/departments_management.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/departments_management.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
|
||||
<title>Manage Departments</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="left_block">
|
||||
<h1>Departments</h1>
|
||||
<div id="departments-container">
|
||||
<!-- Department divs will be dynamically inserted here -->
|
||||
</div>
|
||||
<div class="footer">
|
||||
<button id="backButton" name="back" type="button">Back</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right_block">
|
||||
<h1>Create New Department</h1>
|
||||
<form id="new-department-form">
|
||||
<label for="departmentName">Department Name:</label>
|
||||
<input type="text" id="departmentName" name="departmentName" placeholder="Enter department name" required>
|
||||
<button type="submit" id="createDepartmentButton">Create Department</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal for modifying department -->
|
||||
<div id="modify-department-modal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span id="close-modal" class="close">×</span>
|
||||
<h2>Modify Department</h2>
|
||||
<label for="new-department-name">New Department Name:</label>
|
||||
<input type="text" id="new-department-name" placeholder="Enter new department name" />
|
||||
<button id="confirm-modify">Modify</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/login.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>DO WE KNOW</h1>
|
||||
<h1>EACH OTHER?</h1>
|
||||
</div>
|
||||
<form class="login-form" id="loginForm">
|
||||
<div class="login-form-title">
|
||||
<h2>Login</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="login-form-content">
|
||||
<input name="email" placeholder="Email" type="email">
|
||||
<input name="password" placeholder="Password" type="password">
|
||||
</div>
|
||||
<div class="login-form-footer">
|
||||
<button id="submit" name="submit" type="submit">Submit</button>
|
||||
<button id="resetPassword" name="resetPassword" type="button">Reset Password</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="../js/login.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/main_menu.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/main_menu.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
|
||||
<title>Main Page</title>
|
||||
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div id="disclaimer-modal" class="overlay">
|
||||
<div class="ceo-validation-form">
|
||||
<h2>Are you sure?</h2>
|
||||
<p>This operation cannot be reverted. Do you want to proceed with resetting the database?</p>
|
||||
<div class="form-actions">
|
||||
<button id="disclaimer-cancel" class="cancel-button">Cancel</button>
|
||||
<button id="disclaimer-submit" class="submit-button">Yes, Reset</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="left_block">
|
||||
<div class="left_block_top">
|
||||
<div>
|
||||
<h1>WELCOME BACK,</h1>
|
||||
<h1 id="username-field"></h1>
|
||||
<h2>Hope you have a productive day!</h2>
|
||||
</div>
|
||||
<img alt="" src="../assets/user_1144760.png">
|
||||
</div>
|
||||
<div class="left_block_content">
|
||||
<div class="left_block_buttons">
|
||||
<button id="change-info" name="menu_button">Change your info</button>
|
||||
<button id="share-file" name="menu_button">Share a file</button>
|
||||
</div>
|
||||
<div class="left_block_buttons">
|
||||
<button id="backup-dir" name="menu_button">Set backup directory</button>
|
||||
<button id="department-dir" name="menu_button">Set department directory</button>
|
||||
<button id="share-dir" name="menu_button">Set share directory</button>
|
||||
</div>
|
||||
<div class="left_block_buttons">
|
||||
<button id="manage-users" name="menu_button">Manage users</button>
|
||||
<button id="manage-departments" name="menu_button">Manage departments</button>
|
||||
</div>
|
||||
<div class="left_block_buttons">
|
||||
<button id="reset-database" name="menu_button">Reset database</button>
|
||||
</div>
|
||||
<div class="left_block_buttons">
|
||||
<button id="restore-backup" name="menu_button">Restore backup</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="left_block_footer">
|
||||
<button id="logout" name="logout">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right_block">
|
||||
<div>
|
||||
<h1>NOTIFICATIONS</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="notifications" id="notifications">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/profile.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/profile.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
|
||||
<title>Profile</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<form class="profile-form" id="profileForm">
|
||||
<div class="profile-form-title">
|
||||
<h2>Profile</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="profile-form-content">
|
||||
<input name="email" placeholder="Email" type="email">
|
||||
<input name="username" placeholder="Username" type="text">
|
||||
<input name="password" placeholder="Password" type="password">
|
||||
</div>
|
||||
<div class="profile-form-footer">
|
||||
<button name="login" type="button">Back</button>
|
||||
<button name="submit" type="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
<link href="../css/reset_password.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
<title>Reset Password</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>RESET</h1>
|
||||
<h1>YOUR PASSWORD</h1>
|
||||
</div>
|
||||
<form class="login-form" id="resetPasswordForm">
|
||||
<div class="login-form-title">
|
||||
<h2>Reset Password</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="login-form-content">
|
||||
<input name="email" placeholder="Email" type="email" required>
|
||||
<input name="newPassword" placeholder="New Password" type="password" required>
|
||||
</div>
|
||||
<div class="login-form-footer">
|
||||
<button id="backToLogin" name="backToLogin" type="button">Back to Login</button>
|
||||
<button id="resetPassword" name="resetPassword" type="submit">Reset Password</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="../js/reset_password.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/share_file.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/share_file.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
|
||||
<title>Share File</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="left_block">
|
||||
<div class="left_block_top">
|
||||
<div class="left_block_top_left">
|
||||
<h1>SHARE A FILE</h1>
|
||||
<hr>
|
||||
<h2>First select the file you want to share</h2>
|
||||
<h2>(can be whatever resource from the system)</h2>
|
||||
</div>
|
||||
<div class="left_block_top_right">
|
||||
<h2 id="fileName"></h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="left_block_content">
|
||||
<button id="selectFile" name="select_file" type="button">Select</button>
|
||||
</div>
|
||||
<div class="left_block_footer">
|
||||
<button id="backButton" name="back" type="button">Back</button>
|
||||
<button id="submitButton" name="submit" type="submit">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
<form class="right_block" id="userDestForm">
|
||||
<div class="choose_user_form_title">
|
||||
<h1>USERS</h1>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="choose_user_form_content">
|
||||
<!-- Insert the users from the database -->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
<link href="../css/sign_up.css" rel="stylesheet">
|
||||
<title>Signup Process</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
|
||||
<div class="container">
|
||||
<!-- Step 1: Profile Information -->
|
||||
<div class="step active" id="step1">
|
||||
<div class="header">
|
||||
<h1>LET US MEET</h1>
|
||||
<h1>EACH OTHER</h1>
|
||||
</div>
|
||||
<form class="signup-form" id="signupForm">
|
||||
<div class="signup-form-title">
|
||||
<h2>Sign Up</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="signup-form-content">
|
||||
<input name="email" placeholder="Email" type="email" required>
|
||||
<input name="name" placeholder="Username" type="text" required>
|
||||
<input name="password" placeholder="Password" type="password" required>
|
||||
</div>
|
||||
<div class="signup-form-footer">
|
||||
<button id="backToLogin" name="back" type="button">Cancel</button>
|
||||
<button id="nextToStep2" name="continue" type="submit">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Step 2: Department Selection -->
|
||||
<div class="step" id="step2" style="display: none;">
|
||||
<div class="header">
|
||||
<h1>TELL ME MORE</h1>
|
||||
<h1>ABOUT</h1>
|
||||
<h1>YOUR WORK</h1>
|
||||
</div>
|
||||
<form class="signup-form" id="departmentForm">
|
||||
<div class="signup-form-title">
|
||||
<h2>Choose your department</h2>
|
||||
<hr>
|
||||
</div>
|
||||
<div class="signup-form-content" id="departmentList">
|
||||
<!-- List of departments will be dynamically inserted here -->
|
||||
</div>
|
||||
<div class="signup-form-footer">
|
||||
<button id="backToStep1" name="back" type="button">Back</button>
|
||||
<button id="submitSignup" name="continue" type="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../js/sign_up.js"></script>
|
||||
<script src="../js/helpers.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/uc_not_found.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/helpers.js"></script>
|
||||
|
||||
<title>UC Not Found</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>SEARCHING FOR THE</h1>
|
||||
<h1>SERVER...</h1>
|
||||
</div>
|
||||
<div class="loading-section">
|
||||
<div class="spinner"></div>
|
||||
<p>Please wait while we try to connect to the server.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<link href="../css/users_management.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/helpers.js"></script>
|
||||
<script src="../js/users_management.js"></script>
|
||||
|
||||
<title>Manage Users</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="user-management-container">
|
||||
<h1>Manage Users</h1>
|
||||
<div id="users-container">
|
||||
<!-- User divs will be dynamically inserted here -->
|
||||
</div>
|
||||
<div class="footer">
|
||||
<button id="backButton" name="back" type="button">Back</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<!-- Reuse the same CSS files as UC Not Found -->
|
||||
<link href="../css/welcome.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/helpers.js"></script>
|
||||
<title>Welcome</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>WELCOME TO THE APP</h1>
|
||||
</div>
|
||||
<div class="loading-section">
|
||||
<div class="spinner"></div>
|
||||
<p>Initializing the application, please wait...</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||||
<link href="../assets/hard-disk.ico" rel="icon" type="image/x-icon">
|
||||
|
||||
<!-- Reuse the same CSS files as UC Not Found -->
|
||||
<link href="../css/welcome.css" rel="stylesheet">
|
||||
<link href="../css/transition.css" rel="stylesheet">
|
||||
|
||||
<script src="../js/helpers.js"></script>
|
||||
<title>Welcome</title>
|
||||
</head>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>BACKUP FETCHER</h1>
|
||||
</div>
|
||||
<div class="loading-section">
|
||||
<div class="spinner"></div>
|
||||
<p>Backup is not searched, please wait...</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,216 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const backButton = document.getElementById('backButton');
|
||||
const form = document.getElementById('new-department-form');
|
||||
const modifyModal = document.getElementById('modify-department-modal');
|
||||
const closeModal = document.getElementById('close-modal');
|
||||
const confirmModifyButton = document.getElementById('confirm-modify');
|
||||
let currentDepartmentId = null;
|
||||
|
||||
// Retrieve operation codes via IPC
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the TCP socket right after fetching the operation codes
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
await window.electronAPI.showAlert('Failed to open socket. Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
let codeGetDepartments = operationCodes.GET_DEPARTMENTS;
|
||||
let codeCreateDepartment = operationCodes.CREATE_DEPARTMENT;
|
||||
let codeModifyDepartment = operationCodes.MODIFY_DEPARTMENT;
|
||||
let codeDeleteDepartment = operationCodes.DELETE_DEPARTMENT;
|
||||
let codeOk = operationCodes.OK;
|
||||
|
||||
// Set up the back button - close the socket before going back
|
||||
backButton.addEventListener('click', async () => {
|
||||
await window.electronAPI.closeUcSocket(); // Close the socket when going back
|
||||
fadeOut('main_menu'); // Navigate to the main menu
|
||||
});
|
||||
|
||||
// Set up the form for creating new departments
|
||||
form.addEventListener('submit', async function (event) {
|
||||
event.preventDefault(); // Prevent the form from refreshing the page
|
||||
const departmentName = document.getElementById('departmentName').value;
|
||||
|
||||
if (departmentName.trim()) {
|
||||
await createDepartment(departmentName); // Call createDepartment function when the form is submitted
|
||||
}
|
||||
});
|
||||
|
||||
// Fetch the departments on page load
|
||||
await fetchDepartments();
|
||||
|
||||
// Fetch departments and render them in the left block
|
||||
async function fetchDepartments() {
|
||||
const departmentsContainer = document.getElementById('departments-container');
|
||||
|
||||
// Send the request to get the departments
|
||||
if (!await window.electronAPI.sendUcMessage(codeGetDepartments)) {
|
||||
await window.electronAPI.showAlert("Failed to send request.");
|
||||
await redirectToMainMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (!response || response.operationCode !== codeOk) {
|
||||
await window.electronAPI.showAlert("Unable to fetch departments.");
|
||||
await redirectToMainMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
departmentsContainer.innerHTML = ''; // Clear any existing data
|
||||
|
||||
const departments = response.metaInfo.departments;
|
||||
|
||||
// Filter out CEO department
|
||||
const filteredDepartments = departments.filter(department => department.name.toLowerCase() !== 'ceo');
|
||||
|
||||
// Check if there are no departments after filtering
|
||||
if (!filteredDepartments.length) {
|
||||
const noDepartmentsMessage = document.createElement('p');
|
||||
noDepartmentsMessage.textContent = 'No departments exist.';
|
||||
noDepartmentsMessage.classList.add('no-departments-message'); // Add a class for styling
|
||||
departmentsContainer.appendChild(noDepartmentsMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over the remaining departments and render them
|
||||
filteredDepartments.forEach(department => {
|
||||
const departmentDiv = document.createElement('div');
|
||||
departmentDiv.classList.add('department-card');
|
||||
|
||||
// Create department name div
|
||||
const nameDiv = document.createElement('div');
|
||||
nameDiv.classList.add('department-name');
|
||||
nameDiv.textContent = department.name;
|
||||
|
||||
// Create modify button
|
||||
const modifyButton = document.createElement('button');
|
||||
modifyButton.textContent = 'Modify';
|
||||
modifyButton.classList.add('modify-button');
|
||||
modifyButton.dataset.departmentId = department.id;
|
||||
|
||||
// Create delete button
|
||||
const deleteButton = document.createElement('button');
|
||||
deleteButton.textContent = 'Delete';
|
||||
deleteButton.classList.add('delete-button');
|
||||
deleteButton.dataset.departmentId = department.id;
|
||||
|
||||
// Append department info and buttons to the department div
|
||||
departmentDiv.appendChild(nameDiv);
|
||||
departmentDiv.appendChild(modifyButton);
|
||||
departmentDiv.appendChild(deleteButton);
|
||||
|
||||
// Append department div to the container
|
||||
departmentsContainer.appendChild(departmentDiv);
|
||||
});
|
||||
|
||||
// Add click event listeners for all dynamically created buttons
|
||||
addEventListenersToButtons();
|
||||
}
|
||||
|
||||
// Add event listeners to dynamically created buttons
|
||||
function addEventListenersToButtons() {
|
||||
const modifyButtons = document.querySelectorAll('.modify-button');
|
||||
const deleteButtons = document.querySelectorAll('.delete-button');
|
||||
|
||||
modifyButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
currentDepartmentId = button.dataset.departmentId;
|
||||
openModifyModal(); // Open the modal when modify button is clicked
|
||||
});
|
||||
});
|
||||
|
||||
deleteButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const departmentId = button.dataset.departmentId;
|
||||
deleteDepartment(departmentId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Open the modify modal
|
||||
function openModifyModal() {
|
||||
modifyModal.style.display = 'block';
|
||||
}
|
||||
|
||||
// Close the modify modal
|
||||
function closeModifyModal() {
|
||||
modifyModal.style.display = 'none';
|
||||
currentDepartmentId = null;
|
||||
}
|
||||
|
||||
// Handle modify modal close event
|
||||
closeModal.addEventListener('click', closeModifyModal);
|
||||
|
||||
// Handle department modification
|
||||
confirmModifyButton.addEventListener('click', async () => {
|
||||
const newDepartmentName = document.getElementById('new-department-name').value;
|
||||
if (newDepartmentName.trim() && currentDepartmentId) {
|
||||
await modifyDepartment(currentDepartmentId, newDepartmentName);
|
||||
closeModifyModal(); // Close the modal after modification
|
||||
}
|
||||
});
|
||||
|
||||
async function modifyDepartment(departmentId, newName) {
|
||||
if (!await window.electronAPI.sendUcMessage(codeModifyDepartment, {
|
||||
departmentId: departmentId,
|
||||
newDepartmentName: newName
|
||||
})) {
|
||||
await window.electronAPI.showAlert('Failed to send modification request.');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
await window.electronAPI.showAlert(`Department modified: ${newName}`);
|
||||
await fetchDepartments(); // Refresh the department list after modification
|
||||
} else {
|
||||
await window.electronAPI.showAlert('Failed to modify the department.');
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteDepartment(departmentId) {
|
||||
const confirmDelete = confirm("Are you sure you want to delete this department?");
|
||||
if (confirmDelete) {
|
||||
if (!await window.electronAPI.sendUcMessage(codeDeleteDepartment, { departmentId })) {
|
||||
await window.electronAPI.showAlert('Failed to send delete request.');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
await window.electronAPI.showAlert("Department deleted successfully.");
|
||||
await fetchDepartments(); // Refresh the department list after deletion
|
||||
} else {
|
||||
await window.electronAPI.showAlert("Failed to delete the department.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to create a new department
|
||||
async function createDepartment(departmentName) {
|
||||
if (!await window.electronAPI.sendUcMessage(codeCreateDepartment, { departmentName })) {
|
||||
await window.electronAPI.showAlert('Failed to send create request.');
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
await window.electronAPI.showAlert(`New department created: ${departmentName}`);
|
||||
await fetchDepartments(); // Refresh the department list
|
||||
} else {
|
||||
await window.electronAPI.showAlert("Failed to create department.");
|
||||
}
|
||||
}
|
||||
|
||||
// Redirect to main menu
|
||||
async function redirectToMainMenu() {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
fadeOut('main_menu');
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
function fadeIn() {
|
||||
document.querySelector('.container').classList.remove('fade-out');
|
||||
document.querySelector('.container').classList.add('fade-in');
|
||||
}
|
||||
|
||||
function fadeOut(destination) {
|
||||
const container = document.querySelector('.container');
|
||||
container.classList.remove('fade-in');
|
||||
container.classList.add('fade-out');
|
||||
|
||||
console.log(destination);
|
||||
setTimeout(() => {}, 5000);
|
||||
|
||||
container.addEventListener('animationend', async () => {
|
||||
try {
|
||||
await window.electronAPI.changeContent(destination);
|
||||
console.log('Navigated to', destination);
|
||||
} catch (error) {
|
||||
console.error('Error navigating:', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForResponse() {
|
||||
return new Promise((resolve) => {
|
||||
const idResponseCheck = setInterval(async () => {
|
||||
const status = await window.electronAPI.hasResponseArrived();
|
||||
if (status) {
|
||||
clearInterval(idResponseCheck);
|
||||
const response = await window.electronAPI.getLastUcResult();
|
||||
resolve(response || null); // Resolve the response or null if not available
|
||||
}
|
||||
}, 100); // Check every 100 milliseconds if the response has arrived
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
const submitButton = document.getElementById('submit');
|
||||
const resetPasswordButton = document.getElementById('resetPassword');
|
||||
|
||||
// Retrieve the operation codes via IPC
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application. Failed to retrieve operation codes.');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeLogin = operationCodes.LOGIN;
|
||||
const codeFindByEmail = operationCodes.FIND_BY_EMAIL;
|
||||
const codeFindKeyByUser = operationCodes.FIND_KEY_BY_USER_ID;
|
||||
const codeOk = operationCodes.OK;
|
||||
|
||||
resetPasswordButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
window.electronAPI.changeContent('reset_password');
|
||||
});
|
||||
|
||||
// Submit button logic (handle login)
|
||||
submitButton.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
console.log('Submit button clicked');
|
||||
|
||||
const form = document.getElementById('loginForm');
|
||||
const formData = new FormData(form);
|
||||
|
||||
const email = formData.get('email');
|
||||
const password = formData.get('password');
|
||||
|
||||
// Open a TCP socket to the stored IP
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
await window.electronAPI.showAlert('Internal error of the application. Unable to open socket.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt login
|
||||
if (!await attemptLogin(email, password)) {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch and store user info
|
||||
if (!await fetchAndStoreUserInfo(email)) {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch user info from local storage
|
||||
const userInfo = await window.electronAPI.readUserConfig('user_info');
|
||||
if (!userInfo) {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
await window.electronAPI.showAlert('Failed to fetch user info.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch and store encryption key
|
||||
if (!await fetchAndStoreEncryptionKey(userInfo.id)) {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the socket and navigate to main menu after success
|
||||
await window.electronAPI.closeUcSocket();
|
||||
await window.electronAPI.changeContent('main_menu');
|
||||
});
|
||||
|
||||
async function attemptLogin(email, password) {
|
||||
const app_type = await window.electronAPI.readUserConfig('app_type');
|
||||
const messageData = { email, password, app_type };
|
||||
|
||||
// Send the login message to the server
|
||||
if (!await window.electronAPI.sendUcMessage(codeLogin, messageData)) {
|
||||
await window.electronAPI.showAlert('Failed to send login request.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for the response using waitForResponse
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
await window.electronAPI.resetApplicationInfo();
|
||||
await window.electronAPI.resetUserConfig();
|
||||
await window.electronAPI.writeUserConfig('app_type', app_type);
|
||||
await window.electronAPI.writeUserConfig('user_info', { email, password });
|
||||
return true;
|
||||
}else if(response && respone.operationCode !== codeOk){
|
||||
await window.electronAPI.showAlert(response.metaInfo.message);
|
||||
return false;
|
||||
}
|
||||
|
||||
await window.electronAPI.showAlert('Invalid login response received.');
|
||||
return false;
|
||||
}
|
||||
|
||||
async function fetchAndStoreUserInfo(userEmail) {
|
||||
if (!await window.electronAPI.sendUcMessage(codeFindByEmail, { email: userEmail })) {
|
||||
await window.electronAPI.showAlert('Failed to send request to fetch user info.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for the response using waitForResponse
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
let userInfo = await window.electronAPI.readUserConfig('user_info');
|
||||
if (!userInfo) {
|
||||
userInfo = {};
|
||||
}
|
||||
|
||||
userInfo.id = response.metaInfo.id;
|
||||
userInfo.departmentId = response.metaInfo.departmentId;
|
||||
userInfo.name = response.metaInfo.name || 'User';
|
||||
|
||||
await window.electronAPI.writeUserConfig('user_info', userInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
await window.electronAPI.showAlert('Failed to fetch user info from server.');
|
||||
return false;
|
||||
}
|
||||
|
||||
async function fetchAndStoreEncryptionKey(userId) {
|
||||
if (!await window.electronAPI.sendUcMessage(codeFindKeyByUser, { userId })) {
|
||||
await window.electronAPI.showAlert('Failed to send request to fetch encryption key.');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for the response using waitForResponse
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
const encryptionKey = {
|
||||
key: response.metaInfo.key.key,
|
||||
iv: response.metaInfo.key.iv,
|
||||
};
|
||||
|
||||
await window.electronAPI.writeUserConfig('encryption_key', encryptionKey);
|
||||
return true;
|
||||
}
|
||||
|
||||
await window.electronAPI.showAlert('Failed to fetch encryption key from server.');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,233 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
setInterval(loadReceivedFiles, 3000); // Call loadReceivedFiles every 3000 ms (3 seconds)
|
||||
|
||||
const backupButton = document.getElementById('backup-dir');
|
||||
const shareButton = document.getElementById('share-dir');
|
||||
const departmentButton = document.getElementById('department-dir');
|
||||
|
||||
const changeInfoButton = document.getElementById('change-info');
|
||||
const shareFileButton = document.getElementById('share-file');
|
||||
|
||||
const manageUsersButton = document.getElementById('manage-users');
|
||||
const manageDepartmentsButton = document.getElementById('manage-departments');
|
||||
|
||||
const resetDatabaseButton = document.getElementById('reset-database');
|
||||
const restoreBackupButton = document.getElementById('restore-backup');
|
||||
|
||||
const logoutButton = document.getElementById('logout');
|
||||
|
||||
const disclaimerModal = document.getElementById('disclaimer-modal');
|
||||
const cancelDisclaimerButton = document.getElementById('disclaimer-cancel');
|
||||
const submitDisclaimerButton = document.getElementById('disclaimer-submit');
|
||||
|
||||
await fetchUserInfo();
|
||||
await checkAndSetAllDirectories();
|
||||
|
||||
backupButton.addEventListener('click', async function () {
|
||||
await setPath('backupDirectory');
|
||||
});
|
||||
|
||||
shareButton.addEventListener('click', async function () {
|
||||
await setPath('shareDirectory');
|
||||
});
|
||||
|
||||
departmentButton.addEventListener('click', async function () {
|
||||
await setPath('departmentDirectory');
|
||||
});
|
||||
|
||||
changeInfoButton.addEventListener('click', function () {
|
||||
fadeOut('profile');
|
||||
});
|
||||
|
||||
shareFileButton.addEventListener('click', function () {
|
||||
fadeOut('share_file');
|
||||
});
|
||||
|
||||
manageUsersButton.addEventListener('click', function () {
|
||||
fadeOut('users_management');
|
||||
});
|
||||
|
||||
manageDepartmentsButton.addEventListener('click', function () {
|
||||
fadeOut('departments_management' +
|
||||
'');
|
||||
});
|
||||
|
||||
resetDatabaseButton.addEventListener('click', function () {
|
||||
disclaimerModal.style.display = 'block'; // Show disclaimer modal
|
||||
});
|
||||
|
||||
cancelDisclaimerButton.addEventListener('click', function () {
|
||||
disclaimerModal.style.display = 'none'; // Hide modal if cancel is clicked
|
||||
});
|
||||
|
||||
submitDisclaimerButton.addEventListener('click', async function () {
|
||||
disclaimerModal.style.display = 'none'; // Hide modal
|
||||
await resetDatabase(); // Perform database reset
|
||||
fadeOut('login'); // Fade out and go back to login
|
||||
});
|
||||
|
||||
logoutButton.addEventListener('click', async function () {
|
||||
fadeOut('login');
|
||||
});
|
||||
|
||||
restoreBackupButton.addEventListener('click', async function () {
|
||||
await restoreBackup();
|
||||
});
|
||||
|
||||
async function restoreBackup() {
|
||||
const backupDirectory = await window.electronAPI.readApplicationInfo('backupDirectory');
|
||||
|
||||
if (backupDirectory && backupDirectory.path) {
|
||||
await window.electronAPI.showAlert('You have already set a backup directory. You cannot restore again.');
|
||||
return;
|
||||
}
|
||||
|
||||
const destinationPath = await window.electronAPI.selectDirectory();
|
||||
if (!destinationPath) return;
|
||||
|
||||
await window.electronAPI.startBackupRetrieval(destinationPath);
|
||||
fadeOut('backup_retrieve');
|
||||
}
|
||||
|
||||
async function checkAndSetAllDirectories() {
|
||||
await attachNotificationButton('backupDirectory', 'Set your backup directory!', 'backup_alert', 'alert');
|
||||
await attachNotificationButton('shareDirectory', 'Set your share directory!', 'share_alert', 'alert');
|
||||
await attachNotificationButton('departmentDirectory', 'Set your department directory!', 'department_alert', 'alert');
|
||||
}
|
||||
|
||||
async function checkPathExistence(pathKey) {
|
||||
return await window.electronAPI.readApplicationInfo(pathKey);
|
||||
}
|
||||
|
||||
async function setPath(pathKey) {
|
||||
const path = await window.electronAPI.selectDirectory();
|
||||
if (path === undefined) return;
|
||||
|
||||
const id = await window.electronAPI.createMemoryEntry()
|
||||
console.log({id, path})
|
||||
await window.electronAPI.writeApplicationInfo(pathKey, {id, path});
|
||||
}
|
||||
|
||||
async function attachNotificationButton(pathKey, buttonText, buttonId, buttonName) {
|
||||
const path = await checkPathExistence(pathKey);
|
||||
if (!path) {
|
||||
const notificationsDiv = document.getElementById('notifications');
|
||||
const button = document.createElement('button');
|
||||
button.id = buttonId;
|
||||
button.name = buttonName;
|
||||
button.textContent = buttonText;
|
||||
button.addEventListener('click', async function () {
|
||||
await setPath(pathKey);
|
||||
button.remove();
|
||||
});
|
||||
notificationsDiv.appendChild(button);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchUserInfo() {
|
||||
const usernameField = document.getElementById('username-field');
|
||||
let userInfo = await window.electronAPI.readUserConfig('user_info');
|
||||
if (userInfo && userInfo.name) {
|
||||
usernameField.textContent = userInfo.name;
|
||||
} else {
|
||||
console.error("Username field is not available in the DOM.");
|
||||
}
|
||||
}
|
||||
|
||||
async function loadReceivedFiles() {
|
||||
const shareDirectoryData = await window.electronAPI.readApplicationInfo('shareDirectory');
|
||||
if (!shareDirectoryData || !shareDirectoryData.id) {
|
||||
console.log('No received files or directory ID found.');
|
||||
return;
|
||||
}
|
||||
|
||||
const directoryId = shareDirectoryData.id;
|
||||
const directoryStructure = await window.electronAPI.readMemoryEntry(directoryId);
|
||||
if (!directoryStructure || !directoryStructure.structure) {
|
||||
console.log('No received files found in the directory structure.');
|
||||
return;
|
||||
}
|
||||
|
||||
const notificationsDiv = document.getElementById('notifications');
|
||||
const existingButtons = Array.from(notificationsDiv.children).map(button => button.getAttribute('data-filepath'));
|
||||
|
||||
Object.keys(directoryStructure.structure).forEach(userName => {
|
||||
const userFiles = directoryStructure.structure[userName];
|
||||
Object.keys(userFiles).forEach(fileName => {
|
||||
const filePath = userFiles[fileName];
|
||||
if (!existingButtons.includes(filePath)) {
|
||||
const button = document.createElement('button');
|
||||
button.setAttribute('data-filepath', filePath);
|
||||
button.name = 'notification';
|
||||
button.textContent = `You received a file "${fileName}" from ${userName}`;
|
||||
button.addEventListener('click', () => handleFileReceivedButtonPressed(filePath, button));
|
||||
notificationsDiv.appendChild(button);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function removeReceivedFile(filePath) {
|
||||
const shareDirectoryData = await window.electronAPI.readApplicationInfo('shareDirectory');
|
||||
if (!shareDirectoryData || !shareDirectoryData.id) {
|
||||
console.log('No directory ID found to update.');
|
||||
return;
|
||||
}
|
||||
|
||||
const directoryId = shareDirectoryData.id;
|
||||
let directoryStructure = await window.electronAPI.readMemoryEntry(directoryId);
|
||||
|
||||
if (directoryStructure && directoryStructure.structure) {
|
||||
for (let userName in directoryStructure.structure) {
|
||||
let userFiles = directoryStructure.structure[userName];
|
||||
if (userFiles[filePath]) {
|
||||
delete userFiles[filePath];
|
||||
if (Object.keys(userFiles).length === 0) {
|
||||
delete directoryStructure.structure[userName];
|
||||
}
|
||||
await window.electronAPI.updateMemoryEntry(directoryId, directoryStructure);
|
||||
console.log(`File ${filePath} removed from memory.`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('No directory structure found in memory to update.');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFileReceivedButtonPressed(filePath, button) {
|
||||
await window.electronAPI.showFileInExplorer(filePath)
|
||||
.then(() => console.log('File explorer opened for: ' + filePath))
|
||||
.catch(error => console.error('Error opening file explorer:', error));
|
||||
|
||||
button.remove();
|
||||
await removeReceivedFile(filePath);
|
||||
}
|
||||
|
||||
async function resetDatabase() {
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application. Failed to retrieve operation codes.');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeOk = operationCodes.OK;
|
||||
const codeResetDatabase = operationCodes.RESET_DATABASE;
|
||||
|
||||
if(!await window.electronAPI.openUcSocket()){
|
||||
await window.electronAPI.showAlert('Internal application error.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the request to reset the database
|
||||
if (!await window.electronAPI.sendUcMessage(codeResetDatabase)) {
|
||||
await window.electronAPI.showAlert('Failed to send reset database request.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for the response
|
||||
await waitForResponse();
|
||||
await window.electronAPI.changeContent('login');
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
const {email, password, name} = await window.electronAPI.readUserConfig('user_info');
|
||||
|
||||
const emailInput = document.querySelector('input[name="email"]');
|
||||
const usernameInput = document.querySelector('input[name="username"]');
|
||||
const passwordInput = document.querySelector('input[name="password"]');
|
||||
|
||||
// Pre-fill form fields with existing data
|
||||
emailInput.value = email;
|
||||
usernameInput.value = name;
|
||||
passwordInput.value = password;
|
||||
|
||||
const backButton = document.querySelector('button[name="login"]');
|
||||
const submitButton = document.querySelector('button[name="submit"]');
|
||||
|
||||
// Get operation codes from the backend
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeModifyUser = operationCodes.MODIFY_USER;
|
||||
const codeOk = operationCodes.OK;
|
||||
|
||||
// Handle the back button click
|
||||
backButton.addEventListener('click', async function () {
|
||||
console.log('Back button clicked!');
|
||||
fadeOut('main_menu');
|
||||
});
|
||||
|
||||
// Handle the submit button click
|
||||
submitButton.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
console.log('Submit button clicked!');
|
||||
|
||||
// Fetch form values
|
||||
const email = emailInput.value;
|
||||
const name = usernameInput.value;
|
||||
const password = passwordInput.value;
|
||||
|
||||
const { id, departmentId, app_type } = await window.electronAPI.readUserConfig('user_info'); // Fetch login data
|
||||
|
||||
// Prepare the data to be sent via the UC socket
|
||||
const messageData = {
|
||||
id: id,
|
||||
name: name,
|
||||
email: email,
|
||||
password: password,
|
||||
departmentId: departmentId,
|
||||
app_type: app_type // Include app_type in the payload
|
||||
};
|
||||
|
||||
// Open UC socket
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
await window.electronAPI.showAlert('Failed to open socket. Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the message to the server using the UC socket
|
||||
if (!await window.electronAPI.sendUcMessage(codeModifyUser, messageData)) {
|
||||
await window.electronAPI.showAlert('Failed to send message.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait for the response
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
console.log('User update successful.');
|
||||
|
||||
// Save updated user info to the userConfig
|
||||
await window.electronAPI.writeUserConfig('user_credentials', { email: email, password: password });
|
||||
await window.electronAPI.writeUserConfig('user_info', {id: id, departmentId: departmentId, name: name});
|
||||
|
||||
// Navigate back to the main menu
|
||||
fadeOut('main_menu');
|
||||
} else {
|
||||
console.log('Error updating user:', response?.metaInfo?.message || 'Unknown error');
|
||||
await window.electronAPI.showAlert(response?.metaInfo?.message || 'Unknown error occurred');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
const backToLoginButton = document.getElementById('backToLogin');
|
||||
const resetPasswordButton = document.getElementById('resetPassword');
|
||||
|
||||
// Retrieve the operation codes via IPC
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeResetPassword = operationCodes.RESET_PASSWORD;
|
||||
const codeOk = operationCodes.OK;
|
||||
|
||||
// Back to login
|
||||
backToLoginButton.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
window.electronAPI.changeContent('login');
|
||||
});
|
||||
|
||||
// Reset password logic
|
||||
resetPasswordButton.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
await window.electronAPI.showAlert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
const form = document.getElementById('resetPasswordForm');
|
||||
const formData = new FormData(form);
|
||||
const email = formData.get('email');
|
||||
const newPassword = formData.get('newPassword');
|
||||
|
||||
// Ensure the email and new password are provided
|
||||
if (!email || !newPassword) {
|
||||
await window.electronAPI.showAlert('Please provide both email and new password.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await attemptResetPassword(email, newPassword)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await window.electronAPI.closeUcSocket();
|
||||
await window.electronAPI.showAlert('Password reset successfully.');
|
||||
window.electronAPI.changeContent('login');
|
||||
});
|
||||
|
||||
async function attemptResetPassword(email, newPassword) {
|
||||
const app_type = await window.electronAPI.readUserConfig('app_type');
|
||||
const messageData = { email, newPassword, app_type };
|
||||
|
||||
if (!await window.electronAPI.sendUcMessage(codeResetPassword, messageData)) return false;
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
return true;
|
||||
} else {
|
||||
await window.electronAPI.showAlert(response?.metaInfo?.message || 'Error resetting password.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
let user_info = {};
|
||||
let pathToFile = '';
|
||||
|
||||
user_info = await window.electronAPI.readUserConfig('user_info');
|
||||
if (!user_info) {
|
||||
await window.electronAPI.showAlert('No user_info entry found.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Function to update the file name display
|
||||
function updateFileName() {
|
||||
const fileNameElement = document.getElementById('fileName');
|
||||
if (!fileNameElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pathToFile.trim() === '') {
|
||||
fileNameElement.textContent = 'No file chosen';
|
||||
} else {
|
||||
fileNameElement.textContent = pathToFile.split('\\').pop().split('/').pop();
|
||||
}
|
||||
}
|
||||
|
||||
updateFileName();
|
||||
|
||||
// Fetch user information from applicationInfo and create checkboxes for selecting users
|
||||
async function fetchUsersAndCreateCheckboxes() {
|
||||
const usersInfoId = await window.electronAPI.readApplicationInfo('active_users_info');
|
||||
if (!usersInfoId) {
|
||||
await window.electronAPI.showAlert('Internal error.');
|
||||
return;
|
||||
}
|
||||
|
||||
const usersInfo = await window.electronAPI.readMemoryEntry(usersInfoId);
|
||||
if (!usersInfo || usersInfo.length === 0) {
|
||||
await window.electronAPI.showAlert('No active users found.');
|
||||
await window.electronAPI.changeContent('main_menu');
|
||||
return;
|
||||
}
|
||||
|
||||
const usersDiv = document.querySelector('.choose_user_form_content');
|
||||
usersDiv.innerHTML = '';
|
||||
usersInfo.forEach(user => {
|
||||
const checkbox = document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.name = 'users';
|
||||
checkbox.value = user.ip; // Store user's IP in the value
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.innerHTML = `${user.user_info.name}`; // Display user's name
|
||||
label.insertBefore(checkbox, label.firstChild);
|
||||
|
||||
usersDiv.appendChild(label);
|
||||
});
|
||||
}
|
||||
|
||||
// Event listener for selecting the file
|
||||
document.getElementById('selectFile').addEventListener('click', async function () {
|
||||
try {
|
||||
pathToFile = await window.electronAPI.selectFile();
|
||||
updateFileName();
|
||||
} catch (error) {
|
||||
console.error('Error opening file dialog:', error);
|
||||
}
|
||||
});
|
||||
|
||||
// Event listener for back button to navigate to main menu
|
||||
document.getElementById('backButton').addEventListener('click', function () {
|
||||
fadeOut('main_menu');
|
||||
});
|
||||
|
||||
// Submit button logic to queue file send tasks and then navigate to main_menu.html
|
||||
document.getElementById('submitButton').addEventListener('click', async function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Check if a file was chosen
|
||||
if (!pathToFile.trim()) {
|
||||
await window.electronAPI.showAlert('File not chosen!');
|
||||
return;
|
||||
}
|
||||
|
||||
const form = document.getElementById('userDestForm');
|
||||
const checkboxes = form.querySelectorAll('input[name="users"]');
|
||||
const selectedUserIps = Array.from(checkboxes)
|
||||
.filter(checkbox => checkbox.checked)
|
||||
.map(checkbox => checkbox.value); // Get IP of the selected users
|
||||
|
||||
if (!selectedUserIps.length) {
|
||||
await window.electronAPI.showAlert('No user selected!');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const selectedUserIp of selectedUserIps) {
|
||||
try {
|
||||
// Add task to send file to the queue
|
||||
const task = {
|
||||
ip: selectedUserIp, // Destination IP for the file
|
||||
path: pathToFile, // File path
|
||||
userName: user_info.name // Sender's username from userConfig
|
||||
};
|
||||
await window.electronAPI.addTaskToSendFileQueue(task);
|
||||
|
||||
console.log(`Task added to send file to IP ${selectedUserIp}`);
|
||||
} catch (error) {
|
||||
console.error(`Error processing IP ${selectedUserIp}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Navigate back to the main menu after all tasks are queued
|
||||
fadeOut('main_menu'); // Navigate to the main menu
|
||||
});
|
||||
|
||||
// Fetch users and create checkboxes every 5 seconds (in case of updates)
|
||||
setInterval(fetchUsersAndCreateCheckboxes, 5000);
|
||||
|
||||
fetchUsersAndCreateCheckboxes().then(() => console.log('User checkboxes rendered'));
|
||||
});
|
||||
@@ -0,0 +1,134 @@
|
||||
document.addEventListener('DOMContentLoaded', async function () {
|
||||
const nextToStep2Button = document.getElementById('nextToStep2');
|
||||
const backToStep1Button = document.getElementById('backToStep1');
|
||||
const submitSignupButton = document.getElementById('submitSignup');
|
||||
const backToLogin = document.getElementById('backToLogin');
|
||||
|
||||
const step1 = document.getElementById('step1');
|
||||
const step2 = document.getElementById('step2');
|
||||
|
||||
// This object will hold the user data
|
||||
let userData = {
|
||||
email: null,
|
||||
name: null,
|
||||
password: null,
|
||||
app_type: null,
|
||||
departmentId: null
|
||||
};
|
||||
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
alert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
await window.electronAPI.showAlert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
const codeGetDepartments = operationCodes.GET_DEPARTMENTS;
|
||||
const codeSignUp = operationCodes.SIGN_UP;
|
||||
const codeOk = operationCodes.OK;
|
||||
|
||||
let departments = await getDepartments();
|
||||
if (departments === null) {
|
||||
await window.electronAPI.showAlert('Failed to fetch departments.');
|
||||
return;
|
||||
}
|
||||
console.log(departments);
|
||||
|
||||
// Handle form submission for Step 1 (Profile Information)
|
||||
nextToStep2Button.addEventListener('click', async function (e) {
|
||||
e.preventDefault(); // Prevent the default form submission
|
||||
|
||||
// Collect data from Step 1 inputs
|
||||
userData.email = document.querySelector('input[name="email"]').value;
|
||||
userData.name = document.querySelector('input[name="name"]').value;
|
||||
userData.password = document.querySelector('input[name="password"]').value;
|
||||
userData.app_type = await window.electronAPI.readUserConfig('app_type');
|
||||
|
||||
// Move to Step 2
|
||||
const departmentList = document.getElementById('departmentList');
|
||||
departmentList.innerHTML = ''; // Clear existing departments
|
||||
|
||||
// Populate department list
|
||||
departments.forEach(department => {
|
||||
if (department.name !== 'CEO' && department.name !== 'ADMIN') {
|
||||
const label = document.createElement('label');
|
||||
label.innerHTML = `
|
||||
<input type="radio" name="dept" value="${department.id}">
|
||||
${department.name}
|
||||
`;
|
||||
departmentList.appendChild(label);
|
||||
}
|
||||
});
|
||||
|
||||
switchStep(step1, step2);
|
||||
});
|
||||
|
||||
// Handle form submission for Step 2 (Department Selection)
|
||||
submitSignupButton.addEventListener('click', async function (e) {
|
||||
e.preventDefault(); // Prevent form from being submitted in the usual way
|
||||
|
||||
// Get the selected department
|
||||
userData.departmentId = document.querySelector('input[name="dept"]:checked')?.value;
|
||||
if (!userData.departmentId) {
|
||||
await window.electronAPI.showAlert('Please select a department.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await attemptSignUp()) {
|
||||
switchStep(step2, step1);
|
||||
return;
|
||||
}
|
||||
|
||||
await window.electronAPI.showAlert('Signup successful!');
|
||||
await window.electronAPI.changeContent('login');
|
||||
});
|
||||
|
||||
// Back to Step 1 from Step 2
|
||||
backToStep1Button.addEventListener('click', function () {
|
||||
switchStep(step2, step1);
|
||||
});
|
||||
|
||||
// Back to login
|
||||
backToLogin.addEventListener('click', async function (e) {
|
||||
e.preventDefault();
|
||||
await window.electronAPI.closeUcSocket();
|
||||
await window.electronAPI.changeContent('login');
|
||||
});
|
||||
|
||||
async function getDepartments() {
|
||||
if (!await window.electronAPI.sendUcMessage(codeGetDepartments)) return null;
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
return response.metaInfo.departments;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function attemptSignUp() {
|
||||
if (!await window.electronAPI.sendUcMessage(codeSignUp, userData)) return false;
|
||||
|
||||
const response = await waitForResponse();
|
||||
if (response && response.operationCode === codeOk) {
|
||||
return true;
|
||||
}
|
||||
await window.electronAPI.showAlert(`Signup failed: ${response?.metaInfo?.message || 'Unknown error'}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Function to switch between steps
|
||||
function switchStep(fromStep, toStep) {
|
||||
fromStep.classList.remove('active'); // Fade out the current step
|
||||
setTimeout(() => {
|
||||
fromStep.style.display = 'none'; // Hide the current step after transition
|
||||
toStep.style.display = 'flex'; // Ensure display is flex for the next step
|
||||
setTimeout(() => {
|
||||
toStep.classList.add('active'); // Fade in the next step
|
||||
}, 20); // Small delay to allow display change before applying opacity
|
||||
}, 500); // Transition duration (0.5s)
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,142 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const backButton = document.getElementById('backButton');
|
||||
backButton.addEventListener('click', async () => {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
fadeOut('main_menu');
|
||||
});
|
||||
|
||||
const operationCodes = await window.electronAPI.getOperationsCodes();
|
||||
if (!operationCodes) {
|
||||
alert('Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the TCP socket right after fetching the operation codes
|
||||
if (!await window.electronAPI.openUcSocket()) {
|
||||
alert('Failed to open socket. Internal error of the application.');
|
||||
return;
|
||||
}
|
||||
|
||||
let codeGetDepartments = operationCodes.GET_DEPARTMENTS;
|
||||
let codeGetUsers = operationCodes.GET_USERS;
|
||||
let codeDeleteUser = operationCodes.DELETE_USER;
|
||||
let codeOk = operationCodes.OK;
|
||||
|
||||
// Fetch both users and departments, then display the users with their departments
|
||||
async function fetchData() {
|
||||
try {
|
||||
// Fetch departments
|
||||
const departmentsResponse = await fetchDepartments();
|
||||
if (!departmentsResponse || departmentsResponse.operationCode !== codeOk) {
|
||||
alert('Failed to fetch departments. Redirecting to main menu...');
|
||||
await redirectToMainMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
const departments = departmentsResponse.metaInfo.departments;
|
||||
|
||||
// Fetch users
|
||||
const usersResponse = await fetchUsers();
|
||||
if (!usersResponse || usersResponse.operationCode !== codeOk) {
|
||||
alert('Failed to fetch users. Redirecting to main menu...');
|
||||
await redirectToMainMenu();
|
||||
return;
|
||||
}
|
||||
|
||||
const users = usersResponse.metaInfo.users;
|
||||
|
||||
const usersContainer = document.getElementById('users-container');
|
||||
usersContainer.innerHTML = ''; // Clear the container
|
||||
|
||||
// Filter out users in the CEO department
|
||||
const ceoDepartment = departments.find(dept => dept.name.toLowerCase() === 'ceo');
|
||||
const filteredUsers = users.filter(user => user.departmentId !== ceoDepartment.id);
|
||||
|
||||
// Check if there are no users after filtering
|
||||
if (!filteredUsers.length) {
|
||||
const noUsersMessage = document.createElement('p');
|
||||
noUsersMessage.textContent = 'No users exist.';
|
||||
noUsersMessage.classList.add('no-users-message'); // Add a class for styling
|
||||
usersContainer.appendChild(noUsersMessage);
|
||||
fadeIn(); // Fade in the container when the message is loaded
|
||||
return;
|
||||
}
|
||||
|
||||
// Render users if there are any
|
||||
filteredUsers.forEach(user => {
|
||||
const userDiv = document.createElement('div');
|
||||
userDiv.classList.add('user-card');
|
||||
|
||||
// Create user name div
|
||||
const nameDiv = document.createElement('div');
|
||||
nameDiv.classList.add('user-name');
|
||||
nameDiv.textContent = user.name;
|
||||
|
||||
// Find the user's department name using departmentId
|
||||
const department = departments.find(dept => dept.id === user.departmentId);
|
||||
const departmentName = department ? department.name : 'Unknown';
|
||||
|
||||
// Create department div
|
||||
const departmentDiv = document.createElement('div');
|
||||
departmentDiv.classList.add('user-department');
|
||||
departmentDiv.textContent = `Department: ${departmentName}`;
|
||||
|
||||
// Create delete button
|
||||
const deleteButton = document.createElement('button');
|
||||
deleteButton.textContent = 'Delete';
|
||||
deleteButton.classList.add('delete-button');
|
||||
deleteButton.onclick = () => deleteUser(user.id);
|
||||
|
||||
// Append user info and delete button to the user div
|
||||
userDiv.appendChild(nameDiv);
|
||||
userDiv.appendChild(departmentDiv);
|
||||
userDiv.appendChild(deleteButton);
|
||||
|
||||
// Append user div to the container
|
||||
usersContainer.appendChild(userDiv);
|
||||
});
|
||||
|
||||
fadeIn(); // Fade in the container when the users are loaded
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
alert('An unexpected error occurred. Redirecting to main menu...');
|
||||
await redirectToMainMenu();
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchDepartments() {
|
||||
// Send the request to get departments
|
||||
if (!await window.electronAPI.sendUcMessage(codeGetDepartments)) {
|
||||
return null;
|
||||
}
|
||||
return await waitForResponse();
|
||||
}
|
||||
|
||||
async function fetchUsers() {
|
||||
// Send the request to get users
|
||||
if (!await window.electronAPI.sendUcMessage(codeGetUsers)) {
|
||||
return null;
|
||||
}
|
||||
return await waitForResponse();
|
||||
}
|
||||
|
||||
async function deleteUser(userId) {
|
||||
// Find the index of the user in the dummy data
|
||||
const userIndex = dummyUsers.findIndex(user => user.id === userId);
|
||||
|
||||
// If user found, remove it from the array
|
||||
if (userIndex !== -1) {
|
||||
dummyUsers.splice(userIndex, 1);
|
||||
alert(`User with ID ${userId} deleted.`);
|
||||
await fetchData(); // Refresh the users after deleting
|
||||
}
|
||||
}
|
||||
|
||||
async function redirectToMainMenu() {
|
||||
await window.electronAPI.closeUcSocket();
|
||||
fadeOut('main_menu');
|
||||
}
|
||||
|
||||
// Fetch data on page load
|
||||
await fetchData();
|
||||
});
|
||||
Reference in New Issue
Block a user