Feature, UI update and bug fixes

-- added option to apply for internship
-- code refactoring and optimizations
This commit is contained in:
sairaj mote 2022-09-11 02:37:08 +05:30
parent 6c08034f4b
commit fccc29a8ba
4 changed files with 577 additions and 391 deletions

View File

@ -139,6 +139,9 @@ button:not(:disabled),
border: solid rgba(var(--text-color), 0.5) 0.1rem;
background-color: rgba(var(--foreground-color), 1);
}
.button--transparent {
background-color: transparent;
}
.cta {
text-transform: uppercase;
@ -556,6 +559,12 @@ ul {
font-weight: 500;
}
.card {
background-color: rgba(var(--text-color), 0.06);
border-radius: 0.5rem;
padding: max(1rem, 3vw);
}
.ripple {
height: 8rem;
width: 8rem;
@ -603,6 +612,18 @@ ul {
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
}
.multi-state-button {
display: grid;
text-align: center;
align-items: center;
}
.multi-state-button > * {
grid-area: 1/1/2/2;
}
.multi-state-button button {
z-index: 1;
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
@ -733,6 +754,27 @@ ul {
width: 22rem;
}
#application_card {
position: relative;
overflow: hidden;
background-color: rgba(var(--foreground-color), 1);
border: solid thin rgba(var(--text-color), 0.1);
padding: 0;
}
#application_card > div:first-of-type {
padding: max(1rem, 3vw);
z-index: 2;
width: calc(100% - 4rem);
background: linear-gradient(90deg, rgba(var(--foreground-color), 1) 0%, rgba(var(--foreground-color), 0) 100%);
}
#application_card .illustration {
position: absolute;
height: 100%;
right: 0;
width: auto;
margin: 0 -1.5rem -1.5rem 0;
}
.task {
display: grid;
grid-template-columns: auto 1fr;
@ -821,6 +863,7 @@ ul {
-webkit-animation: fadein 0.3s;
animation: fadein 0.3s;
grid-template-columns: minmax(0, 1fr);
height: 100%;
}
@-webkit-keyframes fadein {
@ -903,7 +946,7 @@ ul {
width: 2.6rem;
justify-content: center;
align-items: center;
border-radius: 40%;
border-radius: 50%;
color: white;
font-weight: 500;
font-size: 1rem;
@ -1007,22 +1050,11 @@ ul {
}
#intern_info__initials {
margin-bottom: 1rem;
position: relative;
height: 3rem;
width: 3rem;
font-size: 1.3rem;
}
#intern_info__initials::before {
content: "";
position: absolute;
background-color: inherit;
border-radius: inherit;
height: calc(100% + 1.5rem);
width: calc(100% + 1.5rem);
opacity: 0.3;
z-index: -1;
}
#intern_info__name {
font-size: 1.5rem;
@ -1317,8 +1349,12 @@ ul {
box-shadow: 0 0.5rem 0.8rem rgba(0, 0, 0, 0.3);
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
color: rgba(var(--background-color), 1);
margin: 1rem;
}
.fab .icon {
fill: rgba(var(--background-color), 1);
}
#update_of_project {
color: rgba(var(--text-color), 0.8);
@ -1344,34 +1380,25 @@ ul {
.task-card {
display: grid;
gap: 0.5rem;
padding: 1rem;
border-radius: 0.5rem;
grid-template-columns: minmax(0, 1fr);
background-color: rgba(var(--foreground-color), 1);
}
.task__header {
display: grid;
gap: 0 0.5rem;
align-items: flex-start;
grid-template-columns: 1fr auto;
grid-template-areas: ". send-button" ". send-button";
}
.task__project-title {
font-size: 0.9rem;
font-weight: 500;
border-radius: 0.3rem;
font-size: 0.8rem;
margin: 0 -0.5em;
margin-bottom: 0.5rem;
border-radius: 1rem;
padding: 0.3rem 0.5rem;
justify-self: flex-start;
margin-bottom: 0.5rem !important;
color: rgba(var(--text-color), 0.8);
background-color: rgba(var(--text-color), 0.06);
}
.task__title {
font-size: 1.3rem;
margin-bottom: 1rem !important;
font-size: 1.1rem;
}
.task__description {
@ -1379,12 +1406,15 @@ ul {
overflow-wrap: break-word;
white-space: pre-line;
color: rgba(var(--text-color), 0.8);
font-size: 0.9rem;
margin-top: 0.2rem;
}
.send-update-button {
grid-area: send-button;
--padding: 0.6rem 0.8rem;
padding: 0.6rem 0.8rem;
color: var(--accent-color);
background-color: rgba(var(--text-color), 0.04);
margin-left: auto;
}
.send-update-button .icon {
fill: var(--accent-color);
@ -1511,6 +1541,10 @@ input[type=date]:focus {
transition: width 0.3s;
}
#settings_page {
align-items: flex-start;
}
#username {
margin-top: 1.5rem;
margin-bottom: 0.5rem;
@ -1571,8 +1605,17 @@ input[type=date]:focus {
.project-card--active {
background-color: rgba(var(--text-color), 0.1);
}
.page {
background-color: rgba(var(--foreground-color), 1);
.project-card--active::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto 0;
width: 0.2rem;
height: 1.5em;
background-color: var(--accent-color);
border-radius: 0 0.2rem 0.2rem 0;
}
#sign_in {
width: 24rem;
@ -1655,39 +1698,17 @@ input[type=date]:focus {
grid-area: updates;
}
#all_interns_list {
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
gap: 0.5rem;
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
}
#all_interns_list .intern-card {
gap: 1.5rem 0.5rem;
padding: 1.5rem;
grid-template-columns: 1fr;
gap: 1rem;
border-radius: 0.5rem;
background-color: rgba(var(--foreground-color), 1);
}
#all_interns_list .intern-card__initials {
position: relative;
grid-column: 1/3;
z-index: 1;
}
#all_interns_list .intern-card__initials::after {
content: "";
position: absolute;
background-color: inherit;
border-radius: inherit;
height: calc(100% + 1rem);
width: calc(100% + 1rem);
opacity: 0.3;
z-index: -1;
background-color: rgba(var(--text-color), 0.06);
}
#intern_list_popup {
--height: 80vh;
}
#settings_page {
height: 100%;
align-items: flex-start;
padding: 2rem;
}
}
@media only screen and (min-width: 1280px) {
#main_page {
@ -1717,18 +1738,16 @@ input[type=date]:focus {
background: rgba(var(--text-color), 0.5);
}
.interact:hover {
background: linear-gradient(rgba(var(--text-color), 0.06), rgba(var(--text-color), 0.06)), rgba(var(--foreground-color), 1);
background-color: rgba(var(--text-color), 0.06);
}
.send-update-button,
.task-option,
.task-option,
.apply-button {
opacity: 0;
transition: opacity 0.3s;
}
.task-list-item:hover .task-option,
.task-option:focus-within,
.task:hover .apply-button,
.task-card:hover .send-update-button {
.task:hover .apply-button {
opacity: 1;
}
}

2
css/main.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -134,6 +134,9 @@ button,
border: solid rgba(var(--text-color), 0.5) 0.1rem;
background-color: rgba(var(--foreground-color), 1);
}
&--transparent {
background-color: transparent;
}
}
.cta {
@ -552,6 +555,12 @@ ul {
font-weight: 500;
}
.card {
background-color: rgba(var(--text-color), 0.06);
border-radius: 0.5rem;
padding: max(1rem, 3vw);
}
.ripple {
height: 8rem;
width: 8rem;
@ -603,6 +612,19 @@ ul {
box-shadow: 0 0 0 0.1rem var(--accent-color) inset;
}
}
.multi-state-button {
display: grid;
text-align: center;
align-items: center;
& > * {
grid-area: 1/1/2/2;
}
button {
z-index: 1;
}
}
#confirmation_popup,
#prompt_popup {
@ -740,6 +762,33 @@ ul {
width: 22rem;
}
#application_card {
position: relative;
overflow: hidden;
background-color: rgba(var(--foreground-color), 1);
border: solid thin rgba(var(--text-color), 0.1);
padding: 0;
& > div {
&:first-of-type {
padding: max(1rem, 3vw);
z-index: 2;
width: calc(100% - 4rem);
background: linear-gradient(
90deg,
rgba(var(--foreground-color), 1) 0%,
rgba(var(--foreground-color), 0) 100%
);
}
}
.illustration {
position: absolute;
height: 100%;
right: 0;
width: auto;
margin: 0 -1.5rem -1.5rem 0;
}
}
.task {
display: grid;
grid-template-columns: auto 1fr;
@ -829,6 +878,7 @@ ul {
padding: 1rem;
animation: fadein 0.3s;
grid-template-columns: minmax(0, 1fr);
height: 100%;
}
@keyframes fadein {
0% {
@ -900,7 +950,7 @@ ul {
width: 2.6rem;
justify-content: center;
align-items: center;
border-radius: 40%;
border-radius: 50%;
color: white;
font-weight: 500;
font-size: 1rem;
@ -1009,21 +1059,10 @@ ul {
}
}
#intern_info__initials {
margin-bottom: 1rem;
position: relative;
height: 3rem;
width: 3rem;
font-size: 1.3rem;
&::before {
content: "";
position: absolute;
background-color: inherit;
border-radius: inherit;
height: calc(100% + 1.5rem);
width: calc(100% + 1.5rem);
opacity: 0.3;
z-index: -1;
}
}
#intern_info__name {
font-size: 1.5rem;
@ -1312,7 +1351,11 @@ ul {
box-shadow: 0 0.5rem 0.8rem rgba(0, 0, 0, 0.3);
transition: transform 0.3s;
-webkit-tap-highlight-color: transparent;
color: rgba(var(--background-color), 1);
margin: 1rem;
.icon {
fill: rgba(var(--background-color), 1);
}
}
#update_of_project {
@ -1341,48 +1384,39 @@ ul {
.task-card {
display: grid;
gap: 0.5rem;
padding: 1rem;
border-radius: 0.5rem;
grid-template-columns: minmax(0, 1fr);
background-color: rgba(var(--foreground-color), 1);
}
.task__header {
display: grid;
gap: 0 0.5rem;
align-items: flex-start;
grid-template-columns: 1fr auto;
grid-template-areas: ". send-button" ". send-button";
}
.task__project-title {
font-size: 0.9rem;
font-weight: 500;
border-radius: 0.3rem;
font-size: 0.8rem;
margin: 0 -0.5em;
margin-bottom: 0.5rem;
border-radius: 1rem;
padding: 0.3rem 0.5rem;
justify-self: flex-start;
margin-bottom: 0.5rem !important;
color: rgba(var(--text-color), 0.8);
background-color: rgba(var(--text-color), 0.06);
}
.task__title {
font-size: 1.3rem;
margin-bottom: 1rem !important;
font-size: 1.1rem;
}
.task__description {
word-wrap: break-word;
overflow-wrap: break-word;
white-space: pre-line;
color: rgba(var(--text-color), 0.8);
font-size: 0.9rem;
margin-top: 0.2rem;
}
.send-update-button {
grid-area: send-button;
--padding: 0.6rem 0.8rem;
padding: 0.6rem 0.8rem;
color: var(--accent-color);
background-color: rgba(var(--text-color), 0.04);
margin-left: auto;
.icon {
fill: var(--accent-color);
}
@ -1500,6 +1534,9 @@ input[type="date"] {
transition: width 0.3s;
}
}
#settings_page {
align-items: flex-start;
}
#username {
margin-top: 1.5rem;
margin-bottom: 0.5rem;
@ -1566,11 +1603,20 @@ input[type="date"] {
.project-card {
&--active {
background-color: rgba(var(--text-color), 0.1);
&::before {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto 0;
width: 0.2rem;
height: 1.5em;
background-color: var(--accent-color);
border-radius: 0 0.2rem 0.2rem 0;
}
}
}
.page {
background-color: rgba(var(--foreground-color), 1);
}
#sign_in {
width: 24rem;
@ -1661,39 +1707,17 @@ input[type="date"] {
grid-area: updates;
}
#all_interns_list {
gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
gap: 0.5rem;
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
.intern-card {
gap: 1.5rem 0.5rem;
padding: 1.5rem;
grid-template-columns: 1fr;
gap: 1rem;
border-radius: 0.5rem;
background-color: rgba(var(--foreground-color), 1);
&__initials {
position: relative;
grid-column: 1/3;
z-index: 1;
}
&__initials::after {
content: "";
position: absolute;
background-color: inherit;
border-radius: inherit;
height: calc(100% + 1rem);
width: calc(100% + 1rem);
opacity: 0.3;
z-index: -1;
}
background-color: rgba(var(--text-color), 0.06);
}
}
#intern_list_popup {
--height: 80vh;
}
#settings_page {
height: 100%;
align-items: flex-start;
padding: 2rem;
}
}
@media only screen and (min-width: 1280px) {
@ -1731,14 +1755,9 @@ input[type="date"] {
}
.interact:hover {
background: linear-gradient(
rgba(var(--text-color), 0.06),
rgba(var(--text-color), 0.06)
),
rgba(var(--foreground-color), 1);
background-color: rgba(var(--text-color), 0.06);
}
.send-update-button,
.task-option,
.apply-button {
opacity: 0;
@ -1747,8 +1766,7 @@ input[type="date"] {
.task-list-item:hover .task-option,
.task-option:focus-within,
.task:hover .apply-button,
.task-card:hover .send-update-button {
.task:hover .apply-button {
opacity: 1;
}
}

View File

@ -230,15 +230,112 @@
</nav>
<article id="sub_page_container">
<section id="dashboard_page" class="page">
<section id="project_watching_section">
<h4>Projects watchlist</h4>
<div id="project_watchlist" class="observe-empty-state"></div>
<h4 class="empty-state">No project added to watchlist.</h4>
</section>
<section id="intern_view" class="hidden intern-option">
<h2>My tasks</h2>
<ul id="assigned_task_list"></ul>
</section>
<div class="flex flex-direction-column gap-2">
<div id="application_card" class="card flex align-center space-between general-only">
<div>
<h2 class="margin-bottom-0-5">Looking for an internship?</h2>
<p class="margin-bottom-1">Apply for internships at RanchiMall</p>
<button class="button button--primary"
onclick="openPopup('apply_for_internship_popup')">Apply
Now</button>
</div>
<svg class="illustration" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"
width="753.87469" height="703.82827" viewBox="0 0 753.87469 703.82827"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path
d="M578.47505,103.95771l-23.06843,12.58664L271.19846,271.61447,248.13,284.2011a48.1793,48.1793,0,0,0-19.1955,65.29607L440.57765,737.39072a48.17922,48.17922,0,0,0,65.296,19.19561l.05958-.03251L836.15907,576.37545l.05958-.03251a48.17924,48.17924,0,0,0,19.19553-65.296L643.77106,123.15338A48.17929,48.17929,0,0,0,578.47505,103.95771Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<path
d="M585.11115,116.11916l-27.323,14.908L282.08828,281.455,254.7657,296.36278a34.30947,34.30947,0,0,0-13.66965,46.4988L452.73916,730.75513a34.30947,34.30947,0,0,0,46.4988,13.66952l.05958-.0325L829.5234,564.21377l.06-.03274a34.30935,34.30935,0,0,0,13.66926-46.49851L631.60954,129.789A34.30936,34.30936,0,0,0,585.11115,116.11916Z"
transform="translate(-223.06266 -98.08587)" fill="#fff" />
<path
d="M589.66653,236.52147,466.505,303.72109a8.01411,8.01411,0,1,1-7.677-14.07012l123.16157-67.19962a8.01411,8.01411,0,1,1,7.677,14.07012Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<path
d="M631.641,244.43106,479.45984,327.46442a8.01411,8.01411,0,0,1-7.677-14.07012l152.18119-83.03336a8.01411,8.01411,0,1,1,7.677,14.07012Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<path
d="M415.87223,275.74837l-113.5479,61.95419a3.84082,3.84082,0,0,0-1.53151,5.21006L349.14436,431.53a3.84075,3.84075,0,0,0,5.21,1.5317l113.5479-61.95419a3.84075,3.84075,0,0,0,1.53153-5.21l-48.35154-88.61735A3.84081,3.84081,0,0,0,415.87223,275.74837Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<path
d="M650.7763,348.96263,483.723,440.11051a8.01411,8.01411,0,1,1-7.677-14.07012l167.05327-91.14788a8.01411,8.01411,0,1,1,7.677,14.07012Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<path
d="M692.7508,356.87223,496.67791,463.85384a8.01411,8.01411,0,0,1-7.677-14.07012L685.07384,342.80211a8.01411,8.01411,0,1,1,7.677,14.07012Z"
transform="translate(-223.06266 -98.08587)" fill="#f2f2f2" />
<circle cx="197.03853" cy="382.67177" r="34" fill="#f2f2f2" />
<path
d="M928.81234,263.78816H552.494a48.17927,48.17927,0,0,0-48.125,48.12512V753.78907a48.17922,48.17922,0,0,0,48.125,48.12506H928.81234a48.17922,48.17922,0,0,0,48.125-48.12506V311.91328A48.17927,48.17927,0,0,0,928.81234,263.78816Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M928.81283,277.64235H552.494a34.30947,34.30947,0,0,0-34.271,34.27093V753.78907A34.30947,34.30947,0,0,0,552.494,788.06H928.81283a34.30936,34.30936,0,0,0,34.27051-34.27088V311.91328A34.30937,34.30937,0,0,0,928.81283,277.64235Z"
transform="translate(-223.06266 -98.08587)" fill="#fff" />
<path
d="M875.14319,385.51745H734.84151a8.01411,8.01411,0,0,1,0-16.02823H875.14319a8.01412,8.01412,0,1,1,0,16.02823Z"
transform="translate(-223.06266 -98.08587)" fill="#6c63ff" />
<path
d="M908.20141,412.56508H734.84151a8.01411,8.01411,0,1,1,0-16.02822h173.3599a8.01411,8.01411,0,0,1,0,16.02822Z"
transform="translate(-223.06266 -98.08587)" fill="#6c63ff" />
<path
d="M703.79234,336.71073H574.44224a3.8408,3.8408,0,0,0-3.83984,3.84v100.95a3.84075,3.84075,0,0,0,3.83984,3.84h129.3501a3.84076,3.84076,0,0,0,3.83984-3.84v-100.95A3.84081,3.84081,0,0,0,703.79234,336.71073Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M609.92406,398.70111a34.087,34.087,0,0,1-8.804,23.076c-5.656,6.20712-14.07618,10.3236-22.57327,8.62043-7.82416-1.56829-14.18219-8.4067-13.389-16.6795a12.356,12.356,0,0,1,15.2668-11.09515c7.43265,1.92885,10.39415,12.64095,4.20051,17.669-1.4862,1.2065-3.62136-.90359-2.12132-2.12132,4.0944-3.32385,2.8295-10.5954-2.11244-12.419-5.75371-2.12311-11.84978,2.44324-12.26355,8.32554-.49057,6.97428,4.85221,12.22646,11.40422,13.463,7.08789,1.3377,14.11532-2.29,18.91808-7.29718a30.95507,30.95507,0,0,0,8.474-21.54183,1.5009,1.5009,0,0,1,3,0Z"
transform="translate(-223.06266 -98.08587)" fill="#2f2e41" />
<circle cx="416.15529" cy="266.1673" r="53.51916" fill="#6c63ff" />
<path
d="M636.47981,387.08916l-.05566-2c3.7207-.10352,7.001-.33692,9.46582-2.1377a6.14794,6.14794,0,0,0,2.38134-4.52832,3.51432,3.51432,0,0,0-1.15283-2.89453c-1.63623-1.38184-4.269-.93457-6.188-.05469l-1.65478.75879,3.17334-23.19043,1.98144.27149-2.69922,19.72656c2.60743-.7666,5.02344-.43652,6.67823.96094a5.471,5.471,0,0,1,1.86035,4.49218,8.13264,8.13264,0,0,1-3.2002,6.07325C643.90266,386.88115,639.78694,386.99638,636.47981,387.08916Z"
transform="translate(-223.06266 -98.08587)" fill="#2f2e41" />
<rect x="431.16715" y="256.92907" width="10.77148" height="2" fill="#2f2e41" />
<rect x="397.16715" y="256.92907" width="10.77148" height="2" fill="#2f2e41" />
<path
d="M609.57212,445.34074a53.00636,53.00636,0,0,1,12.89014-5.93,8.56789,8.56789,0,0,1,.02-4.71,9.42609,9.42609,0,0,1,9.12988-6.63h13.04a9.45955,9.45955,0,0,1,9.15039,6.64,8.532,8.532,0,0,1,.01953,4.7,53.16732,53.16732,0,0,1,12.89014,5.93Z"
transform="translate(-223.06266 -98.08587)" fill="#2f2e41" />
<path
d="M700.52232,344.39072a11.57143,11.57143,0,0,0-3.52979-2.87,8.36739,8.36739,0,0,0-3.8501-.95,8.77158,8.77158,0,0,0-5.10986,1.72c-4.07031,2.88-6.89014,9.09-6.89014,16.28,0,9.02,4.43995,16.5,10.21,17.80005a8.25321,8.25321,0,0,0,1.79.2c6.60987,0,12-8.07,12-18C705.14243,352.81077,703.33238,347.68076,700.52232,344.39072Z"
transform="translate(-223.06266 -98.08587)" fill="#3f3d56" />
<path
d="M590.6024,341.86076h-.00977a8.57836,8.57836,0,0,0-4.4502-1.29,8.36738,8.36738,0,0,0-3.85009.95,11.57143,11.57143,0,0,0-3.52979,2.87l-.01025.01c-2.79981,3.29-4.60987,8.42-4.60987,14.17,0,7.76,3.27979,14.38,7.87989,16.91a8.54175,8.54175,0,0,0,4.12011,1.09,7.72431,7.72431,0,0,0,.96-.06h.00976c6.16016-.74,11.03027-8.5,11.03027-17.94C598.14243,351.01072,595.01255,344.52073,590.6024,341.86076Z"
transform="translate(-223.06266 -98.08587)" fill="#3f3d56" />
<path
d="M582.77242,373.76a1.50127,1.50127,0,0,0,1.42151-1.98,58.49864,58.49864,0,1,1,112.68726-6.5747,1.50006,1.50006,0,0,0,2.93554.61914A61.50091,61.50091,0,1,0,581.35116,372.739,1.50077,1.50077,0,0,0,582.77242,373.76Z"
transform="translate(-223.06266 -98.08587)" fill="#3f3d56" />
<path
d="M666.10324,329.57746c2.11924,2.89278,1.07447,6.79121-1.15837,9.28528-2.90548,3.24541-7.53877,3.45016-11.5618,2.8478-4.51431-.67591-9.3026-2.7909-13.87293-1.3656-3.89537,1.2148-6.67418,4.74793-10.7211,5.63537-3.589.787-7.88081-.25477-9.139-4.08016-.60459-1.83823,2.29142-2.6261,2.89284-.79751.81395,2.47478,4.32865,2.42543,6.34145,1.74012,3.22689-1.09867,5.71374-3.77105,8.8854-5.04749,3.73933-1.50491,7.79621-.82549,11.60323.03181,3.58831.808,7.718,2.006,11.29267.49665,2.64515-1.1169,4.74985-4.635,2.84717-7.23211-1.14219-1.5591,1.45985-3.05738,2.59042-1.51416Z"
transform="translate(-223.06266 -98.08587)" fill="#2f2e41" />
<path
d="M874.932,513.49157H684.63034a8.01411,8.01411,0,1,1,0-16.02823H874.932a8.01412,8.01412,0,0,1,0,16.02823Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M907.99023,540.5392H684.63034a8.01412,8.01412,0,1,1,0-16.02823H907.99023a8.01412,8.01412,0,1,1,0,16.02823Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M874.932,610.705H684.63034a8.01411,8.01411,0,1,1,0-16.02822H874.932a8.01411,8.01411,0,1,1,0,16.02822Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M907.99023,637.75267H684.63034a8.01411,8.01411,0,1,1,0-16.02823H907.99023a8.01411,8.01411,0,1,1,0,16.02823Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<circle cx="386.2497" cy="420.61448" r="34" fill="#e6e6e6" />
<circle cx="386.2497" cy="518.61448" r="34" fill="#e6e6e6" />
<path
d="M874.932,708.705H684.63034a8.01411,8.01411,0,1,1,0-16.02822H874.932a8.01411,8.01411,0,1,1,0,16.02822Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<path
d="M907.99023,735.75267H684.63034a8.01411,8.01411,0,1,1,0-16.02823H907.99023a8.01411,8.01411,0,1,1,0,16.02823Z"
transform="translate(-223.06266 -98.08587)" fill="#e6e6e6" />
<circle cx="386.2497" cy="616.61448" r="34" fill="#e6e6e6" />
</svg>
</div>
<section id="project_watching_section" class="w-100">
<h4>Projects watchlist</h4>
<div id="project_watchlist" class="observe-empty-state"></div>
<h4 class="empty-state">No project added to watchlist.</h4>
</section>
<section id="intern_view" class="hidden intern-option">
<h2>My tasks</h2>
<ul id="assigned_task_list"></ul>
</section>
</div>
<section>
<div id="best_interns_container" class="container-card">
<div class="container-header">
@ -251,7 +348,7 @@
<h4>Leaderboard</h4>
<a id="all_interns_btn" href="#all_interns_page" class="button">All</a>
</div>
<div id="best_interns"></div>
<div id="top_interns"></div>
</div>
<div id="project_list_container" class="container-card">
<div class="container-header">
@ -273,7 +370,8 @@
<h2 id="username" class="capitalize"></h2>
<div id="user_role"></div>
<sm-copy id="user_flo_id"></sm-copy>
<sm-button id="logout" variant="primary" class="justify-self-start" onclick="logout()">
<button id="logout" class="justify-self-start button button--danger button--primary"
onclick="signOut()">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
@ -281,7 +379,7 @@
d="M4 18h2v2h12V4H6v2H4V3a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-3zm2-7h7v2H6v3l-5-4 5-4v3z" />
</svg>
Sign out
</sm-button>
</button>
</section>
</section>
<section id="admin_page" class="page hidden">
@ -293,7 +391,8 @@
</sm-tab-header>
<sm-tab-panels id="admin_tabs">
<section id="projects_container">
<button class="button margin-left-auto" onclick="openPopup('add_project_popup')">
<button class="button button--small margin-left-auto"
onclick="openPopup('add_project_popup')">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z"></path>
@ -307,7 +406,8 @@
<h4 class="empty-state">No project added</h4>
</section>
<section id="interns_container">
<button class="button margin-left-auto" onclick="openPopup('add_intern_popup')">
<button class="button button--small margin-left-auto"
onclick="openPopup('add_intern_popup')">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
@ -327,18 +427,28 @@
</section>
<section id="project_editing_panel" class="inner-page hide-on-mobile hidden">
<div id="project_details_wrapper" class="grid gap-1 margin-bottom-2">
<div class="flex gap-0-5 flex-wrap align-items-start">
<div class="flex flex-wrap align-items-start">
<h2 id="editing_panel__title" data-editable></h2>
<button class="button button--small admin-option" title="Edit this title"
onclick="makeEditable(this.previousElementSibling)">
Edit
<button class="button button--small button--transparent admin-option"
title="Edit this title" onclick="makeEditable(this.previousElementSibling)">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z" />
</svg>
</button>
</div>
<div class="flex gap-0-5 flex-wrap align-items-start">
<div class="flex flex-wrap align-items-start">
<p id="editing_panel__description" data-editable></p>
<button class="button button--small admin-option" title="Edit this description"
onclick="makeEditable(this.previousElementSibling)">
Edit
<button class="button button--small button--transparent admin-option"
title="Edit this description" onclick="makeEditable(this.previousElementSibling)">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24"
width="24px" fill="#000000">
<path d="M0 0h24v24H0V0z" fill="none" />
<path
d="M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z" />
</svg>
</button>
</div>
</div>
@ -435,7 +545,7 @@
<h4 class="empty-state">No related updates</h4>
</section>
</section>
<section id="all_interns_page" class="page hidden">
<section id="all_interns_page" class="page hidden flex flex-direction-column align-start">
<div id="all_interns_page__header" class="grid gap-0-5">
<h2>Interns</h2>
<sm-input id="interns_page__search" placeholder="Search">
@ -453,9 +563,9 @@
<section id="project_explorer" class="page hidden">
<div id="project_explorer__left" class="list-container">
<h4 class="padding intern-option hidden">My projects</h4>
<div></div>
<div id="my_projects"></div>
<h4 class="padding intern-option hidden">Other projects</h4>
<div></div>
<div id="other_projects"></div>
</div>
<section id="project_explorer__right" class="grid hide-on-mobile">
<header class="flex space-between align-center">
@ -624,7 +734,7 @@
<h3 id="update_of_task"></h3>
<sm-form>
<sm-textarea id="update_description" placeholder="Type the update" rows="4" required></sm-textarea>
<sm-button id="post_update_btn" title="post this update" variant="primary" disabled>
<sm-button id="post_update_btn" title="post this update" variant="primary" disabled onclick="postUpdate()">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24"
height="24">
<path fill="none" d="M0 0h24v24H0z" />
@ -636,6 +746,36 @@
</sm-form>
</sm-popup>
<sm-popup id="apply_for_internship_popup">
<header slot="header" class="popup__header">
<button class="popup__header__close" onclick="closePopup()">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z" />
</svg>
</button>
<h3>Apply for internship</h3>
</header>
<sm-form>
<sm-input id="intern_apply__name" placeholder="Full name" autofocus required></sm-input>
<sm-textarea id="intern_apply__brief" placeholder="Tell us about yourself" rows="6" required></sm-textarea>
<div class="multi-state-button">
<sm-button id="intern_apply__button" title="post this update" variant="primary" disabled
onclick="applyForInternship()">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24"
height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M1.923 9.37c-.51-.205-.504-.51.034-.689l19.086-6.362c.529-.176.832.12.684.638l-5.454 19.086c-.15.529-.475.553-.717.07L11 13 1.923 9.37zm4.89-.2l5.636 2.255 3.04 6.082 3.546-12.41L6.812 9.17z" />
</svg>
Apply
</sm-button>
</div>
</sm-form>
</sm-popup>
<!-- Templates -->
<template id="update_card_template">
@ -708,7 +848,7 @@
<div class="line"></div>
</div>
<div class="right">
<div class="apply-container flex space-between align-start">
<div class="apply-container flex space-between align-items-start">
<h4 class="timeline-task__title capitalize"></h4>
</div>
<div class="assigned-interns"></div>
@ -717,15 +857,6 @@
</div>
</div>
</template>
<template id="project_map_template">
<div class="project_map_card">
<h2 class="project-map__title"></h2>
<p class="project-map__description"></p>
<div class="project__branch_container"></div>
<h4>Timeline</h4>
<div class="project-map__timeline"></div>
</div>
</template>
<template id="watchlist_project_template">
<a class="watchlist_project_card interact">
<div class="project-icon">
@ -1219,20 +1350,51 @@
this.render()
}
}
function buttonLoader(id, show) {
const button = typeof id === 'string' ? getRef(id) : id;
button.disabled = show;
const animOptions = {
duration: 200,
fill: 'forwards',
easing: 'ease'
}
if (show) {
button.animate([
{
clipPath: 'circle(100%)',
},
{
clipPath: 'circle(0)',
},
], animOptions).onfinish = e => {
e.target.commitStyles()
e.target.cancel()
}
button.parentNode.append(createElement('sm-spinner'))
} else {
button.style = ''
const potentialTarget = button.parentNode.querySelector('sm-spinner')
if (potentialTarget) potentialTarget.remove();
}
}
// implement event delegation
function delegate(el, event, selector, fn) {
el.addEventListener(event, function (e) {
const potentialTarget = e.target.closest(selector)
if (potentialTarget) {
e.delegateTarget = potentialTarget
fn.call(this, e)
}
})
}
</script>
<script id="UI_functions">
// Method object for creating various UI elements
const render = {
projectCard(projectName, projectCode, isAdmin = false) { // creates cards containing project information
projectCard(projectCode, isAdmin = false) { // creates cards containing project information
const projectName = RIBC.getProjectDetails(projectCode).projectName
const page = isAdmin ? 'admin_page' : 'project_explorer'
return createElement('a', {
className: 'project-card flex align-center interact',
attributes: {
'title': "Project information",
href: `#${page}?projectId=${projectCode}&branch=mainLine`
},
textContent: projectName
});
return html`<a class="project-card flex align-center interact" title="Project information" href=${`#${page}?projectId=${projectCode}&branch=mainLine`}>${projectName}</a>`
},
taskCard(currentProject, currentBranch, taskNo) {
const card = getRef('timeline_task_card').content.cloneNode(true),
@ -1241,30 +1403,25 @@
if (RIBC.getTaskStatus(currentProject, currentBranch, taskNo) === 'completed') {
card.firstElementChild.classList.add('completed-task')
}
if (assignedInterns || typeOfUser === 'general') {
renderElem(card.querySelector('.assigned-interns'), html`${assignedInterns.map((internFloId) => {
return render.assignedInternCard(internFloId);
})
}`)
if (assignedInterns) {
renderElem(card.querySelector('.assigned-interns'), html`${assignedInterns.map((internFloId) => render.assignedInternCard(internFloId))}`)
}
else {
if (typeOfUser === 'intern') {
const applyButton = createElement('sm-button', {
textContent: 'Apply',
className: 'apply-button',
attributes: { 'data-project-code': currentProject, 'data-branch': currentBranch, 'data-task-no': taskNo }
})
function checkObject(obj) {
return (obj.projectCode === currentProject && obj.branch === currentBranch && obj.taskNo == taskNo)
}
if (localStorage.getItem('requests') !== null) {
if (JSON.parse(localStorage.getItem('requests')).find(checkObject) !== undefined) {
applyButton.textContent = 'Applied';
applyButton.setAttribute('disabled', '')
}
}
card.querySelector('.apply-container').append(applyButton)
if (typeOfUser === 'intern') {
const applyButton = createElement('sm-button', {
textContent: 'Apply',
className: 'apply-button',
attributes: { 'data-project-code': currentProject, 'data-branch': currentBranch, 'data-task-no': taskNo }
})
function checkObject(obj) {
return (obj.projectCode === currentProject && obj.branch === currentBranch && obj.taskNo == taskNo)
}
if (localStorage.getItem('requests') !== null) {
if (JSON.parse(localStorage.getItem('requests')).find(checkObject) !== undefined) {
applyButton.textContent = 'Applied';
applyButton.setAttribute('disabled', '')
}
}
card.querySelector('.apply-container').append(applyButton)
}
const { taskTitle, taskDescription } = RIBC.getTaskDetails(currentProject, currentBranch, taskNo)
card.querySelector('.timeline-task__title').textContent = taskTitle;
@ -1284,15 +1441,21 @@
}
return card;
},
internCard(internName, internFLOID, internPoints) {
// creates cards containing intern information
const card = getRef('intern_card_template').content.cloneNode(true)
setAttributes(card.firstElementChild, { 'data-intern-flo-id': internFLOID, 'title': 'Intern Information' })
card.querySelector('.intern-card__initials').style.backgroundColor = getInternColor(internFLOID)
card.querySelector('.intern-card__initials').textContent = internName.split(' ').map(v => v.charAt(0)).join('');
card.querySelector('.intern-card__name').textContent = internName;
card.querySelector('.intern-card__score').textContent = internPoints;
return card;
internCard(internName, internFloID, internPoints) {
const initials = internName.split(' ').map(v => v.charAt(0)).join('');
return html`
<li class="intern-card grid align-center interact" data-intern-flo-id=${internFloID} title="Intern Information"}>
<div class="intern-card__initials" style=${`background-color: ${getInternColor(internFloID)}`}>${initials}</div>
<div class="intern-card__name capitalize">${internName}</div>
<div class="intern-card__score-wrapper flex align-center">
<h4 class="intern-card__score">${internPoints}</h4>
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path
d="M12 18.26l-7.053 3.948 1.575-7.928L.587 8.792l8.027-.952L12 .5l3.386 7.34 8.027.952-5.935 5.488 1.575 7.928z" />
</svg>
</div>
</li>`;
},
// creates cards containing updates provided by interns
updateCard(update) {
@ -1325,7 +1488,6 @@
${optionsButton}
</span>
`
return internCard;
},
taskListItem(taskNo) {
const card = getRef('task_list_item_template').content.cloneNode(true)
@ -1342,7 +1504,6 @@
const assignedInternsCards = assignedInterns.filter(v => v).map((internFloId) => {
return render.assignedInternCard(internFloId, true);
})
console.log(assignedInterns)
renderElem(card.querySelector('.assigned-interns'), html`${assignedInternsCards}`)
}
const branches = getAllBranches(currentProject)
@ -1360,39 +1521,23 @@
}
return card;
},
projectMapCard(projectCode, page) {
const card = getRef('project_map_template').content.cloneNode(true)
const frag = document.createDocumentFragment()
const { projectName, projectDescription } = RIBC.getProjectDetails(projectCode)
card.firstElementChild.id = `${projectCode}_map`;
card.querySelector('.project-map__title').textContent = projectName
card.querySelector('.project-map__description').textContent = projectDescription
card.querySelector('.project__branch_container').id = `${projectCode}_branch_container`;
RIBC.getProjectBranches(projectCode).forEach((branch) => {
frag.append(render.branchButton({ projectId: projectCode, branch, page }))
})
card.querySelector('.project__branch_container').append(frag);
card.querySelector('.project-map__timeline').id = `${projectCode}_map_body`
currentProject = projectCode;
// mapItems.push(card, card.id, branchContainer.id, mapBody.id)
return card;
},
requestCard(floId, projectCode, branch, taskNo) {
requestCard(details) {
const { projectCode, branch, task, floId, vectorClock } = details
const internName = RIBC.getInternList()[floId];
return html`
<li class="request-card">
<li class="request-card" .dataset=${{ vectorClock }}>
<p class="request-card__description">
<b class="capitalize">${internName}</b> applied for
<b class="capitalize">${RIBC.getTaskDetails(projectCode, branch, taskNo).taskTitle}</b> from
<b class="capitalize">${RIBC.getTaskDetails(projectCode, branch, task).taskTitle}</b> from
<b class="capitalize">${branch}</b> of
<b class="capitalize">${RIBC.getProjectDetails(projectCode).projectName}</b>
</p>
<div class="flex justify-end">
<button class="button button--small reject-app">
<div class="flex gap-0-3 margin-left-auto">
<button class="button button--small reject-request">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></svg>
Reject
</button>
<button class="button button--small accept-app" data-flo-id="${floId}" data-project-code="${projectCode}" data-branch="${branch}" data-task-no="${taskNo}">
<button class="button button--small accept-request">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>
Accept
</button>
@ -1406,15 +1551,15 @@
const projectName = RIBC.getProjectDetails(projectId).projectName
return html`
<li class="task-card" data-unique-id="${uniqueId}">
<div class="task__header">
<h5 class="task__project-title">${projectName}</h5>
<h5 class="task__title">${taskTitle}</h5>
<sm-button class="send-update-button">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M1.946 9.315c-.522-.174-.527-.455.01-.634l19.087-6.362c.529-.176.832.12.684.638l-5.454 19.086c-.15.529-.455.547-.679.045L12 14l6-8-8 6-8.054-2.685z"/></svg>
Post
</sm-button>
<span class="task__project-title">${projectName}</span>
<div>
<h4 class="task__title">${taskTitle}</h4>
<p class="task__description">${taskDescription}</p>
</div>
<p class="task__description">${taskDescription}</p>
<button class="send-update-button">
<svg class="icon margin-right-0-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M1.946 9.315c-.522-.174-.527-.455.01-.634l19.087-6.362c.529-.176.832.12.684.638l-5.454 19.086c-.15.529-.455.547-.679.045L12 14l6-8-8 6-8.054-2.685z"/></svg>
Post an update
</button>
</li>
`;
},
@ -1466,16 +1611,19 @@
}
}
let allInternsList = [], highPerformingInterns = [],
watchList = [], currentIntern, currentTaskId,
typeOfUser = 'general';
let allInternsList = [];
let highPerformingInterns = [];
let watchList = [];
let currentIntern;
let currentTaskId;
let typeOfUser = 'general';
// Adds interns to the database **Only SubAdmins can add interns
function addInternToList() {
let internName = getRef('intern_name_field').value.trim(),
internFLOID = getRef('intern_flo_id_field').value.trim();
if (RIBC.admin.addIntern(internFLOID, internName)) {
getRef('admin_page__intern_list').append(render.internCard(internName, internFLOID, '1'))
internFloID = getRef('intern_flo_id_field').value.trim();
if (RIBC.admin.addIntern(internFloID, internName)) {
renderElem(getRef('admin_page__intern_list'), filterInterns(''))
closePopup();
notify(`${internName} added as an intern.`, 'success')
}
@ -1495,7 +1643,7 @@
const projectCode = `${new Date().getFullYear()}_project_${RIBC.getProjectList() ? (RIBC.getProjectList().length + 1) : '1'}`;
RIBC.admin.createProject(projectCode)
RIBC.admin.addProjectDetails(projectCode, { projectName, projectDescription })
getRef('admin_page__project_list').prepend(render.projectCard(projectName, projectCode, true))
getRef('admin_page__project_list').prepend(render.projectCard(projectCode, true))
closePopup();
}
@ -1802,15 +1950,15 @@
thisPage.classList.remove('hidden');
}
function logout() {
getConfirmation("Do you want to sign out?").then(async (result) => {
if (result) {
await floDapps.clearCredentials()
onLoadStartUp()
}
})
function signOut() {
getConfirmation('Sign out?', 'You are about to sign out of the app, continue?', 'Stay', 'Leave')
.then(async (res) => {
if (res) {
await floDapps.clearCredentials();
location.reload();
}
});
}
document.getElementById('intern_list_container').addEventListener('click', (event) => {
if (event.target.closest('.intern-card')) {
const floId = event.target.closest('.intern-card').dataset.internFloId;
@ -1831,8 +1979,7 @@
}
function renderAllInterns() {
getRef('all_interns_list').innerHTML = ''
getRef('all_interns_list').append(filterInterns('', { sortByRating: true }))
renderElem(getRef('all_interns_list'), filterInterns('', { sortByRating: true }))
}
function changeScore(scoreUpdate) {
@ -2001,7 +2148,7 @@
function watchThisProject(thisBtn) {
watchList = localStorage.getItem(`${myFloID}_watchlist`) ? localStorage.getItem(`${myFloID}_watchlist`).split(',') : []
if (watchList.includes(currentProject)) {
watchList.splice(watchList.indexOf(currentProject), 1)
watchList = watchList.filter(project => project !== currentProject)
thisBtn.textContent = 'Watch'
notify(`${RIBC.getProjectDetails(currentProject).projectName} removed from your watch list.`)
} else {
@ -2065,7 +2212,7 @@
}
// Event listeners
document.getElementById('best_interns').addEventListener('click', (event) => {
document.getElementById('top_interns').addEventListener('click', (event) => {
if (event.target.closest('.intern-card'))
showInternInfo(event.target.closest('.intern-card').dataset.internFloId)
})
@ -2080,21 +2227,20 @@
document.addEventListener('popupopened', e => {
switch (e.detail.popup.id) {
case 'intern_list_popup':
getRef('intern_list_container').innerHTML = ''
getRef('intern_list_container').append(filterInterns(''))
renderElem(getRef('intern_list_container'), filterInterns(''))
break;
}
})
document.addEventListener('popupclosed', e => {
switch (e.detail.popup.id) {
case 'intern_list_popup':
getRef('intern_list_container').innerHTML = ''
renderElem(getRef('intern_list_container'), html``)
getRef('intern_search_field').value = ''
break;
}
})
const internAssignedTasks = {}
floGlobals.assignedTasks = {}
function renderAllElements() {
watchList = localStorage.getItem(`${myFloID}_watchlist`) ? localStorage.getItem(`${myFloID}_watchlist`).split(',') : []
@ -2103,7 +2249,6 @@
//creates cards for highest performing interns
//sort interns earned points
allInternsList = RIBC.getInternList();
highPerformingInterns = [];
for (let intern in allInternsList) {
@ -2119,7 +2264,8 @@
// Intern's view
let assignedProjectsList = [], x;
let assignedProjectsList = [];
let projectTaskNos;
if (allInternsList[myFloID] && !floGlobals.subAdmins.includes(myFloID)) {
typeOfUser = 'intern';
document.querySelectorAll('.intern-option').forEach((option) => {
@ -2128,26 +2274,31 @@
document.getElementById('project_watching_section').classList.add('hidden')
getRef('watch_project_button').classList.add('hidden')
// store all the projects assinged to interns in array
for (let i = 0; i < allProjectsList.length; i++) {
// store all the projects assigned to interns in array
allProjectsList.forEach(projectId => {
nextProject:
for (branch in RIBC.getProjectMap(allProjectsList[i])) {
x = RIBC.getProjectMap(allProjectsList[i])[branch].slice(4);
for (let j = 0; j < x.length; j++)
if (Array.isArray(RIBC.getAssignedInterns(allProjectsList[i], branch, x[j])) && RIBC.getAssignedInterns(allProjectsList[i], branch, x[j]).includes(myFloID)) {
assignedProjectsList.push(allProjectsList[i])
for (branch in RIBC.getProjectMap(projectId)) {
projectTaskNos = RIBC.getProjectMap(projectId)[branch].slice(4);
for (let j = 0; j < projectTaskNos.length; j++) {
const assignedInterns = RIBC.getAssignedInterns(projectId, branch, projectTaskNos[j])
console.log(assignedInterns)
if (Array.isArray(assignedInterns) && assignedInterns.includes(myFloID)) {
console.log('has me')
assignedProjectsList.push(projectId)
break nextProject;
}
}
}
}
})
// sore all the tasks assigned to intern in array
// store all the tasks assigned to intern in array
assignedProjectsList.forEach(project => {
for (branch in RIBC.getProjectMap(project)) {
for (const branch in RIBC.getProjectMap(project)) {
branchTasks = RIBC.getProjectMap(project)[branch].slice(4);
branchTasks.forEach(task => {
if (RIBC.getTaskStatus(project, branch, task) === 'incomplete' && Array.isArray(RIBC.getAssignedInterns(project, branch, task)) && RIBC.getAssignedInterns(project, branch, task).includes(myFloID)) {
internAssignedTasks[floCrypto.randString(16, true)] = {
if (RIBC.getTaskStatus(project, branch, task) === 'incomplete') {
floGlobals.assignedTasks[floCrypto.randString(16, true)] = {
projectId: project,
projectBranch: branch,
task
@ -2159,15 +2310,15 @@
document.getElementById('project_list_container').firstElementChild.children[1].textContent = 'My projects'
let parent = document.getElementById('assigned_task_list');
if (!Object.keys(internAssignedTasks).length) {
if (!Object.keys(floGlobals.assignedTasks).length) {
parent.textContent = 'No task assigned yet.';
} else {
// Render assigned task cards
const taskCards = []
for (const task in internAssignedTasks) {
for (const task in floGlobals.assignedTasks) {
taskCards.push(render.internTaskCard({
'uniqueId': task,
...internAssignedTasks[task]
...floGlobals.assignedTasks[task]
}))
}
renderElem(getRef('assigned_task_list'), html`${taskCards}`)
@ -2178,8 +2329,8 @@
if (e.target.closest('.send-update-button')) {
const taskCard = e.target.closest('.task-card')
currentTaskId = taskCard.dataset.uniqueId
const { projectId, projectBranch, task } = internAssignedTasks[currentTaskId]
getRef('update_of_project').textContent = RIBC.getProjectDetails(project).projectName
const { projectId, projectBranch, task } = floGlobals.assignedTasks[currentTaskId]
getRef('update_of_project').textContent = RIBC.getProjectDetails(projectId).projectName
getRef('update_of_task').textContent = RIBC.getTaskDetails(projectId, projectBranch, task).taskTitle
openPopup('post_update_popup')
}
@ -2198,42 +2349,44 @@
typeOfUser = 'admin'
const requestCards = [];
RIBC.getTaskRequests().forEach((request) => {
const { projectCode, branch, task, floID } = request
const { projectCode, branch, task } = request
if (typeof RIBC.getTaskDetails(projectCode, branch, task) !== 'undefined')
requestCards.push(render.requestCard(floID, projectCode, branch, task))
requestCards.push(render.requestCard(request))
})
renderElem(getRef('requests_list'), html`${requestCards}`)
getRef('requests_list').addEventListener('click', (e) => {
function removeRequest(requestCard) {
requestCard.animate([
{
transform: 'translateX(0)',
opacity: 1
},
{
transform: 'translateX(-100%)',
opacity: 0
},
], {
duration: 300,
easing: 'ease'
}).onfinish = () => {
requestCard.remove()
}
function removeRequest(requestCard) {
requestCard.animate([
{
transform: 'translateX(0)',
opacity: 1
},
{
transform: 'translateX(-100%)',
opacity: 0
},
], {
duration: 300,
easing: 'ease'
}).onfinish = () => {
requestCard.remove()
}
if (e.target.closest('.accept-app')) {
let btn = e.target.closest('.accept-app'),
requestCard = e.target.closest('.request-card');
if (RIBC.admin.assignInternToTask(btn.dataset.floId, btn.dataset.projectCode, btn.dataset.branch, btn.dataset.taskNo)) {
notify('Intern assinged.', 'success')
removeRequest(requestCard)
}
else {
notify('Intern already assinged.', 'error')
}
} else if (e.target.closest('.reject-app')) {
let requestCard = e.target.closest('.request-card');
removeRequest(requestCard)
}
// accept task request
delegate(getRef('requests_list'), 'click', '.accept-request', (e) => {
const vectorClock = e.delegateTarget.closest('.request-card').dataset.vectorClock
const result = RIBC.admin.processTaskRequest(vectorClock, true)
if (result === 'Accepted') {
notify('Intern assigned.', 'success')
removeRequest(e.delegateTarget.closest('.request-card'))
}
})
// reject task request
delegate(getRef('requests_list'), 'click', '.reject-request', (e) => {
const vectorClock = e.delegateTarget.closest('.request-card').dataset.vectorClock
const result = RIBC.admin.processTaskRequest(vectorClock, false)
if (result === 'Rejected') {
notify('Request rejected', 'success')
removeRequest(e.delegateTarget.closest('.request-card'))
}
})
@ -2242,17 +2395,10 @@
})
//show interns
getRef('admin_page__intern_list').innerHTML = ``;
getRef('admin_page__intern_list').append(filterInterns(''))
renderElem(getRef('admin_page__intern_list'), filterInterns(''))
//show project
getRef('admin_page__project_list').innerHTML = ``;
for (let project in allProjectsList) {
const projectCode = allProjectsList[project]
const projectName = RIBC.getProjectDetails(projectCode).projectName
frag.prepend(render.projectCard(projectName, projectCode, true))
}
getRef('admin_page__project_list').append(frag)
//show projects
renderElem(getRef('admin_page__project_list'), html`${allProjectsList.map(projectCode => render.projectCard(projectCode, true))}`)
}
else {
document.querySelectorAll('.admin-option').forEach((option) => {
@ -2260,60 +2406,38 @@
})
}
document.getElementById('best_interns').innerHTML = ``;
let limit = Math.min(4, highPerformingInterns.length);
for (let p = 0; p < limit; p++) {
const { internName, floId, rating } = highPerformingInterns[p]
frag.append(render.internCard(internName, floId, rating))
}
document.getElementById('best_interns').appendChild(frag)
// displays recent projects
document.getElementById('project_list').innerHTML = '';
if (allInternsList.myFloID && !floGlobals.subAdmins.includes(myFloID)) {
assignedProjectsList.forEach((project) => {
frag.append(render.projectCard(RIBC.getProjectDetails(project).projectName, project))
// General only view for non admin and non intern
if (!allInternsList[myFloID] && !floGlobals.subAdmins.includes(myFloID)) {
document.querySelectorAll('.general-only').forEach((elem) => {
elem.classList.remove('hidden')
})
}
else {
for (project of allProjectsList.reverse().slice(0, 4)) {
frag.append(render.projectCard(RIBC.getProjectDetails(project).projectName, project))
}
}
document.getElementById('project_list').appendChild(frag)
getRef('post_update_btn').addEventListener('click', () => {
const { projectId, projectBranch, task } = internAssignedTasks[currentTaskId]
const description = getRef('update_description').value.trim()
if (topic !== '' && description !== '') {
RIBC.postInternUpdate({ projectId, projectBranch, task, description })
.then((result) => {
notify('Update posted', 'success')
closePopup()
})
.catch((error) => {
notify(error, 'error')
})
}
else {
notify('Please enter topic and description', 'error')
}
})
getRef('project_explorer').children[0].children[1].innerHTML = ``;
getRef('project_explorer').children[0].children[3].innerHTML = ``;
if (allInternsList[myFloID] && !floGlobals.subAdmins.includes(myFloID)) {
assignedProjectsList.forEach((project) => {
frag.append(render.projectCard(RIBC.getProjectDetails(project).projectName, project))
document.querySelectorAll('.general-only').forEach((elem) => {
elem.classList.add('hidden')
})
getRef('project_explorer').children[0].children[1].appendChild(frag)
}
renderElem(getRef('top_interns'), html`${highPerformingInterns.slice(0, 4).map((intern) => {
const { internName, floId, rating } = intern
return render.internCard(internName, floId, rating)
})}`);
// displays recent projects
let recentProjects = []
if (allInternsList.myFloID && !floGlobals.subAdmins.includes(myFloID)) {
recentProjects = assignedProjectsList.map((projectCode) => render.projectCard(projectCode))
} else {
recentProjects = allProjectsList.reverse().slice(0, 4).map((projectCode) => render.projectCard(projectCode))
}
renderElem(getRef('project_list'), html`${recentProjects}`)
if (allInternsList[myFloID] && !floGlobals.subAdmins.includes(myFloID)) {
renderElem(getRef('my_projects'), html`${assignedProjectsList.map((project) => render.projectCard(project))}`)
allProjectsList = allProjectsList.filter(val => !assignedProjectsList.includes(val));
}
for (i = 0; i < allProjectsList.length; i++) {
frag.appendChild(render.projectCard(RIBC.getProjectDetails(allProjectsList[i]).projectName, allProjectsList[i]))
}
getRef('project_explorer').children[0].children[3].appendChild(frag)
renderElem(getRef('other_projects'), html`${allProjectsList.map((project) => render.projectCard(project))}`)
getRef('explorer_task_list').addEventListener('click', (event) => {
if (event.target.closest('.apply-button')) {
@ -2327,9 +2451,26 @@
console.log(typeOfUser)
}
function postUpdate() {
const { projectId, projectBranch, task } = floGlobals.assignedTasks[currentTaskId]
const description = getRef('update_description').value.trim()
if (topic !== '' && description !== '') {
RIBC.postInternUpdate({ projectId, projectBranch, task, description })
.then((result) => {
notify('Update posted', 'success')
closePopup()
})
.catch((error) => {
notify(error, 'error')
})
}
else {
notify('Please enter topic and description', 'error')
}
}
function filterInterns(searchKey, options = {}) {
const { sortByRating = false } = options
const frag = document.createDocumentFragment();
let filtered = [];
const allInterns = RIBC.getInternList()
const arrayOfInterns = []
for (const intern in allInterns) {
@ -2340,38 +2481,46 @@
}
arrayOfInterns.sort((a, b) => a.internName.toLowerCase().localeCompare(b.internName.toLowerCase()))
if (searchKey === '') {
if (sortByRating) {
highPerformingInterns.forEach(({ internName, floId }) => {
frag.append(render.internCard(internName, floId, RIBC.getInternRating(floId)))
})
} else {
arrayOfInterns.forEach(({ internName, floId }) => {
frag.append(render.internCard(internName, floId, RIBC.getInternRating(floId)))
})
}
filtered = (sortByRating ? highPerformingInterns : arrayOfInterns).map(({ internName, floId }) => {
return render.internCard(internName, floId, RIBC.getInternRating(floId))
})
} else {
const options = {
keys: ['internName'],
threshold: 0.2
}
const fuse = new Fuse(arrayOfInterns, options)
fuse.search(searchKey).map(v => v.item).forEach(({ internName, floId }) => {
frag.append(render.internCard(internName, floId, RIBC.getInternRating(floId)))
filtered = fuse.search(searchKey).map(v => v.item).map(({ internName, floId }) => {
return render.internCard(internName, floId, RIBC.getInternRating(floId))
})
}
return frag
return html`${filtered}`
}
const searchInternPopup = debounce((e) => {
getRef('intern_list_container').innerHTML = ''
getRef('intern_list_container').append(filterInterns(e.target.value.trim()))
renderElem(getRef('intern_list_container'), filterInterns(e.target.value.trim()))
}, 150)
const searchInternPage = debounce((e) => {
getRef('all_interns_list').innerHTML = ''
getRef('all_interns_list').append(filterInterns(e.target.value.trim(), { sortByRating: true }))
renderElem(getRef('all_interns_list'), filterInterns(e.target.value.trim(), { sortByRating: true }))
}, 150)
getRef('intern_search_field').addEventListener('input', searchInternPopup)
getRef('interns_page__search').addEventListener('input', searchInternPage)
function applyForInternship() {
buttonLoader(getRef('intern_apply__button'), true)
const name = getRef('intern_apply__name').value.trim();
const brief = getRef('intern_apply__brief').value.trim();
RIBC.applyForIntern(name, brief)
.then((result) => {
notify('Application submitted', 'success')
closePopup()
})
.catch((error) => {
notify(error, 'error')
}).finally(() => {
buttonLoader(getRef('intern_apply__button'), false)
})
}
</script>
</body>