CLASSROOMIO-T-4: Add deadline and show it was late or early
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
QUESTION_TYPES,
|
QUESTION_TYPES,
|
||||||
} from '../../../../Question/constants';
|
} from '../../../../Question/constants';
|
||||||
import { filterOutDeleted } from './functions';
|
import { filterOutDeleted } from './functions';
|
||||||
|
import Date from '../../../../Form/Date.svelte';
|
||||||
// import EditContent from "../../../../EditContent/index.svelte";
|
// import EditContent from "../../../../EditContent/index.svelte";
|
||||||
// import readme from "../../readme.js";
|
// import readme from "../../readme.js";
|
||||||
|
|
||||||
@@ -100,11 +101,12 @@
|
|||||||
/>
|
/>
|
||||||
<DateTime
|
<DateTime
|
||||||
label="Due by"
|
label="Due by"
|
||||||
bind:value={$questionnaire.due_by}
|
|
||||||
placeholder="2021-03-25"
|
|
||||||
className="w-50"
|
className="w-50"
|
||||||
useTime={true}
|
value={$questionnaire.due_by}
|
||||||
onChange={() => ($questionnaire.is_due_by_dirty = true)}
|
onInput={(e) => {
|
||||||
|
$questionnaire.due_by = e.target.value;
|
||||||
|
$questionnaire.is_due_by_dirty = true;
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<EditContent
|
<EditContent
|
||||||
writeLabel="Description"
|
writeLabel="Description"
|
||||||
|
|||||||
@@ -116,7 +116,22 @@
|
|||||||
<div
|
<div
|
||||||
class="hover:bg-gray-100 border-b border-t-0 border-l-0 border-r-0 border-gray-300 p-3"
|
class="hover:bg-gray-100 border-b border-t-0 border-l-0 border-r-0 border-gray-300 p-3"
|
||||||
>
|
>
|
||||||
<p class="font-bold text-lg">Details</p>
|
<p class="font-bold text-lg">
|
||||||
|
Details
|
||||||
|
{#if data.isEarly}
|
||||||
|
<span
|
||||||
|
class="ml-2 text-sm badge rounded-sm px-2 bg-green-500 text-white"
|
||||||
|
>
|
||||||
|
early
|
||||||
|
</span>
|
||||||
|
{:else}
|
||||||
|
<span
|
||||||
|
class="ml-2 badge text-sm rounded-sm px-2 bg-red-500 text-white"
|
||||||
|
>
|
||||||
|
late
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center text-sm p-3">
|
<div class="flex items-center text-sm p-3">
|
||||||
@@ -148,3 +163,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.badge {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import marked from 'marked';
|
||||||
import { fly } from 'svelte/transition';
|
import { fly } from 'svelte/transition';
|
||||||
import { group, course } from '../../../store';
|
import { group, course } from '../../../store';
|
||||||
import { questionnaire } from '../store/exercise';
|
import { questionnaire } from '../store/exercise';
|
||||||
@@ -198,14 +199,23 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
|
|
||||||
<p class="mx-2">All required</p>
|
<p class="mx-2">All required</p>
|
||||||
|
{#if $questionnaire.due_by}
|
||||||
|
|
|
||||||
|
<p class="mx-2">
|
||||||
|
<strong>Due by:</strong>
|
||||||
|
{new Date($questionnaire.due_by).toLocaleString()}
|
||||||
|
</p>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="text-lg mt-3">{$questionnaire.description}</p>
|
<article class="preview prose prose-sm sm:prose p-2">
|
||||||
|
{@html marked($questionnaire.description || 'No desription')}
|
||||||
|
</article>
|
||||||
|
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
onClick={handleStart}
|
onClick={handleStart}
|
||||||
label="Start"
|
label="Start"
|
||||||
className="my-5"
|
className="my-5 float-right"
|
||||||
type="button"
|
type="button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
export let placeholder;
|
export let placeholder;
|
||||||
export let value;
|
export let value;
|
||||||
export let className = '';
|
export let className = '';
|
||||||
export let onChange = () => {}; // This is to know if element is 'dirty'
|
export let onInput = () => {};
|
||||||
|
$: console.log(`value`, value);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="block {className}">
|
<label class="block {className}">
|
||||||
<span class="text-gray-700">{label}</span>
|
<span class="text-gray-700">{label}</span>
|
||||||
<input
|
<input
|
||||||
bind:value
|
bind:value
|
||||||
|
on:input={onInput}
|
||||||
{placeholder}
|
{placeholder}
|
||||||
type="datetime-local"
|
type="datetime-local"
|
||||||
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
||||||
on:blur={onChange}
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
@@ -142,6 +142,7 @@
|
|||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
color: var(--main-primary-color);
|
||||||
padding: 0 1.5em;
|
padding: 0 1.5em;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -61,6 +61,10 @@
|
|||||||
fill: var(--main-primary-color);
|
fill: var(--main-primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.prose a {
|
||||||
|
color: var(--main-primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
.success :global(svg.carbon-icon) {
|
.success :global(svg.carbon-icon) {
|
||||||
fill: green;
|
fill: green;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
import { formatAnswers } from '../../../components/Course/function';
|
import { formatAnswers } from '../../../components/Course/function';
|
||||||
import { snackbarStore } from '../../../components/Snackbar/store';
|
import { snackbarStore } from '../../../components/Snackbar/store';
|
||||||
import { SNACKBAR_SEVERITY } from '../../../components/Snackbar/constants';
|
import { SNACKBAR_SEVERITY } from '../../../components/Snackbar/constants';
|
||||||
|
import Date from '../../../components/Form/Date.svelte';
|
||||||
|
import isSubmissionEarly from '../../../utils/functions/isSubmissionEarly';
|
||||||
|
import formatDate from '../../../utils/functions/formatDate';
|
||||||
|
|
||||||
const flipDurationMs = 300;
|
const flipDurationMs = 300;
|
||||||
|
|
||||||
@@ -188,12 +191,22 @@
|
|||||||
const sectionById = {};
|
const sectionById = {};
|
||||||
|
|
||||||
for (const submission of submissions) {
|
for (const submission of submissions) {
|
||||||
const { id, exercise, course, answers, groupmember, status_id } =
|
const {
|
||||||
submission;
|
id,
|
||||||
|
created_at,
|
||||||
|
exercise,
|
||||||
|
course,
|
||||||
|
answers,
|
||||||
|
groupmember,
|
||||||
|
status_id,
|
||||||
|
} = submission;
|
||||||
|
const isEarly = isSubmissionEarly(created_at, exercise.due_by);
|
||||||
|
|
||||||
const submissionItem = {
|
const submissionItem = {
|
||||||
id,
|
id,
|
||||||
statusId: status_id,
|
statusId: status_id,
|
||||||
|
isEarly,
|
||||||
|
submittedAt: formatDate(created_at),
|
||||||
exercise: {
|
exercise: {
|
||||||
id: exercise.id,
|
id: exercise.id,
|
||||||
title: exercise.title,
|
title: exercise.title,
|
||||||
@@ -205,10 +218,11 @@
|
|||||||
title: exercise.lesson.title,
|
title: exercise.lesson.title,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
console.log(`answers`, answers);
|
|
||||||
submissionIdData[id] = {
|
submissionIdData[id] = {
|
||||||
id,
|
id,
|
||||||
status_id,
|
status_id,
|
||||||
|
isEarly,
|
||||||
title: exercise.title,
|
title: exercise.title,
|
||||||
student: submissionItem.student,
|
student: submissionItem.student,
|
||||||
questions: exercise.questions,
|
questions: exercise.questions,
|
||||||
@@ -281,11 +295,16 @@
|
|||||||
>
|
>
|
||||||
{#each items as item (item.id)}
|
{#each items as item (item.id)}
|
||||||
<div
|
<div
|
||||||
class="border border-grey-700 w-full my-2 mx-0 rounded-md bg-white py-2 px-3"
|
class="border {item.isEarly
|
||||||
|
? 'border-grey-700'
|
||||||
|
: 'border-red-700'} w-full my-2 mx-0 rounded-md bg-white py-2 px-3"
|
||||||
animate:flip={{ duration: flipDurationMs }}
|
animate:flip={{ duration: flipDurationMs }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex items-center no-underline hover:underline text-black mb-2"
|
class="flex items-center cursor-pointer text-black mb-2"
|
||||||
|
on:click={() => {
|
||||||
|
goto(`${$page.path}?submissionId=${item.id}`);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
alt="Student avatar"
|
alt="Student avatar"
|
||||||
@@ -310,6 +329,15 @@
|
|||||||
{`${item.tutor ? 'created by' + item.tutor.name : ''}`}
|
{`${item.tutor ? 'created by' + item.tutor.name : ''}`}
|
||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
|
<p class="text-gray-500 text-xs">
|
||||||
|
{item.submittedAt}
|
||||||
|
</p>
|
||||||
|
<!-- <div class="badge rounded-md px-2 bg-green-500 text-white">
|
||||||
|
early
|
||||||
|
</div>
|
||||||
|
<div class="badge rounded-md px-2 bg-red-600 text-white">
|
||||||
|
late
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export default (date) => {
|
||||||
|
const d = new Date(date);
|
||||||
|
|
||||||
|
const ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(d);
|
||||||
|
const mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(d);
|
||||||
|
const da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(d);
|
||||||
|
|
||||||
|
// return `${ye}-${mo}-${da} ${d.toLocaleTimeString('en-US')}`;
|
||||||
|
return new Intl.DateTimeFormat('en-US', {
|
||||||
|
dateStyle: 'full',
|
||||||
|
timeStyle: 'medium',
|
||||||
|
}).format(d);
|
||||||
|
};
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export default (created_at, due_date) => {
|
||||||
|
return !!due_date
|
||||||
|
? !!(new Date(created_at).getTime() <= new Date(due_date).getTime())
|
||||||
|
: true;
|
||||||
|
};
|
||||||
@@ -10,9 +10,10 @@ export function fetchSubmissions(course_id) {
|
|||||||
.select(
|
.select(
|
||||||
`
|
`
|
||||||
id,
|
id,
|
||||||
|
created_at,
|
||||||
answers:question_answer(*),
|
answers:question_answer(*),
|
||||||
exercise:exercise_id(
|
exercise:exercise_id(
|
||||||
id, title,
|
id, title, due_by,
|
||||||
lesson:lesson_id(id, title),
|
lesson:lesson_id(id, title),
|
||||||
questions:question(
|
questions:question(
|
||||||
*,
|
*,
|
||||||
|
|||||||
Reference in New Issue
Block a user