New scoring system display UI
This commit is contained in:
parent
0ecde83eb1
commit
75a55b2252
125
css/main.css
125
css/main.css
@ -158,26 +158,25 @@ button:not(:disabled),
|
|||||||
border: solid thin rgba(var(--text-color), 0.06);
|
border: solid thin rgba(var(--text-color), 0.06);
|
||||||
}
|
}
|
||||||
.button--primary {
|
.button--primary {
|
||||||
color: rgba(var(--background-color), 1) !important;
|
color: rgba(var(--background-color), 1);
|
||||||
|
background-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
.button--primary .icon {
|
.button--primary .icon {
|
||||||
fill: rgba(var(--background-color), 1);
|
fill: rgba(var(--background-color), 1);
|
||||||
}
|
}
|
||||||
.button--danger {
|
|
||||||
color: var(--danger-color);
|
|
||||||
}
|
|
||||||
.button--danger .icon {
|
|
||||||
fill: var(--danger-color);
|
|
||||||
}
|
|
||||||
.button--primary {
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
}
|
|
||||||
.button--colored {
|
.button--colored {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
}
|
}
|
||||||
.button--colored .icon {
|
.button--colored .icon {
|
||||||
fill: var(--accent-color);
|
fill: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
.button--danger {
|
||||||
|
background-color: rgba(255, 115, 115, 0.062745098);
|
||||||
|
color: var(--danger-color);
|
||||||
|
}
|
||||||
|
.button--danger .icon {
|
||||||
|
fill: var(--danger-color);
|
||||||
|
}
|
||||||
.button--small {
|
.button--small {
|
||||||
padding: 0.4rem 0.6rem;
|
padding: 0.4rem 0.6rem;
|
||||||
}
|
}
|
||||||
@ -246,18 +245,6 @@ details[open] > summary .down-arrow {
|
|||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
accent-color: var(--accent-color);
|
|
||||||
}
|
|
||||||
input[type=range]:active {
|
|
||||||
cursor: -webkit-grab;
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
|
|
||||||
sm-input,
|
sm-input,
|
||||||
sm-textarea,
|
sm-textarea,
|
||||||
tags-input {
|
tags-input {
|
||||||
@ -422,6 +409,10 @@ ul {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.align-items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
.align-content-start {
|
.align-content-start {
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
}
|
}
|
||||||
@ -450,7 +441,7 @@ ul {
|
|||||||
justify-content: start;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify-center {
|
.justify-content-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,6 +477,10 @@ ul {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.space-evenly {
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
.w-100 {
|
.w-100 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
@ -1291,14 +1286,6 @@ ul {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#intern_info_popup .grid > * {
|
|
||||||
justify-self: center;
|
|
||||||
}
|
|
||||||
#intern_info_popup #update_intern_score {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#intern_info__initials {
|
#intern_info__initials {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 4rem;
|
height: 4rem;
|
||||||
@ -1309,15 +1296,81 @@ ul {
|
|||||||
|
|
||||||
#intern_info__name {
|
#intern_info__name {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon--star {
|
.icon--star {
|
||||||
fill: var(--orange);
|
fill: var(--orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
#intern_info__score {
|
#stats_wrapper {
|
||||||
font-size: 1.5rem;
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
#stats_wrapper > * {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
.stat__display {
|
||||||
|
display: grid;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 4rem;
|
||||||
|
}
|
||||||
|
.stat__display > * {
|
||||||
|
grid-area: 1/1;
|
||||||
|
}
|
||||||
|
.stat__circle {
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 10;
|
||||||
|
overflow: visible;
|
||||||
|
stroke-dasharray: 400;
|
||||||
|
stroke-dashoffset: var(--progress, 400);
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
stroke-linecap: round;
|
||||||
|
transition: stroke-dashoffset 1s;
|
||||||
|
}
|
||||||
|
.stat__count {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.stat p {
|
||||||
|
color: rgba(var(--text-color), 0.8);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
max-width: 8ch;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#intern_rating .stat__circle {
|
||||||
|
fill: rgba(var(--text-color), 0.06);
|
||||||
|
stroke: var(--rating-color, --green);
|
||||||
|
}
|
||||||
|
#intern_rating .stat__count {
|
||||||
|
color: var(--rating-color, --green);
|
||||||
|
}
|
||||||
|
|
||||||
|
#intern_complete_tasks .stat__circle {
|
||||||
|
fill: rgba(255, 61, 0, 0.062745098);
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
#intern_complete_tasks .stat__count {
|
||||||
|
color: var(--orange);
|
||||||
|
}
|
||||||
|
|
||||||
|
#intern_points .stat__circle {
|
||||||
|
fill: rgba(109, 131, 255, 0.062745098);
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
#intern_points .stat__count {
|
||||||
|
color: var(--nice-blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
#project_info {
|
#project_info {
|
||||||
@ -1762,8 +1815,8 @@ input[type=date] {
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border: rgba(var(--text-color), 0.2) solid thin;
|
border: none;
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.5rem;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|||||||
2
css/main.min.css
vendored
2
css/main.min.css
vendored
File diff suppressed because one or more lines are too long
130
css/main.scss
130
css/main.scss
@ -145,28 +145,26 @@ button,
|
|||||||
background-color: rgba(var(--text-color), 0.02);
|
background-color: rgba(var(--text-color), 0.02);
|
||||||
border: solid thin rgba(var(--text-color), 0.06);
|
border: solid thin rgba(var(--text-color), 0.06);
|
||||||
&--primary {
|
&--primary {
|
||||||
color: rgba(var(--background-color), 1) !important;
|
color: rgba(var(--background-color), 1);
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
fill: rgba(var(--background-color), 1);
|
fill: rgba(var(--background-color), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&--danger {
|
|
||||||
color: var(--danger-color);
|
|
||||||
.icon {
|
|
||||||
fill: var(--danger-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--primary {
|
|
||||||
background-color: var(--accent-color);
|
|
||||||
}
|
|
||||||
&--colored {
|
&--colored {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
.icon {
|
.icon {
|
||||||
fill: var(--accent-color);
|
fill: var(--accent-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&--danger {
|
||||||
|
background-color: #ff737310;
|
||||||
|
color: var(--danger-color);
|
||||||
|
.icon {
|
||||||
|
fill: var(--danger-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&--small {
|
&--small {
|
||||||
padding: 0.4rem 0.6rem;
|
padding: 0.4rem 0.6rem;
|
||||||
@ -230,20 +228,6 @@ details[open] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
accent-color: var(--accent-color);
|
|
||||||
|
|
||||||
&[type="range"] {
|
|
||||||
&:active {
|
|
||||||
cursor: grab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sm-input,
|
sm-input,
|
||||||
sm-textarea,
|
sm-textarea,
|
||||||
tags-input {
|
tags-input {
|
||||||
@ -411,6 +395,9 @@ ul {
|
|||||||
.align-items-start {
|
.align-items-start {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
.align-items-center {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.align-content-start {
|
.align-content-start {
|
||||||
align-content: flex-start;
|
align-content: flex-start;
|
||||||
}
|
}
|
||||||
@ -438,7 +425,7 @@ ul {
|
|||||||
justify-content: start;
|
justify-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.justify-center {
|
.justify-content-center {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -473,6 +460,9 @@ ul {
|
|||||||
.space-between {
|
.space-between {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
.space-evenly {
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
.w-100 {
|
.w-100 {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -1283,15 +1273,6 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#intern_info_popup {
|
#intern_info_popup {
|
||||||
.grid {
|
|
||||||
& > * {
|
|
||||||
justify-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#update_intern_score {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#intern_info__initials {
|
#intern_info__initials {
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -1302,15 +1283,82 @@ ul {
|
|||||||
}
|
}
|
||||||
#intern_info__name {
|
#intern_info__name {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
}
|
||||||
.icon--star {
|
.icon--star {
|
||||||
fill: var(--orange);
|
fill: var(--orange);
|
||||||
}
|
}
|
||||||
#intern_info__score {
|
#stats_wrapper {
|
||||||
font-size: 1.5rem;
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
& > * {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.stat {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
&__display {
|
||||||
|
display: grid;
|
||||||
|
justify-items: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 4rem;
|
||||||
|
& > * {
|
||||||
|
grid-area: 1/1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__circle {
|
||||||
|
height: 100%;
|
||||||
|
stroke-width: 10;
|
||||||
|
overflow: visible;
|
||||||
|
stroke-dasharray: 400;
|
||||||
|
stroke-dashoffset: var(--progress, 400);
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
stroke-linecap: round;
|
||||||
|
transition: stroke-dashoffset 1s;
|
||||||
|
}
|
||||||
|
&__count {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: rgba(var(--text-color), 0.8);
|
||||||
|
font-size: 0.9rem;
|
||||||
|
max-width: 8ch;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#intern_rating {
|
||||||
|
.stat__circle {
|
||||||
|
fill: rgba(var(--text-color), 0.06);
|
||||||
|
stroke: var(--rating-color, --green);
|
||||||
|
}
|
||||||
|
.stat__count {
|
||||||
|
color: var(--rating-color, --green);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#intern_complete_tasks {
|
||||||
|
.stat__circle {
|
||||||
|
fill: #ff3d0010;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
.stat__count {
|
||||||
|
color: var(--orange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#intern_points {
|
||||||
|
.stat__circle {
|
||||||
|
fill: #6d83ff10;
|
||||||
|
stroke-dashoffset: 0;
|
||||||
|
}
|
||||||
|
.stat__count {
|
||||||
|
color: var(--nice-blue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#project_info {
|
#project_info {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@ -1739,8 +1787,8 @@ input[type="date"] {
|
|||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
border: rgba(var(--text-color), 0.2) solid thin;
|
border: none;
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.5rem;
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|||||||
86
index.html
86
index.html
@ -105,7 +105,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<img src="assets/working-intern.svg" alt="">
|
<img src="assets/working-intern.svg" alt="">
|
||||||
</div>
|
</div>
|
||||||
<div id="landing_tasks_wrapper" class="flex flex-direction-column justify-center"></div>
|
<div id="landing_tasks_wrapper" class="flex flex-direction-column justify-content-center"></div>
|
||||||
</div>
|
</div>
|
||||||
<article id="sign_in" class="inner-page hidden">
|
<article id="sign_in" class="inner-page hidden">
|
||||||
<section>
|
<section>
|
||||||
@ -878,7 +878,7 @@
|
|||||||
// displays a popup for asking permission. Use this instead of JS confirm
|
// displays a popup for asking permission. Use this instead of JS confirm
|
||||||
const getConfirmation = (title, options = {}) => {
|
const getConfirmation = (title, options = {}) => {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const { message = '', cancelText = 'Cancel', confirmText = 'OK' } = options
|
const { message = '', cancelText = 'Cancel', confirmText = 'OK', danger = false } = options
|
||||||
openPopup('confirmation_popup', true)
|
openPopup('confirmation_popup', true)
|
||||||
getRef('confirm_title').innerText = title;
|
getRef('confirm_title').innerText = title;
|
||||||
getRef('confirm_message').innerText = message;
|
getRef('confirm_message').innerText = message;
|
||||||
@ -886,6 +886,10 @@
|
|||||||
const confirmButton = getRef('confirmation_popup').querySelector('.confirm-button')
|
const confirmButton = getRef('confirmation_popup').querySelector('.confirm-button')
|
||||||
confirmButton.textContent = confirmText
|
confirmButton.textContent = confirmText
|
||||||
cancelButton.textContent = cancelText
|
cancelButton.textContent = cancelText
|
||||||
|
if (danger)
|
||||||
|
confirmButton.classList.add('button--danger')
|
||||||
|
else
|
||||||
|
confirmButton.classList.remove('button--danger')
|
||||||
confirmButton.onclick = () => {
|
confirmButton.onclick = () => {
|
||||||
closePopup()
|
closePopup()
|
||||||
resolve(true);
|
resolve(true);
|
||||||
@ -1142,7 +1146,7 @@
|
|||||||
<ul id="assigned_task_list">${renderedAssignedTasks}</ul>
|
<ul id="assigned_task_list">${renderedAssignedTasks}</ul>
|
||||||
</section>
|
</section>
|
||||||
` : ''}
|
` : ''}
|
||||||
<div id="dashboard_tasks_wrapper" class=${`flex flex-direction-column justify-center dashboard-view__item ${typeOfUser === 'intern' ? 'hidden' : ''}`}>${render.displayTasks(params?.category, params?.search)}</div>
|
<div id="dashboard_tasks_wrapper" class=${`flex flex-direction-column justify-content-center dashboard-view__item ${typeOfUser === 'intern' ? 'hidden' : ''}`}>${render.displayTasks(params?.category, params?.search)}</div>
|
||||||
<div id="projects_wrapper" class="grid gap-2 align-items-start dashboard-view__item hidden">${render.dashProjects()}</div>
|
<div id="projects_wrapper" class="grid gap-2 align-items-start dashboard-view__item hidden">${render.dashProjects()}</div>
|
||||||
<div id="intern_leaderboard_container" class="container-card dashboard-view__item hide-on-mobile">
|
<div id="intern_leaderboard_container" class="container-card dashboard-view__item hide-on-mobile">
|
||||||
<div class="container-header">
|
<div class="container-header">
|
||||||
@ -1975,7 +1979,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h4 class="task-title capitalize" data-editable data-edit-field="title">${title}</h4>
|
<h4 class="task-title capitalize" data-editable data-edit-field="title">${title}</h4>
|
||||||
<div class="assigned-interns">
|
<div class="assigned-interns">
|
||||||
<button class="button--outlined button--small button--colored" onclick="currentTask=this.closest('.admin-task');openPopup('intern_list_popup')">
|
<button class="button button--small button--colored" onclick="currentTask=this.closest('.admin-task');openPopup('intern_list_popup')">
|
||||||
<svg class="icon margin-right-0-3" 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="M11 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0-6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zM5 18c.2-.63 2.57-1.68 4.96-1.94l2.04-2c-.39-.04-.68-.06-1-.06-2.67 0-8 1.34-8 4v2h9l-2-2H5zm15.6-5.5l-5.13 5.17-2.07-2.08L12 17l3.47 3.5L22 13.91z"/></svg>
|
<svg class="icon margin-right-0-3" 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="M11 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0-6c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zM5 18c.2-.63 2.57-1.68 4.96-1.94l2.04-2c-.39-.04-.68-.06-1-.06-2.67 0-8 1.34-8 4v2h9l-2-2H5zm15.6-5.5l-5.13 5.17-2.07-2.08L12 17l3.47 3.5L22 13.91z"/></svg>
|
||||||
Assign intern
|
Assign intern
|
||||||
</button>
|
</button>
|
||||||
@ -2509,31 +2513,57 @@
|
|||||||
// opens a popup containing various intern information
|
// opens a popup containing various intern information
|
||||||
function showInternInfo(e) {
|
function showInternInfo(e) {
|
||||||
const internFloId = e.target.closest('.intern-card').dataset.internFloId;
|
const internFloId = e.target.closest('.intern-card').dataset.internFloId;
|
||||||
|
const { completedTasks = {}, active = true } = RIBC.getInternRecord(internFloId) || {}
|
||||||
const internName = RIBC.getInternList()[internFloId]
|
const internName = RIBC.getInternList()[internFloId]
|
||||||
const { completedTasks = [], active = true } = RIBC.getInternRecord(internFloId) || {}
|
const rating = RIBC.getInternRating(internFloId)
|
||||||
|
let completedTasksCount = 0;
|
||||||
|
let totalPoints = 0
|
||||||
|
for (const task in completedTasks) {
|
||||||
|
completedTasksCount++
|
||||||
|
totalPoints += completedTasks[task].points
|
||||||
|
}
|
||||||
renderElem(getRef('intern_info__wrapper'), html`
|
renderElem(getRef('intern_info__wrapper'), html`
|
||||||
<div id="intern_info__initials" class="intern-card__initials" style=${`--color: var(${getInternColor(internFloId)})`}>${internName.split(' ').map(v => v.charAt(0)).join('')}</div>
|
<div class="flex flex-direction-column align-items-center gap-1 text-center">
|
||||||
<h3 id="intern_info__name">${internName}</h3>
|
<div id="intern_info__initials" class="intern-card__initials" style=${`--color: var(${getInternColor(internFloId)})`}>${internName.split(' ').map(v => v.charAt(0)).join('')}</div>
|
||||||
|
<h3 id="intern_info__name">${internName}</h3>
|
||||||
|
</div>
|
||||||
<sm-copy id="intern_info__flo_id" value=${internFloId}></sm-copy>
|
<sm-copy id="intern_info__flo_id" value=${internFloId}></sm-copy>
|
||||||
<div id="update_intern_score" class="flex align-center">
|
<div id="stats_wrapper">
|
||||||
<svg class="icon icon--star 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 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 id="intern_rating" class="stat">
|
||||||
<h4 id="intern_info__score">0</h4>
|
<div class="stat__display">
|
||||||
|
<svg class="stat__circle" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="64" cy="64" r="63.5"/> </svg>
|
||||||
|
<span class="stat__count">${rating}%</h4>
|
||||||
|
</div>
|
||||||
|
<p>Rating</p>
|
||||||
|
</div>
|
||||||
|
<div id="intern_complete_tasks" class="stat">
|
||||||
|
<div class="stat__display">
|
||||||
|
<svg class="stat__circle" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="64" cy="64" r="63.5"/> </svg>
|
||||||
|
<span class="stat__count">${completedTasksCount}</h4>
|
||||||
|
</div>
|
||||||
|
<p>Task completed</p>
|
||||||
|
</div>
|
||||||
|
<div id="intern_points" class="stat">
|
||||||
|
<div class="stat__display">
|
||||||
|
<svg class="stat__circle" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <circle cx="64" cy="64" r="63.5"/> </svg>
|
||||||
|
<span class="stat__count">${totalPoints}</h4>
|
||||||
|
</div>
|
||||||
|
<p>Points earned</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`)
|
`)
|
||||||
openPopup('intern_info_popup');
|
openPopup('intern_info_popup');
|
||||||
// animate number counting up within 1s from 0 to the intern's score
|
// TODO: popup opening should return a promise
|
||||||
const scoreElem = getRef('intern_info__score')
|
let color = '--green';
|
||||||
const finalScore = RIBC.getInternRating(internFloId)
|
if (rating < 50) {
|
||||||
let score = 0;
|
color = '--danger-color'
|
||||||
const scoreInterval = setInterval(incrementNumber, 600 / finalScore)
|
} else if (rating < 80) {
|
||||||
function incrementNumber() {
|
color = '--orange'
|
||||||
scoreElem.textContent = score;
|
|
||||||
score++;
|
|
||||||
if (score > finalScore) {
|
|
||||||
clearInterval(scoreInterval)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
incrementNumber()
|
setTimeout(() => {
|
||||||
|
document.getElementById('intern_rating').style.setProperty('--progress', `${400 - (rating * 4)}`)
|
||||||
|
document.getElementById('intern_rating').style.setProperty('--rating-color', `var(${color})`)
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// opens a popup containing various project information
|
// opens a popup containing various project information
|
||||||
@ -2634,7 +2664,7 @@
|
|||||||
<div class="flex flex-direction-column gap-0-5 rating-part" data-intern-id=${intern}>
|
<div class="flex flex-direction-column gap-0-5 rating-part" data-intern-id=${intern}>
|
||||||
<h4>${RIBC.getInternList()[intern]}</h4>
|
<h4>${RIBC.getInternList()[intern]}</h4>
|
||||||
<div class="flex gap-0-5">
|
<div class="flex gap-0-5">
|
||||||
<sm-input type="number" min="0" max="50" class="flex-1" placeholder="Rate out of 50" error-text="Points must be between 0-50" autofocus required></sm-input>
|
<sm-input type="number" min="0" max="50" class="flex-1" placeholder="Rate out of 50" error-text="Points must be between 0-50" ?autofocus=${index === 0} required></sm-input>
|
||||||
<input class="flex-1" type="date" value=${formatDate(new Date())} placeholder="Completion date" aria-label="Set date of completion" required>
|
<input class="flex-1" type="date" value=${formatDate(new Date())} placeholder="Completion date" aria-label="Set date of completion" required>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -2646,7 +2676,7 @@
|
|||||||
}
|
}
|
||||||
function markTaskAsIncomplete(e) {
|
function markTaskAsIncomplete(e) {
|
||||||
currentTask = e.target.closest('.admin-task');
|
currentTask = e.target.closest('.admin-task');
|
||||||
getConfirmation('Mark this task as incomplete?', { message: 'Score given to participants regarding this task will also be removed', confirmText: 'Mark as incomplete' }).then(res => {
|
getConfirmation('Mark this task as incomplete?', { message: 'Score given to participants regarding this task will also be removed', confirmText: 'Mark as incomplete', danger: true }).then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
RIBC.admin.putTaskStatus('incomplete', appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
RIBC.admin.putTaskStatus('incomplete', appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
||||||
// TODO: remove task scores from intern rating
|
// TODO: remove task scores from intern rating
|
||||||
@ -2674,9 +2704,9 @@
|
|||||||
document.querySelectorAll('.rating-part').forEach((ratingPart) => {
|
document.querySelectorAll('.rating-part').forEach((ratingPart) => {
|
||||||
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
|
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
|
||||||
const internId = ratingPart.dataset.internId;
|
const internId = ratingPart.dataset.internId;
|
||||||
const score = 50 + parseInt(ratingPart.querySelector('sm-input').value.trim());
|
const points = 50 + parseInt(ratingPart.querySelector('sm-input').value.trim());
|
||||||
const completionDate = ratingPart.querySelector('input').value;
|
const completionDate = ratingPart.querySelector('input').value;
|
||||||
RIBC.admin.addTaskScore(internId, taskId, score, { completionDate })
|
RIBC.admin.addTaskScore(internId, taskId, points, { completionDate })
|
||||||
})
|
})
|
||||||
markTaskAsCompleted()
|
markTaskAsCompleted()
|
||||||
closePopup()
|
closePopup()
|
||||||
@ -2758,7 +2788,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (e.target.closest('.assigned-intern button')) {
|
else if (e.target.closest('.assigned-intern button')) {
|
||||||
getConfirmation('Do you want to unassign this intern from this task?', { confirmText: 'Unassign' }).then((result) => {
|
getConfirmation('Do you want to unassign this intern from this task?', { confirmText: 'Unassign', danger: true }).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
RIBC.admin.unassignInternFromTask(e.target.closest('.assigned-intern').dataset.floId, appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
RIBC.admin.unassignInternFromTask(e.target.closest('.assigned-intern').dataset.floId, appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
||||||
notify('Intern removed from the task')
|
notify('Intern removed from the task')
|
||||||
@ -2863,7 +2893,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
function removeThisTask() {
|
function removeThisTask() {
|
||||||
getConfirmation("Are you sure to delete this task?", { confirmText: 'Delete' }).then((result) => {
|
getConfirmation("Are you sure to delete this task?", { confirmText: 'Delete', danger: true }).then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
RIBC.admin.deleteTaskInMap(appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
RIBC.admin.deleteTaskInMap(appState.params.id, appState.params.branch, currentTask.dataset.taskId)
|
||||||
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
|
const taskId = `${appState.params.id}_${appState.params.branch}_${currentTask.dataset.taskId}`;
|
||||||
|
|||||||
@ -191,7 +191,7 @@
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Admin.addTaskScore = function (floID, taskId, score, details = {}) {
|
Admin.addTaskScore = function (floID, taskId, points, details = {}) {
|
||||||
if (!(floID in _.internList))
|
if (!(floID in _.internList))
|
||||||
return false;
|
return false;
|
||||||
if (!_.internRecord[floID])
|
if (!_.internRecord[floID])
|
||||||
@ -200,14 +200,14 @@
|
|||||||
completedTasks: {},
|
completedTasks: {},
|
||||||
}
|
}
|
||||||
_.internRecord[floID].completedTasks[taskId] = {
|
_.internRecord[floID].completedTasks[taskId] = {
|
||||||
score,
|
points,
|
||||||
...details
|
...details
|
||||||
};
|
};
|
||||||
let totalScore = 0;
|
let totalScore = 0;
|
||||||
for (const taskId in _.internRecord[floID].completedTasks) {
|
for (const taskId in _.internRecord[floID].completedTasks) {
|
||||||
totalScore += _.internRecord[floID].completedTasks[taskId].score;
|
totalScore += _.internRecord[floID].completedTasks[taskId].points;
|
||||||
}
|
}
|
||||||
_.internRating[floID] = totalScore;
|
_.internRating[floID] = parseInt(totalScore / (Object.keys(_.internRecord[floID].completedTasks).length || 1));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Admin.setInternStatus = function (floID, active = true) {
|
Admin.setInternStatus = function (floID, active = true) {
|
||||||
|
|||||||
2
scripts/ribc.min.js
vendored
2
scripts/ribc.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user