| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- <template>
- <div class="space-y-4">
- <div v-if="filteredPosts.length === 0" class="flex flex-col items-center justify-center py-20 bg-card/40 border border-border/50 rounded-3xl opacity-50">
- <Newspaper class="w-12 h-12 text-muted-foreground/20 mb-4" />
- <p class="text-sm text-muted-foreground">{{ t("admin.fields.noPosts") }}</p>
- </div>
- <div v-else class="grid gap-4">
- <div v-for="p in filteredPosts" :key="p.id"
- class="p-4 bg-card/40 border border-border/50 rounded-2xl flex items-center justify-between group hover:border-primary/30 transition-all">
- <div class="flex items-center gap-4 min-w-0">
- <div class="w-16 h-16 rounded-xl bg-muted/20 overflow-hidden flex-shrink-0 border border-border/50">
- <img v-if="p.image_url" :src="p.image_url" class="w-full h-full object-cover" />
- <Newspaper v-else class="w-full h-full p-4 text-muted-foreground/30" />
- </div>
- <div class="min-w-0">
- <h4 class="font-bold truncate text-sm">{{ p.title_en }}</h4>
- <div class="flex items-center gap-3 text-[10px] text-muted-foreground uppercase font-bold mt-1">
- <span class="bg-muted px-1.5 py-0.5 rounded border border-border/50">{{ p.category }}</span>
- <span class="opacity-30">•</span>
- <span class="font-mono">{{ p.slug }}</span>
- </div>
- </div>
- </div>
- <div class="flex items-center gap-2">
- <button @click="$emit('edit', p)" class="p-2.5 rounded-xl hover:bg-white/5 text-muted-foreground hover:text-primary transition-all">
- <Edit2 class="w-4 h-4" />
- </button>
- <button @click="$emit('toggle-publish', p)" :class="`p-2.5 rounded-xl transition-all ${p.is_published ? 'text-emerald-500 hover:bg-emerald-500/10' : 'text-rose-500 hover:bg-rose-500/10'}`">
- <Eye v-if="p.is_published" class="w-5 h-5" />
- <EyeOff v-else class="w-5 h-5" />
- </button>
- <button @click="$emit('delete', p.id, p.title_en)" class="p-2.5 rounded-xl hover:bg-rose-500/10 text-muted-foreground hover:text-rose-500 transition-all">
- <Trash2 class="w-4 h-4" />
- </button>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { computed } from "vue";
- import { useI18n } from "vue-i18n";
- import { Newspaper, Edit2, Trash2, Eye, EyeOff } from "lucide-vue-next";
- import Button from "@/components/ui/button.vue";
- const { t } = useI18n();
- const props = defineProps<{
- posts: any[];
- searchQuery: string;
- }>();
- defineEmits(['edit', 'delete', 'toggle-publish']);
- const filteredPosts = computed(() => {
- if (!props.searchQuery) return props.posts;
- const q = props.searchQuery.toLowerCase();
- return props.posts.filter(p =>
- p.title_en?.toLowerCase().includes(q) ||
- p.title_ru?.toLowerCase().includes(q) ||
- p.slug?.toLowerCase().includes(q)
- );
- });
- </script>
|