BACKEND DONE FOR ALL APPS

This commit is contained in:
andrei-mihnea-cerbu
2024-10-21 18:34:45 +03:00
parent 4157ca9e7d
commit ab1eaec413
349 changed files with 17199 additions and 14015 deletions
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

+110
View File
@@ -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;
}
+232
View File
@@ -0,0 +1,232 @@
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;
}
.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; /* Reduced width of the scrollbar by 2px */
}
.notifications::-webkit-scrollbar-track {
background: #1B1A55; /* Updated track color */
}
.notifications::-webkit-scrollbar-thumb {
background: #535C91; /* Updated handle color */
border: 2px solid #1B1A55; /* Adding a border to effectively reduce the thumb size */
}
.notifications::-webkit-scrollbar-thumb:hover {
background: #555; /* Updated handle color on hover */
}
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;
}
+110
View File
@@ -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;
}
+110
View File
@@ -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;
}
+191
View File
@@ -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;
}
+117
View File
@@ -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;
}
+25
View File
@@ -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;
}
}
+59
View File
@@ -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;
}
+59
View File
@@ -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;
}
+26
View File
@@ -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>
+38
View File
@@ -0,0 +1,38 @@
<!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="signup" name="submit" type="button">Sign Up</button>
<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>
+57
View File
@@ -0,0 +1,57 @@
<!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 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="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>
+35
View File
@@ -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>
+36
View File
@@ -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>
+49
View File
@@ -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>
+63
View File
@@ -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>
+27
View File
@@ -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>
+26
View File
@@ -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>
+36
View File
@@ -0,0 +1,36 @@
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
});
}
+150
View File
@@ -0,0 +1,150 @@
document.addEventListener('DOMContentLoaded', async function () {
const submitButton = document.getElementById('submit');
const signUpButton = document.getElementById('signup');
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;
signUpButton.addEventListener('click', function (e) {
e.preventDefault();
window.electronAPI.changeContent('sign_up');
});
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;
}
});
+216
View File
@@ -0,0 +1,216 @@
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 logoutButton = document.getElementById('logout');
const restoreBackupButton = document.getElementById('restore-backup');
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');
});
logoutButton.addEventListener('click', async function () {
fadeOut('login');
});
// Add event listener for the restore backup button
restoreBackupButton.addEventListener('click', async function () {
await restoreBackup();
});
});
async function restoreBackup() {
const backupDirectory = await window.electronAPI.readApplicationInfo('backupDirectory');
if (backupDirectory && backupDirectory.path) {
// If backup directory is already set, display an alert
await window.electronAPI.showAlert('You have already set a backup directory. You cannot restore again.');
return;
}
// Prompt the user to choose the destination for the restored backup
const destinationPath = await window.electronAPI.selectDirectory();
if (!destinationPath) {
return; // User canceled the directory selection
}
// Call the IPC method to initiate the backup retrieval process
await window.electronAPI.startBackupRetrieval(destinationPath);
// Switch the content to the 'backup_retrieve' page
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(); // Remove button after setting the path
});
notificationsDiv.appendChild(button);
}
}
async function fetchUserInfo() {
const usernameField = document.getElementById('username-field');
// Read the user credentials from the userConfig
let userInfo = await window.electronAPI.readUserConfig('user_info');
if (userInfo && userInfo.name) {
usernameField.textContent = userInfo.name;
return;
}
// Update the greeting with the fetched user's name
if (usernameField) {
usernameField.textContent = userInfo.name; // Update the h1 with the user's name
} else {
console.error("Username field is not available in the DOM.");
}
}
async function loadReceivedFiles() {
// Read the shareDirectory from applicationInfo
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;
// Fetch the directory structure (JSON objects with user names and file paths)
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'));
// Iterate over each user and their files in the structure
Object.keys(directoryStructure.structure).forEach(userName => {
const userFiles = directoryStructure.structure[userName];
// Iterate over each file of the user
Object.keys(userFiles).forEach(fileName => {
const filePath = userFiles[fileName];
// Check if a button for this file path already exists
if (!existingButtons.includes(filePath)) {
const button = document.createElement('button');
button.setAttribute('data-filepath', filePath); // Set a custom attribute to track the file path
button.name = 'notification';
button.textContent = `You received a file "${fileName}" from ${userName}`; // Display the userName and file name
button.addEventListener('click', () => handleFileReceivedButtonPressed(filePath, button));
notificationsDiv.appendChild(button);
}
});
});
}
async function removeReceivedFile(filePath) {
// Read the shareDirectory from applicationInfo
const shareDirectoryData = await window.electronAPI.readApplicationInfo('shareDirectory');
if (!shareDirectoryData || !shareDirectoryData.id) {
console.log('No directory ID found to update.');
return;
}
const directoryId = shareDirectoryData.id;
// Fetch the directory structure
let directoryStructure = await window.electronAPI.readMemoryEntry(directoryId);
if (directoryStructure && directoryStructure.structure) {
// Iterate over each user and their files
for (let userName in directoryStructure.structure) {
let userFiles = directoryStructure.structure[userName];
// Check if the file exists and remove it
if (userFiles[filePath]) {
delete userFiles[filePath];
// Remove the user if no more files are left
if (Object.keys(userFiles).length === 0) {
delete directoryStructure.structure[userName];
}
// Update the directory structure in memory
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) {
console.log('Notification button clicked!');
// Open the file in the file explorer
await window.electronAPI.showFileInExplorer(filePath)
.then(() => console.log('File explorer opened for: ' + filePath))
.catch(error => console.error('Error opening file explorer:', error));
// Remove the button after opening the file
button.remove();
// Remove the file from memory
await removeReceivedFile(filePath);
}
+82
View File
@@ -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');
}
});
});
+63
View File
@@ -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;
}
}
});
+118
View File
@@ -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'));
});
+134
View File
@@ -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)
}
});