Tied in new state system into members filters

This commit is contained in:
2026-02-08 01:06:44 -05:00
parent f77f5b5a7f
commit cf880ed124

View File

@@ -1,65 +1,70 @@
<script setup lang="ts">
import { ref, computed, onMounted, watch } from "vue";
import { useRouter } from 'vue-router';
import {
import { ref, computed, onMounted, watch } from "vue";
import { useRouter } from 'vue-router';
import {
Ellipsis, Search, Trash2, UserX,
X,
} from "lucide-vue-next";
import {
} from "lucide-vue-next";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination'
} from '@/components/ui/pagination'
// API & Types
import { getMembersFiltered } from "@/api/member";
import { getUnits } from "@/api/units";
import type { Member } from "@shared/types/member";
import { MemberState } from "@shared/types/member";
import type { Unit } from "@shared/types/units";
import type { pagination as PaginationType } from "@shared/types/pagination";
// API & Types
import { getMembersFiltered } from "@/api/member";
import { getUnits } from "@/api/units";
import type { Member } from "@shared/types/member";
import { MemberState } from "@shared/types/member";
import type { Unit } from "@shared/types/units";
import type { pagination as PaginationType } from "@shared/types/pagination";
// UI Components
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Button } from "@/components/ui/button";
import Badge from "@/components/ui/badge/Badge.vue";
import Input from "@/components/ui/input/Input.vue";
import Spinner from "@/components/ui/spinner/Spinner.vue";
import DischargeMember from "@/components/members/DischargeMember.vue";
import MemberCard from "@/components/members/MemberCard.vue";
// UI Components
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Button } from "@/components/ui/button";
import Badge from "@/components/ui/badge/Badge.vue";
import Input from "@/components/ui/input/Input.vue";
import Spinner from "@/components/ui/spinner/Spinner.vue";
import DischargeMember from "@/components/members/DischargeMember.vue";
import MemberCard from "@/components/members/MemberCard.vue";
// --- State ---
const router = useRouter();
const members = ref<Member[]>([]);
const units = ref<Unit[]>([]);
const isLoaded = ref(false);
const pagination = ref<PaginationType>({
// --- State ---
const router = useRouter();
const members = ref<Member[]>([]);
const units = ref<Unit[]>([]);
const isLoaded = ref(false);
const pagination = ref<PaginationType>({
page: 1,
pageSize: 15,
total: 0,
totalPages: 0,
});
});
const filters = ref<{ search: string; status: "all" | MemberState; unitId: string }>({
const filters = ref<{ search: string; status: "all" | MemberState; unitId: string }>({
search: "",
status: MemberState.Member,
unitId: "all"
});
});
// Pagination State
const pageNum = ref(1);
const pageSize = ref(15);
const pageSizeOptions = [10, 15, 30];
// Pagination State
const pageNum = ref(1);
const pageSize = ref(15);
const pageSizeOptions = [10, 15, 30];
const MEMBER_STATUSES = Object.values(MemberState);
const MEMBER_STATUSES = Object.entries(MemberState)
.filter(([key, value]) => isNaN(Number(key)))
.map(([label, id]) => ({
label,
id: id as number // Casting back to number for your SQL logic
}));
// --- Methods ---
const fetchMembers = async () => {
// --- Methods ---
const fetchMembers = async () => {
isLoaded.value = false;
try {
const result = await getMembersFiltered({
@@ -77,76 +82,76 @@ const fetchMembers = async () => {
} finally {
isLoaded.value = true;
}
};
};
const fetchUnits = async () => {
const fetchUnits = async () => {
try {
units.value = await getUnits();
} catch (error) {
console.error('Failed to fetch units:', error);
}
};
};
const navigateToMember = (id: string | number) => router.push(`/member/${id}`);
const navigateToMember = (id: string | number) => router.push(`/member/${id}`);
const setPage = (num: number) => {
const setPage = (num: number) => {
pageNum.value = num;
};
};
const setPageSize = (size: number) => {
const setPageSize = (size: number) => {
pageSize.value = size;
pageNum.value = 1;
};
};
// --- Computed ---
const paginatedMembers = computed(() => members.value);
const totalItems = computed(() => pagination.value.total);
// --- Computed ---
const paginatedMembers = computed(() => members.value);
const totalItems = computed(() => pagination.value.total);
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
// Watch pagination (Immediate)
watch([pageNum, pageSize], () => {
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
// Watch pagination (Immediate)
watch([pageNum, pageSize], () => {
if (debounceTimer) clearTimeout(debounceTimer);
fetchMembers();
});
});
// Watch filters (Debounced)
watch(filters, () => {
// Watch filters (Debounced)
watch(filters, () => {
if (debounceTimer) clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
fetchMembers();
}, 300);
}, { deep: true });
}, { deep: true });
function clearFilters() {
function clearFilters() {
filters.value = {
search: "",
status: "all",
unitId: "all"
}
}
}
onMounted(() => {
onMounted(() => {
fetchUnits();
fetchMembers();
});
});
//discharge form logic
const isDischargeOpen = ref(false)
const targetMember = ref(null)
//discharge form logic
const isDischargeOpen = ref(false)
const targetMember = ref(null)
function openDischargeModal(member: Member) {
function openDischargeModal(member: Member) {
targetMember.value = member
isDischargeOpen.value = true
}
}
function suspendMember(member: Member) {
function suspendMember(member: Member) {
}
}
function handleDischargeSuccess(data) {
function handleDischargeSuccess(data) {
fetchMembers();
}
}
</script>
<template>
@@ -171,8 +176,8 @@ function handleDischargeSuccess(data) {
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All Statuses</SelectItem>
<SelectItem v-for="s in MEMBER_STATUSES" :key="s" :value="s">
<span class="capitalize">{{ s }}</span>
<SelectItem v-for="s in MEMBER_STATUSES" :key="s.id" :value="s.id">
<span class="capitalize">{{ s.label }}</span>
</SelectItem>
</SelectContent>
</Select>