Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #210 from MartinKanera/feat/admin
Browse files Browse the repository at this point in the history
merge: from admin
  • Loading branch information
MartinKanera authored Dec 2, 2020
2 parents 1913e15 + 077f79c commit 490cbcb
Show file tree
Hide file tree
Showing 70 changed files with 5,773 additions and 3,945 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
"eslint.alwaysShowStatus": true,
"eslint.lintTask.enable": true,
"eslint.packageManager": "yarn",
"vetur.experimental.templateInterpolationService": true
"vetur.experimental.templateInterpolationService": true,
"compile-hero.disable-compile-files-on-did-save-code": true
}
28 changes: 28 additions & 0 deletions components/admin-project/admin-project.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.admin-project
@apply p-4 leading-5
@apply bg-ps-secondary shadow w-full rounded-lg
@apply flex flex-col

@screen lg
@apply flex-row items-center

a:link
@apply text-ps-mint

a:hover
@apply text-ps-green

.info
@apply flex items-center

.profile-picture
@apply rounded-full border-2 border-solid border-ps-green mr-2

.actions
@apply mt-2
@apply flex justify-between flex-row-reverse
@apply text-ps-white capitalize

@screen lg
@apply m-0
@apply items-center
198 changes: 198 additions & 0 deletions components/admin-project/admin-project.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<template lang="pug">
.admin-project
.info.flex-1
img.profile-picture(:src='profilePicture', width='48')
.flex.justify-between.flex-1(class='lg:justify-between')
.flex.flex-col.justify-center
span.text-ps-green.font-bold.text-lg {{ displayName }}
span.text-ps-white {{ title }}
.flex.flex-col.text-ps-white.items-end(class='lg:flex-row lg:mr-4 lg:items-center')
span(class='lg:mr-4') posudky: {{ reviews.length }}/
span.text-ps-green 4
span(v-if='submittedDate') {{ getDate(submittedDate) }}
span(v-else) není odevzdán
.actions
nuxt-link(to='idk')
ps-btn.self-start(text) projekt
template(#icon-right)
chevron-icon(:size='18')/
ps-btn.self-start(text, @click='openModal') detail
template(#icon-right)
details-icon(:size='18')/
ps-modal.text-ps-white.leading-6(v-model='detailsModal')
.flex.flex-col
span.text-ps-green.text-2xl {{ projectToUpdate.title }}
span.mb-8 {{ displayName }}
ps-text-field.mb-4(v-model='projectToUpdate.title', name='projectTitle', label='Název projektu')
span.text-ps-green Viditelnost projektu
ps-select.mb-4(v-model='projectToUpdate.publicProject', :options='projectPublicity')
span.text-ps-green Vedoucí projektu
ps-select.mb-4(v-model='projectToUpdate.teacherId', placeholder='Vedoucí projektu', :options='deltaTeachers')
span.text-ps-green Oponent
ps-select.mb-4(v-model='projectToUpdate.opponentId', placeholder='Oponent', :options='teachers')
.flex.flex-col
span.text-ps-green.text-lg(v-if='reviews.length > 0') Odevzdaná hodnocení
span(v-for='review in reviewsView') {{ review.displayName }} -
a.ml-1(:href='review.publicUrl') {{ review.fileName }}
ps-btn.self-end(@click='updateProject', :loading='btnLoading', :disabled='btnLoading') Uložit změny
</template>

<script lang="ts">
import { defineComponent, ref } from 'nuxt-composition-api';
import firebase from 'firebase/app';
import 'firebase/firestore';
import 'firebase/auth';
import detailsIcon from 'vue-material-design-icons/AccountDetails.vue';
import chevronIcon from 'vue-material-design-icons/ChevronRight.vue';
import axios from 'axios';
export default defineComponent({
components: {
detailsIcon,
chevronIcon,
},
props: {
projectId: {
type: String,
required: true,
},
currentYear: {
type: firebase.firestore.Timestamp,
required: true,
},
opponentId: {
type: String,
required: true,
},
publicProject: {
type: Boolean,
required: true,
},
reviews: {
type: Array,
default: () => [],
},
studentId: {
type: String,
required: true,
},
submittedDate: {
type: firebase.firestore.Timestamp || null,
default: null,
},
teacherId: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
displayName: {
type: String,
required: true,
},
profilePicture: {
type: String,
required: true,
},
teachers: {
type: Array,
default: () => [],
},
},
// { projectId, currentYear, opponentId, publicProject, reviews, studentId, submittedDate, teacherId, title, displayName, profilePicture, teachers }
setup({ projectId, opponentId, publicProject, teacherId, title, teachers, reviews }) {
const projectToUpdate = ref({ opponentId, publicProject: publicProject.toString(), teacherId, title });
const getDate = (timeStamp: firebase.firestore.Timestamp) => new Date(timeStamp?.toMillis()).toString().substr(4, 11);
// @ts-ignore
const deltaTeachers = ref(teachers.filter((teacher) => !teacher.extern));
const btnLoading = ref(false);
const updateProject = async () => {
btnLoading.value = true;
try {
await axios.put(
`/api/project/${projectId}`,
{
opponentId: projectToUpdate.value.opponentId,
public: JSON.parse(projectToUpdate.value.publicProject),
teacherId: projectToUpdate.value.teacherId,
title: projectToUpdate.value.title,
},
{
headers: {
authorization: `Bearer ${await firebase.auth().currentUser?.getIdToken()}`,
},
},
);
detailsModal.value = false;
} catch (e) {
console.error(e);
}
btnLoading.value = false;
};
const detailsModal = ref(false);
const reviewsView = ref(undefined);
const openModal = async () => {
detailsModal.value = true;
if (reviewsView.value || reviews.length === 0) return;
const teacherIds = [teacherId];
if (opponentId !== '') teacherIds.push(opponentId);
try {
const teachers = (await firebase.firestore().collection('users').where(firebase.firestore.FieldPath.documentId(), 'in', teacherIds).get()).docs;
const reviewsData = (
await axios.get(`/api/reviews/${projectId}`, {
headers: {
authorization: `Bearer ${await firebase.auth().currentUser?.getIdToken()}`,
},
})
).data;
// @ts-ignore
reviewsView.value = reviewsData.map((review) => {
return {
...review,
// @ts-ignore
displayName: teachers.find((teacher) => review.teacherId === teacher.id || review.opponentId === teacher.id)?.data()?.displayName,
};
});
} catch (e) {
console.error(e);
}
};
const projectPublicity = [
{ placeholder: 'Private', value: 'false' },
{ placeholder: 'Veřejný', value: 'true' },
];
return {
getDate,
detailsModal,
updateProject,
projectToUpdate,
deltaTeachers,
openModal,
reviewsView,
projectPublicity,
btnLoading,
};
},
});
</script>

<style lang="sass" src="./admin-project.sass" scoped />
9 changes: 8 additions & 1 deletion components/admin-stats/admin-stats.sass
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
.admin-stats
@apply m-2 p-4 h-28 shadow rounded-lg
@apply m-2 p-4 shadow rounded-lg
@apply flex items-center justify-between bg-ps-secondary text-ps-white

@screen lg
@apply h-28

flex: 0 1 32%

.spinner
-webkit-user-select: none
-ms-user-select: none
user-select: none

.max
@apply text-ps-green text-2xl
8 changes: 7 additions & 1 deletion components/admin-stats/admin-stats.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<template lang="pug">
.admin-stats
slot.placeholder
div
.spinner(v-if='loading')
img.animate-spin.mx-auto(src='/loader.svg', width='36')
div(v-else)
span {{ currentCount }}/
span.max {{ maxCount }}
</template>
Expand All @@ -19,6 +21,10 @@ export default defineComponent({
type: Number,
default: 0,
},
loading: {
type: Boolean,
default: false,
},
},
});
</script>
Expand Down
21 changes: 21 additions & 0 deletions components/login-form/login-form.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.login-form
@apply text-ps-white
@apply flex flex-col w-full

.header
@apply text-ps-green text-2xl
@apply self-center
@apply mb-4

button
@apply text-ps-primary
@apply bg-ps-white #{!important}

&.shrink
@apply py-0 #{!important}

.blank
content: ''
width: 24px
height: 24px

Loading

0 comments on commit 490cbcb

Please sign in to comment.