154 lines
5.6 KiB
Vue
154 lines
5.6 KiB
Vue
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import usePageData from '../../../composables/usePageData.js';
|
|
import { useNavigate } from '../../../composables/Core/useNavigate.js';
|
|
import { useAuth } from '../../../composables/Core/useAuth.js';
|
|
import { useModal } from '../../../composables/Core/useModal.js';
|
|
import { useChapters } from '../../../composables/useChapters.js';
|
|
import HomeSkeleton from '../../../Components/Core/Skeleton/HomeSkeleton.vue';
|
|
|
|
const { user } = useAuth();
|
|
const { navigate } = useNavigate();
|
|
const modal = useModal();
|
|
|
|
const { data, loading, fetchPageData } = usePageData();
|
|
const { fetchOrgChart } = useChapters();
|
|
|
|
const officers = ref([]);
|
|
|
|
const chapterInfo = computed(() => data.value?.chapter_info ?? null);
|
|
|
|
const chapterTitle = computed(() => {
|
|
if (!chapterInfo.value) return 'No chapter assigned';
|
|
const level = (chapterInfo.value.chapter_level || '').toUpperCase();
|
|
return `${level} — ${chapterInfo.value.chapter_name || ''}`;
|
|
});
|
|
|
|
const memberCount = computed(() => chapterInfo.value?.member_count ?? 0);
|
|
|
|
const services = [
|
|
{ icon: 'fas fa-sitemap', title: 'Org Chart', pagename: 'ChapterOrgChart' },
|
|
{ icon: 'fas fa-handshake', title: 'My Cooperative', action: 'viewMyCoop' },
|
|
{ icon: 'fas fa-user-circle', title: 'My Profile', pagename: 'UserInfoEdit' },
|
|
{ icon: 'fas fa-wallet', title: 'My Wallet', pagename: 'MyWallet' },
|
|
];
|
|
|
|
const activeOrgHash = computed(() => user.value?.settings?.cooperatives?.[0] ?? null);
|
|
|
|
const roleLabel = (role) => {
|
|
const map = {
|
|
PRESIDENT: 'Pres.',
|
|
VICE_PRESIDENT: 'V.P.',
|
|
SECRETARY: 'Sec.',
|
|
TREASURER: 'Treas.',
|
|
AUDITOR: 'Auditor',
|
|
BOARD_MEMBER: 'Board',
|
|
};
|
|
return map[role] || role;
|
|
};
|
|
|
|
const viewMyCoop = () => {
|
|
if (activeOrgHash.value) {
|
|
navigate({ page: 'CooperativeDetail', props: { target: activeOrgHash.value } });
|
|
} else {
|
|
modal.quickDismiss({ title: 'No Cooperative', body: 'You are not linked to a cooperative yet.' });
|
|
}
|
|
};
|
|
|
|
const handleAction = (item) => {
|
|
if (item.action === 'viewMyCoop') return viewMyCoop();
|
|
if (item.pagename) navigate({ page: item.pagename });
|
|
};
|
|
|
|
onMounted(async () => {
|
|
await fetchPageData('/home-data', {});
|
|
const chart = await fetchOrgChart({});
|
|
officers.value = chart?.own_chapter?.officers ?? [];
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="home-coop-member-fragment pb-5">
|
|
<HomeSkeleton v-if="loading" />
|
|
|
|
<template v-else>
|
|
<div class="tf-container mt-3">
|
|
<div class="chapter-card rounded-4 p-3 mb-3">
|
|
<div class="small text-uppercase opacity-75" style="letter-spacing:.05em;">Your Chapter</div>
|
|
<div class="fw-bold fs-5">{{ chapterTitle }}</div>
|
|
<div v-if="chapterInfo?.cooperative_name" class="small mt-1 opacity-75">
|
|
<i class="fas fa-handshake me-1"></i>{{ chapterInfo.cooperative_name }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="member-count-badge rounded-pill px-4 py-2 mb-3 d-inline-flex align-items-center gap-2">
|
|
<i class="fas fa-users"></i>
|
|
<span class="fw-semibold">{{ memberCount }} member{{ memberCount !== 1 ? 's' : '' }} in this chapter</span>
|
|
</div>
|
|
|
|
<div class="officers-strip rounded-4 p-3 mb-3">
|
|
<div class="small fw-semibold mb-2"><i class="fas fa-user-tie me-1"></i>Chapter Officers</div>
|
|
<div v-if="!officers.length" class="small opacity-75">No officers assigned yet.</div>
|
|
<div v-else class="d-flex flex-wrap gap-2">
|
|
<span v-for="(o, i) in officers" :key="i" class="officer-badge rounded-pill px-3 py-1 small">
|
|
<strong>{{ roleLabel(o.role) }}</strong> {{ o.name }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tf-container mt-4">
|
|
<h5 class="fw_7 mb-3">My Cooperative</h5>
|
|
<div class="row g-2">
|
|
<div v-for="item in services" :key="item.title" class="col-6 col-md-3">
|
|
<button
|
|
class="service-tile rounded-4 p-3 w-100 h-100 d-flex flex-column align-items-center justify-content-center gap-2"
|
|
@click="handleAction(item)"
|
|
>
|
|
<i :class="item.icon" class="fa-lg" style="color: var(--accent-color);"></i>
|
|
<span class="small fw-semibold text-center">{{ item.title }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.chapter-card {
|
|
background: var(--accent-color);
|
|
color: #fff;
|
|
}
|
|
.member-count-badge {
|
|
background: var(--bg-card);
|
|
color: var(--text-primary);
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
}
|
|
.officers-strip {
|
|
background: var(--bg-card);
|
|
color: var(--text-primary);
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
}
|
|
.officer-badge {
|
|
background: var(--bg-primary);
|
|
color: var(--text-primary);
|
|
border: 1px solid rgba(0, 0, 0, 0.08);
|
|
}
|
|
.service-tile {
|
|
background: var(--bg-card);
|
|
color: var(--text-primary);
|
|
border: 1px solid rgba(0, 0, 0, 0.06);
|
|
transition: transform 0.15s;
|
|
}
|
|
.service-tile:hover {
|
|
transform: translateY(-2px);
|
|
}
|
|
:global(.dark-mode) .member-count-badge,
|
|
:global(.dark-mode) .officers-strip,
|
|
:global(.dark-mode) .officer-badge,
|
|
:global(.dark-mode) .service-tile {
|
|
border-color: rgba(255, 255, 255, 0.08);
|
|
}
|
|
</style>
|