Skip to content

Commit

Permalink
project status on homescreen
Browse files Browse the repository at this point in the history
  • Loading branch information
reyniersbram committed May 16, 2024
1 parent eb1c8b5 commit a8989c6
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 38 deletions.
23 changes: 6 additions & 17 deletions frontend/src/components/home/cards/DeadlinesCard.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
<template>
<HomeScreenCard :title="'homescreen.deadlines'">
<DeadlineItem
v-for="deadline in deadlines"
:deadline="deadline"
:key="deadline.project.id"
/>
<DeadlineItem v-for="project in filteredProjects" :project="project" :key="project.id" />
</HomeScreenCard>
</template>

<script setup lang="ts">
import HomeScreenCard from "@/components/home/cards/HomeScreenCard.vue";
import DeadlineItem from "@/components/home/listcontent/DeadlineItem.vue";
import { type Deadline } from "@/models/Project";
import { useProjectsQuery } from "@/queries/Project";
import { computed } from "vue";
const { data: projects } = useProjectsQuery();
const deadlines = computed<Deadline[]>(() => {
const filteredProjects = computed(() => {
if (!projects.value) return [];
return (
[...projects.value.as_student, ...projects.value.as_instructor]
.filter((project) => project.deadline > new Date())
.sort((a, b) => a.deadline.getTime() - b.deadline.getTime())
.slice(0, 5)
.map((project) => ({
project,
status: "none",
})) || []
);
return [...projects.value.as_student, ...projects.value.as_instructor]
.filter((project) => project.deadline > new Date())
.sort((a, b) => a.deadline.getTime() - b.deadline.getTime())
.slice(0, 5);
});
</script>
48 changes: 31 additions & 17 deletions frontend/src/components/home/listcontent/DeadlineItem.vue
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
<template>
<div class="projectbtn" @click="navigateToProject">
<div :class="getBackgroundClass()"></div>
<div :class="submissionToClass(latestSubmissionStatus)"></div>
<div class="leftcontent">
<h3>{{ deadline.project.name }}</h3>
<h3>{{ project.name }}</h3>
<p v-if="!isSubjectLoading" class="p">{{ subject!.name }}</p>
</div>
<div class="rightcontent">
{{ $d(deadline.project.deadline, "short") }}
{{ $d(project.deadline, "short") }}
</div>
</div>
</template>

<script setup lang="ts">
import { type Deadline } from "@/models/Project";
import { useSubjectQuery } from "@/queries/Subject";
import { computed, toRefs } from "vue";
import router from "@/router";
import { toRefs } from "vue";
import type Project from "@/models/Project";
import type Submission from "@/models/Submission";
import { Status } from "@/models/Submission";
import { useSubjectQuery } from "@/queries/Subject";
import { useProjectSubmissionsQuery } from "@/queries/Submission";
const props = defineProps<{
deadline: Deadline;
project: Project;
}>();
const { deadline } = toRefs(props);
const { project } = toRefs(props);
const { data: submissions } = useProjectSubmissionsQuery(computed(() => project.value.id));
const { data: subject, isLoading: isSubjectLoading } = useSubjectQuery(
() => deadline.value.project.subject_id
);
const latestSubmissionStatus = computed(() => {
if (!submissions.value || submissions.value.length === 0) return null;
return [...submissions.value].sort((a, b) => b.date.getTime() - a.date.getTime())[0];
});
const getBackgroundClass = () => {
const { data: subject, isLoading: isSubjectLoading } = useSubjectQuery(project.value.subject_id);
function submissionToClass(submission: Submission | null) {
return {
block: true,
accepted: deadline.value.status === "accepted",
rejected: deadline.value.status === "rejected",
none: deadline.value.status === "none",
in_progress: submission?.status === Status.InProgress,
accepted: submission?.status === Status.Accepted,
rejected: submission?.status === Status.Rejected || submission?.status === Status.Crashed,
none: !submission,
};
};
}
const navigateToProject = () => {
router.push(`/project/${deadline.value.project.id}`);
router.push(`/project/${project.value.id}`);
};
</script>

Expand Down Expand Up @@ -74,6 +83,11 @@ const navigateToProject = () => {
.rejected {
background-color: darkred;
}
.in_progress {
background-color: orange;
}
.leftcontent {
margin-left: 20px;
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/queries/Group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export function useProjectGroupQuery(
return useQuery<Group | null, Error>({
queryKey: computed(() => PROJECT_USER_GROUP_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getGroupWithProjectId(groups.value!, toValue(projectId)!),
enabled: !!toValue(projectId) && groups.value !== undefined,
enabled: () => !!toValue(projectId) && groups.value !== undefined,
});
}

Expand Down
22 changes: 21 additions & 1 deletion frontend/src/queries/Submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import type { UseMutationReturnType, UseQueryReturnType } from "@tanstack/vue-qu
import { createSubmission, getFiles, getSubmission, getSubmissions } from "@/services/submission";
import type Submission from "@/models/Submission";
import type FileInfo from "@/models/File";
import { useProjectGroupQuery } from "./Group";

function SUBMISSION_QUERY_KEY(submissionId: number): (string | number)[] {
return ["submission", submissionId];
}

function SUBMISSIONS_QUERY_KEY(groupId: number): (string | number)[] {
return ["submissions", groupId];
return ["submissions", "group", groupId];
}

function PROJECT_SUBMISSIONS_QUERY_KEY(projectId: number): (string | number)[] {
return ["submissions", "project", projectId];
}

function FILES_QUERY_KEY(submissionId: number): (string | number)[] {
Expand Down Expand Up @@ -45,6 +50,21 @@ export function useSubmissionsQuery(
});
}

/**
* Query composable for fetching all submissions of the group of the current user
* in the project with the given id
*/
export function useProjectSubmissionsQuery(
projectId: MaybeRefOrGetter<number | undefined>
): UseQueryReturnType<Submission[], Error> {
const { data: group } = useProjectGroupQuery(projectId);
return useQuery<Submission[], Error>({
queryKey: computed(() => PROJECT_SUBMISSIONS_QUERY_KEY(toValue(projectId)!)),
queryFn: () => getSubmissions(group.value!.id),
enabled: () => !!toValue(projectId),
});
}

/**
* Query composable for fetching files for a submission
*/
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/services/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,28 @@ import type Submission from "@/models/Submission";
import { authorized_fetch } from ".";
import type FileInfo from "@/models/File";

function initSubmissionDate(submission: Submission): Submission {
return { ...submission, date: new Date(submission.date) };
}

/**
* Fetches the submission with the given ID.
*/
export async function getSubmission(submissionId: number): Promise<Submission> {
return authorized_fetch(`/api/submissions/${submissionId}`, { method: "GET" });
const result = await authorized_fetch<Submission>(`/api/submissions/${submissionId}`, {
method: "GET",
});
return initSubmissionDate(result);
}

/**
* Fetches all submissions of a group.
*/
export async function getSubmissions(groupId: number): Promise<Submission[]> {
return authorized_fetch(`/api/groups/${groupId}/submissions`, { method: "GET" });
const result = await authorized_fetch<Submission[]>(`/api/groups/${groupId}/submissions`, {
method: "GET",
});
return result.map(initSubmissionDate);
}

/**
Expand Down

0 comments on commit a8989c6

Please sign in to comment.