elearning/Frontend-Learner/components/discovery/CategorySidebar.vue
supalerk-ar66 1eeec4d22c
Some checks failed
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Failing after 1m16s
Build and Deploy Frontend Learner / Deploy Frontend Learner to Server (push) Has been skipped
feat: Add CategorySidebar component to filter courses by category with show more/less functionality.
2026-02-10 10:28:49 +07:00

149 lines
4 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="category-sidebar-root border rounded-2xl overflow-hidden shadow-sm">
<q-expansion-item
expand-separator
:label="`หมวดหมู่ (${modelValue.length})`"
class="category-sidebar-expansion"
header-class="category-sidebar-header"
default-opened
>
<q-list class="category-sidebar-list border-t">
<q-item
v-for="cat in showAllCategories ? categories : categories.slice(0, 4)"
:key="cat.id"
tag="label"
clickable
v-ripple
dense
class="category-item"
>
<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="category-item-label text-sm font-medium">
{{ 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="show-more-item font-bold text-sm"
>
<q-item-section>
<div class="flex items-center gap-1 text-blue-600 dark:text-blue-400">
{{ 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>
<style scoped>
/* Base Styles - Rely on main.css variables */
.category-sidebar-root {
background-color: var(--bg-surface);
border-color: var(--border-color);
transition: all 0.3s ease;
}
/* Internal Quasar components color management */
:deep(.category-sidebar-header),
.category-sidebar-list {
background-color: var(--bg-surface) !important;
color: var(--text-main) !important;
}
/* Labels and Icons - use var(--text-main) but force opacity */
:deep(.q-item__label),
:deep(.q-icon) {
color: var(--text-main) !important;
opacity: 1 !important;
}
.category-item-label {
color: var(--text-main);
}
/* ✅ DARK MODE SPECIFIC OVERRIDES using :global(.dark) as recommended */
:global(.dark) .category-item-label {
color: #f8fafc !important; /* Forces slate-50 in dark mode */
}
:global(.dark) :deep(.category-sidebar-header *) {
color: #f8fafc !important;
opacity: 1 !important;
}
/* Hover effects */
.category-item:hover {
background-color: rgba(0, 0, 0, 0.03);
}
:global(.dark) .category-item:hover {
background-color: rgba(255, 255, 255, 0.05) !important;
}
/* Checkbox Label handling */
:deep(.q-checkbox__label) {
color: var(--text-secondary) !important;
}
/* Show More button fix */
.show-more-item {
background-color: transparent !important;
}
</style>