nidus-sync/ts/components/ReviewContactColumnList.vue

123 lines
2.5 KiB
Vue
Raw Normal View History

<style scoped>
.user-filters {
display: flex;
gap: 1rem;
align-items: center;
flex-wrap: wrap;
}
.user-filters input[type="text"],
.user-filters select {
padding: 0.5rem;
border: 1px solid #ddd;
border-radius: 4px;
}
.user-filters button {
padding: 0.5rem 1rem;
background: #dc3545;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.user-footer {
font-weight: 500;
color: #666;
}
</style>
2026-05-15 17:19:06 +00:00
<template>
<ListCard
:items="items"
:loading="loading"
selection-mode="single"
@selection-change="handleSelectionChange"
>
<!-- Filters Slot -->
<template #filters="{ applyFilter, clearFilters, activeFilters }">
<div class="user-filters">
<input
v-model="searchTerm"
type="text"
placeholder="Search by name..."
@input="handleSearch(applyFilter)"
/>
<button
@click="handleClearFilters(clearFilters)"
v-if="activeFilters > 0"
>
Clear Filters ({{ activeFilters }})
</button>
</div>
</template>
<!-- Item Slot -->
<template #item="{ item, isSelected, toggleSelection }">
<ListCardContact
:contact="item"
@click="toggleSelection"
:is-selected="isSelected"
/>
</template>
</ListCard>
2026-05-15 17:19:06 +00:00
</template>
<script setup lang="ts">
import { computed, ref } from "vue";
import ListCard from "@/components/layout/ListCard.vue";
import ListCardContact from "@/components/ListCardContact.vue";
import { Contact } from "@/type/api";
interface Props {
contacts: Contact[] | undefined;
loading: boolean;
}
2026-05-18 23:37:59 +00:00
interface Emits {
"selection-change": [contact: Contact | undefined];
}
2026-05-18 23:37:59 +00:00
const emit = defineEmits<Emits>();
const loading = ref(false);
const props = defineProps<Props>();
const searchTerm = ref("");
const roleFilter = ref("");
const activeOnly = ref(false);
// Filter handlers
const handleSearch = (
applyFilter: (fn: (contact: Contact) => boolean) => void,
) => {
applyFilter((contact: Contact) =>
contact.name.toLowerCase().includes(searchTerm.value.toLowerCase()),
);
};
const handleClearFilters = (clearFilters: () => void) => {
searchTerm.value = "";
roleFilter.value = "";
activeOnly.value = false;
clearFilters();
};
const handleContactClick = (contact: any) => {
console.log("Clicked contact:", contact);
};
const items = computed((): Contact[] => {
if (props.contacts) {
return props.contacts;
}
return [];
});
2026-05-18 23:37:59 +00:00
const handleSelectionChange = (selectedContacts: Contact[]) => {
if (selectedContacts.length > 0) {
emit("selection-change", selectedContacts[0]);
} else {
emit("selection-change", undefined);
}
};
</script>