add assignment completion ui

This commit is contained in:
Yisroel Baum 2026-08-15 22:52:13 +03:00
parent 0d9e2fa71b
commit 9f53245987
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
3 changed files with 335 additions and 22 deletions

View file

@ -35,6 +35,10 @@ function formatDate(value: string): string {
timeZone: 'UTC',
}).format(new Date(`${value}T00:00:00Z`))
}
async function completeAssignment(assignmentId: number): Promise<void> {
await schedulesStore.setAssignmentCompleted(assignmentId, true)
}
</script>
<template>
@ -76,15 +80,19 @@ function formatDate(value: string): string {
</p>
<ul v-else class="today-assignment-list" aria-label="Today's assignments">
<li v-for="assignment in assignmentsForDate" :key="assignment.id">
<RouterLink
class="today-assignment-link"
:to="{
name: 'schedule-detail',
params: { scheduleId: assignment.schedule.id },
}"
>
<article class="today-assignment">
<li
v-for="assignment in assignmentsForDate"
:key="assignment.id"
:data-today-assignment="assignment.id"
>
<article class="today-assignment">
<RouterLink
class="today-assignment-link"
:to="{
name: 'schedule-detail',
params: { scheduleId: assignment.schedule.id },
}"
>
<div class="today-assignment__heading">
<p>{{ assignment.schedule.set.name }}</p>
<span class="today-assignment__kind">{{ assignment.element.kind }}</span>
@ -96,8 +104,30 @@ function formatDate(value: string): string {
Open schedule
<span aria-hidden="true"></span>
</span>
</article>
</RouterLink>
</RouterLink>
<div class="today-assignment__completion">
<p
v-if="schedulesStore.assignmentCompletionError(assignment.id) !== null"
class="assignment-completion-error"
role="alert"
>
{{ schedulesStore.assignmentCompletionError(assignment.id) }}
</p>
<button
type="button"
class="assignment-completion-button"
:aria-label="`Mark ${assignment.element.path.join(' / ')} complete`"
:disabled="schedulesStore.isAssignmentCompletionPending(assignment.id)"
@click="completeAssignment(assignment.id)"
>
{{
schedulesStore.isAssignmentCompletionPending(assignment.id)
? 'Completing...'
: 'Mark complete'
}}
</button>
</div>
</article>
</li>
</ul>
</section>
@ -313,12 +343,13 @@ function formatDate(value: string): string {
.today-assignment-link {
display: block;
height: 100%;
border-radius: 1rem;
color: inherit;
text-decoration: none;
}
.today-assignment {
display: flex;
flex-direction: column;
height: 100%;
padding: 1.4rem;
border: 1px solid rgb(24 48 41 / 12%);
@ -330,7 +361,7 @@ function formatDate(value: string): string {
transform 160ms ease;
}
.today-assignment-link:hover .today-assignment {
.today-assignment:hover {
border-color: rgb(40 92 78 / 35%);
transform: translateY(-2px);
}
@ -377,6 +408,48 @@ function formatDate(value: string): string {
font-weight: 750;
}
.today-assignment__completion {
display: grid;
justify-items: start;
gap: 0.65rem;
margin-top: auto;
padding-top: 1.15rem;
border-top: 1px solid rgb(24 48 41 / 10%);
}
.assignment-completion-button {
min-height: 2.5rem;
padding: 0.6rem 0.9rem;
border: 1px solid rgb(24 58 49 / 28%);
border-radius: 0.7rem;
color: #fffdf7;
background: #285c4e;
font-size: 0.78rem;
font-weight: 800;
cursor: pointer;
}
.assignment-completion-button:hover:not(:disabled) {
background: #183a31;
}
.assignment-completion-button:focus-visible {
outline: 3px solid rgb(86 127 112 / 34%);
outline-offset: 0.25rem;
}
.assignment-completion-button:disabled {
cursor: wait;
opacity: 0.65;
}
.assignment-completion-error {
margin: 0;
color: #9b3f32;
font-size: 0.76rem;
font-weight: 700;
}
.sets-catalog__description {
max-width: 38rem;
margin: 1.5rem 0 0;