UI: Refactor course card list

pull/4344/head
Angel Fernando Quiroz Campos 2 years ago
parent 0ace78c403
commit fff73d490f
  1. 3
      assets/css/scss/index.scss
  2. 29
      assets/css/scss/molecules/_teacher_bar.scss
  3. 30
      assets/css/scss/organisms/_cards.scss
  4. 5
      assets/css/scss/organisms/_course_card.scss
  5. 38
      assets/vue/components/TeacherBar.vue
  6. 104
      assets/vue/components/course/CourseCard.vue
  7. 53
      assets/vue/components/course/CourseCardList.vue
  8. 3
      assets/vue/graphql/queries/CourseRelUser.js

@ -25,7 +25,10 @@
@import "molecules/course_tool";
@import "molecules/datepicker";
@import "molecules/empty_state";
@import "molecules/teacher_bar";
@import "organisms/cards";
@import "organisms/course_card";
@import "organisms/modals";
@import "organisms/sidebar";

@ -0,0 +1,29 @@
@layer components {
.teacher-bar {
@apply flex flex-wrap gap-4;
&__item {
@apply flex gap-0.5 items-center;
> div.p-avatar {
@apply flex-none;
}
}
&__item-caption {
@apply flex flex-col flex-grow text-caption;
span:first-child {
@apply line-clamp-1 font-semibold;
}
}
&--simple {
@apply flex-nowrap;
.teacher-bar__item {
@apply w-1/2;
}
}
}
}

@ -0,0 +1,30 @@
.p-card {
@apply rounded-lg shadow-lg;
.p-card-body {
@apply flex flex-col gap-4 p-4;
}
.p-card-header {
img {
@apply rounded-t-lg;
}
}
.p-card-title {
@apply text-body-2-bold line-clamp-2 min-h-[2rem];
}
.p-card-subtitle {
@apply text-body-1 text-gray-50;
}
.p-card-content {
&:empty {
@apply hidden;
}
}
.p-card-footer {
}
}

@ -0,0 +1,5 @@
@layer components {
.course-card {
@apply bg-gray-15;
}
}

@ -0,0 +1,38 @@
<template>
<div
class="teacher-bar"
:class="{ 'teacher-bar--simple': isSimpleLayout }"
>
<div
v-for="user in teachers"
:key="user.id"
class="teacher-bar__item"
>
<Avatar
:image="`${user.illustrationUrl}?w=80&h=80&fit=crop`"
shape="circle"
/>
<div
v-if="isSimpleLayout"
class="teacher-bar__item-caption"
>
<span v-text="user.fullName" />
<span v-t="'Coach'" />
</div>
</div>
</div>
</template>
<script setup>
import Avatar from 'primevue/avatar';
// eslint-disable-next-line no-undef
const props = defineProps({
teachers: {
required: true,
type: Array
}
});
const isSimpleLayout = props.teachers.length < 3;
</script>

@ -1,68 +1,35 @@
<template>
<v-card
v-if="course"
elevation="4"
>
<div class="">
<img class="object-cover w-full h-44" :src="course.illustrationUrl" />
</div>
<div class="p-4">
<div class="h-10 flex flex-row justify-between">
<div class="line-clamp-2 text-md w-5/6">
<router-link :to="{ name: 'CourseHome', params: {id: course._id, course: course}, query: { sid: sessionId } }">
<span v-if="session">
{{ session.name }} -
</span>
{{ course.title }}
</router-link>
</div>
<div>
<v-icon icon="mdi-dots-vertical" />
</div>
</div>
<div v-if="course.users" class="pt-6">
<div class="flex flex-row" v-if="course.users.edges.length">
<div class="flex flex-row pr-3" v-for="courseRelUser in course.users.edges">
<div class="pr-2">
<img class="inline-block h-8 w-8 rounded-full ring-2 ring-white"
:src="courseRelUser.node.user.illustrationUrl + '?w=80&h=80&fit=crop'"
alt=""
/>
</div>
<div v-if="course.users.edges.length < 3 " class="flex-col">
<div>
{{ courseRelUser.node.user.firstname }} {{ courseRelUser.node.user.lastname }}
</div>
</div>
</div>
</div>
</div>
<!-- <q-card-actions>-->
<!-- <q-btn-->
<!-- type="a"-->
<!-- :to="{ name: 'CourseHome', params: {id: course.id, course: course}}"-->
<!-- text-color="white"-->
<!-- color="primary"-->
<!-- label="Go"-->
<!-- />-->
<!-- </q-card-actions>-->
</div>
</v-card>
<Card class="course-card">
<template #header>
<img
:src="course.illustrationUrl"
:alt="course.title"
>
</template>
<template #title>
<router-link
:to="{ name: 'CourseHome', params: {id: course._id, course: course}, query: { sid: sessionId } }"
class="course-card__home-link"
>
<span v-if="session">
{{ session.name }} -
</span>
{{ course.title }}
</router-link>
</template>
<template #footer>
<TeacherBar :teachers="teachers" />
</template>
</Card>
</template>
<style scoped>
.my-card {
width: 100%;
max-width: 370px;
}
</style>
<script>
<script setup>
import Card from 'primevue/card';
import TeacherBar from '../TeacherBar';
export default {
name: 'CourseCard',
props: {
// eslint-disable-next-line no-undef
const props = defineProps(
{
course: Object,
session: Object,
sessionId: {
@ -70,12 +37,13 @@ export default {
required: false,
default: 0
}
},
data() {
return {
};
},
methods: {
}
};
);
const teachers = props.course.users.edges.map(
edge => ({
id: edge.node.id,
...edge.node.user,
})
);
</script>

@ -1,46 +1,19 @@
<template>
<div
v-for="course in courses"
:key="course.id"
>
<CourseCard
:course="course"
/>
</div>
<CourseCard
v-for="course in courses"
:key="course.id"
:course="course"
/>
</template>
<script>
<script setup>
import CourseCard from './CourseCard.vue';
export default {
name: 'CourseCardList',
components: {
CourseCard
},
props: {
courses: Array,
},
data() {
return {
deck: false
};
// eslint-disable-next-line no-undef
defineProps({
courses: {
type: Array,
default: () => [],
},
methods: {
isList: function (){
if (!this.deck) {
return 'primary';
}
return 'secondary';
},
isDeck: function (){
if (this.deck) {
return 'primary';
}
return 'secondary';
},
changeLayout: function () {
this.deck = !this.deck;
},
}
};
});
</script>

@ -17,8 +17,7 @@ export const GET_COURSE_REL_USER = gql`
user {
illustrationUrl,
username,
firstname,
lastname
fullName
}
}
}

Loading…
Cancel
Save