elearning/Frontend-Learner/components/discovery/CategorySidebar.vue

80 lines
2.8 KiB
Vue

<script setup lang="ts">
/**
* @file CategorySidebar.vue
* @description Sidebar for filtering courses by category
*/
const props = defineProps<{
categories: any[];
modelValue: number[]; // selectedCategoryIds
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: number[]): void;
}>();
const showAllCategories = ref(false);
const getLocalizedText = (text: any) => {
if (!text) return ''
if (typeof text === 'string') return text
return text.th || text.en || ''
}
</script>
<template>
<div class="bg-white rounded-2xl shadow-sm border border-slate-200 overflow-hidden">
<q-expansion-item
expand-separator
:label="`หมวดหมู่ (${modelValue.length})`"
class="font-bold text-slate-900"
header-class="bg-white"
text-color="slate-900"
:header-style="{ color: '#0f172a' }"
default-opened
>
<q-list class="bg-white border-t border-slate-200">
<q-item
v-for="cat in (showAllCategories ? categories : categories.slice(0, 4))"
:key="cat.id"
tag="label"
clickable
v-ripple
dense
>
<q-item-section avatar>
<q-checkbox
:model-value="modelValue"
@update:model-value="(val) => emit('update:modelValue', val)"
:val="cat.id"
color="primary"
dense
class="checkbox-visible"
/>
</q-item-section>
<q-item-section>
<q-item-label class="text-sm font-medium text-slate-900">{{ getLocalizedText(cat.name) }}</q-item-label>
</q-item-section>
</q-item>
<!-- Show More/Less Button -->
<q-item
v-if="categories.length > 4"
clickable
v-ripple
@click="showAllCategories = !showAllCategories"
class="text-blue-600 font-bold text-sm"
>
<q-item-section>
<div class="flex items-center gap-1">
{{ showAllCategories ? 'แสดงน้อยลง' : 'แสดงเพิ่มเติม' }}
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" :class="showAllCategories ? 'rotate-180' : ''">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</div>
</q-item-section>
</q-item>
</q-list>
</q-expansion-item>
</div>
</template>