monacousa-portal/pages/member/resources/index.vue

506 lines
14 KiB
Vue

<template>
<div>
<!-- Header -->
<div class="mb-6">
<h1 class="text-h4 font-weight-bold mb-2">Resources</h1>
<p class="text-body-1 text-medium-emphasis">Access documents, guides, and helpful resources</p>
</div>
<!-- Search Bar -->
<v-card class="mb-6" elevation="1">
<v-card-text>
<v-text-field
v-model="searchQuery"
prepend-inner-icon="mdi-magnify"
label="Search resources"
variant="outlined"
density="compact"
clearable
hide-details
/>
</v-card-text>
</v-card>
<!-- Resource Categories -->
<v-row class="mb-6">
<v-col
v-for="category in categories"
:key="category.id"
cols="6"
sm="4"
md="3"
>
<v-card
:color="selectedCategory === category.id ? 'error' : undefined"
:variant="selectedCategory === category.id ? 'tonal' : 'outlined'"
class="text-center pa-4 cursor-pointer"
hover
@click="selectedCategory = selectedCategory === category.id ? null : category.id"
>
<v-icon
size="32"
:color="selectedCategory === category.id ? 'error' : 'grey'"
class="mb-2"
>
{{ category.icon }}
</v-icon>
<div class="text-body-2 font-weight-medium">{{ category.name }}</div>
<div class="text-caption text-medium-emphasis">{{ category.count }} items</div>
</v-card>
</v-col>
</v-row>
<!-- Resources Grid -->
<v-row>
<!-- Documents Section -->
<v-col cols="12">
<h3 class="text-h6 mb-3">
<v-icon start color="error">mdi-file-document</v-icon>
Documents
</h3>
</v-col>
<v-col
v-for="doc in filteredDocuments"
:key="doc.id"
cols="12"
md="6"
lg="4"
>
<v-card elevation="1" hover>
<v-card-text>
<div class="d-flex align-center mb-2">
<v-icon :color="getFileIconColor(doc.type)" class="mr-3">
{{ getFileIcon(doc.type) }}
</v-icon>
<div class="flex-grow-1">
<div class="font-weight-medium">{{ doc.title }}</div>
<div class="text-caption text-medium-emphasis">{{ doc.size }} • {{ doc.date }}</div>
</div>
</div>
<p class="text-body-2 text-medium-emphasis mb-3">{{ doc.description }}</p>
<v-chip
size="x-small"
variant="tonal"
color="grey"
class="mr-1"
>
{{ doc.category }}
</v-chip>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
variant="text"
color="error"
size="small"
@click="viewDocument(doc)"
>
<v-icon start>mdi-eye</v-icon>
View
</v-btn>
<v-btn
variant="text"
size="small"
@click="downloadDocument(doc)"
>
<v-icon start>mdi-download</v-icon>
Download
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<!-- Guides Section -->
<v-row class="mt-6">
<v-col cols="12">
<h3 class="text-h6 mb-3">
<v-icon start color="error">mdi-book-open-variant</v-icon>
Guides & Tutorials
</h3>
</v-col>
<v-col cols="12">
<v-expansion-panels variant="accordion">
<v-expansion-panel
v-for="guide in guides"
:key="guide.id"
>
<v-expansion-panel-title>
<div class="d-flex align-center">
<v-icon class="mr-3" :color="guide.color">{{ guide.icon }}</v-icon>
<div>
<div class="font-weight-medium">{{ guide.title }}</div>
<div class="text-caption text-medium-emphasis">{{ guide.duration }} • {{ guide.level }}</div>
</div>
</div>
</v-expansion-panel-title>
<v-expansion-panel-text>
<p class="mb-3">{{ guide.description }}</p>
<v-list density="compact">
<v-list-item
v-for="(step, index) in guide.steps"
:key="index"
>
<template v-slot:prepend>
<v-avatar size="24" color="error" variant="tonal">
{{ index + 1 }}
</v-avatar>
</template>
<v-list-item-title>{{ step }}</v-list-item-title>
</v-list-item>
</v-list>
<v-btn
color="error"
variant="flat"
class="mt-3"
@click="startGuide(guide)"
>
Start Guide
</v-btn>
</v-expansion-panel-text>
</v-expansion-panel>
</v-expansion-panels>
</v-col>
</v-row>
<!-- Quick Links Section -->
<v-row class="mt-6">
<v-col cols="12">
<h3 class="text-h6 mb-3">
<v-icon start color="error">mdi-link-variant</v-icon>
Quick Links
</h3>
</v-col>
<v-col cols="12">
<v-list lines="two">
<v-list-item
v-for="link in quickLinks"
:key="link.id"
:href="link.url"
target="_blank"
class="mb-2"
>
<template v-slot:prepend>
<v-avatar color="error" variant="tonal">
<v-icon>{{ link.icon }}</v-icon>
</v-avatar>
</template>
<v-list-item-title>{{ link.title }}</v-list-item-title>
<v-list-item-subtitle>{{ link.description }}</v-list-item-subtitle>
<template v-slot:append>
<v-icon>mdi-open-in-new</v-icon>
</template>
</v-list-item>
</v-list>
</v-col>
</v-row>
<!-- FAQs Section -->
<v-row class="mt-6">
<v-col cols="12">
<h3 class="text-h6 mb-3">
<v-icon start color="error">mdi-help-circle</v-icon>
Frequently Asked Questions
</h3>
</v-col>
<v-col cols="12">
<v-card elevation="1">
<v-list>
<template v-for="(faq, index) in faqs" :key="faq.id">
<v-list-item @click="faq.expanded = !faq.expanded">
<v-list-item-title class="font-weight-medium">
{{ faq.question }}
</v-list-item-title>
<template v-slot:append>
<v-icon>
{{ faq.expanded ? 'mdi-chevron-up' : 'mdi-chevron-down' }}
</v-icon>
</template>
</v-list-item>
<v-expand-transition>
<div v-show="faq.expanded">
<v-list-item>
<v-list-item-subtitle class="text-wrap">
{{ faq.answer }}
</v-list-item-subtitle>
</v-list-item>
</div>
</v-expand-transition>
<v-divider v-if="index < faqs.length - 1" />
</template>
</v-list>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: 'member',
middleware: 'member'
});
// State
const searchQuery = ref('');
const selectedCategory = ref<string | null>(null);
// Categories
const categories = ref([
{ id: 'membership', name: 'Membership', icon: 'mdi-card-account-details', count: 5 },
{ id: 'events', name: 'Events', icon: 'mdi-calendar', count: 8 },
{ id: 'finance', name: 'Finance', icon: 'mdi-currency-usd', count: 4 },
{ id: 'governance', name: 'Governance', icon: 'mdi-gavel', count: 6 },
{ id: 'guides', name: 'Guides', icon: 'mdi-book-open', count: 10 },
{ id: 'forms', name: 'Forms', icon: 'mdi-file-document-edit', count: 7 },
{ id: 'policies', name: 'Policies', icon: 'mdi-shield-check', count: 5 },
{ id: 'other', name: 'Other', icon: 'mdi-folder', count: 3 }
]);
// Documents
const documents = ref([
{
id: 1,
title: 'Member Handbook 2024',
description: 'Complete guide to membership benefits and responsibilities',
category: 'membership',
type: 'pdf',
size: '2.4 MB',
date: 'Jan 2024'
},
{
id: 2,
title: 'Annual Report 2023',
description: 'Financial statements and organizational achievements',
category: 'finance',
type: 'pdf',
size: '5.1 MB',
date: 'Mar 2024'
},
{
id: 3,
title: 'Event Planning Guide',
description: 'How to organize and host MonacoUSA events',
category: 'events',
type: 'docx',
size: '1.2 MB',
date: 'Feb 2024'
},
{
id: 4,
title: 'Bylaws and Constitution',
description: 'Official governing documents of MonacoUSA',
category: 'governance',
type: 'pdf',
size: '890 KB',
date: 'Jan 2023'
},
{
id: 5,
title: 'Membership Application Form',
description: 'Form for new member applications',
category: 'forms',
type: 'pdf',
size: '245 KB',
date: 'Jan 2024'
},
{
id: 6,
title: 'Privacy Policy',
description: 'How we handle and protect your personal information',
category: 'policies',
type: 'pdf',
size: '180 KB',
date: 'Dec 2023'
}
]);
// Guides
const guides = ref([
{
id: 1,
title: 'Getting Started with MonacoUSA',
description: 'A comprehensive guide for new members to navigate the portal and make the most of their membership',
duration: '10 min',
level: 'Beginner',
icon: 'mdi-rocket-launch',
color: 'green',
expanded: false,
steps: [
'Complete your profile information',
'Explore upcoming events',
'Connect with other members',
'Access member resources',
'Set up payment methods'
]
},
{
id: 2,
title: 'How to Register for Events',
description: 'Step-by-step instructions for browsing and registering for MonacoUSA events',
duration: '5 min',
level: 'Beginner',
icon: 'mdi-calendar-plus',
color: 'blue',
expanded: false,
steps: [
'Navigate to the Events page',
'Browse available events',
'Click on an event for details',
'Click the Register button',
'Confirm your registration'
]
},
{
id: 3,
title: 'Managing Your Dues and Payments',
description: 'Learn how to view payment history, update payment methods, and manage your dues',
duration: '7 min',
level: 'Intermediate',
icon: 'mdi-credit-card',
color: 'purple',
expanded: false,
steps: [
'Access your payment dashboard',
'Review payment history',
'Update payment method',
'Set up automatic payments',
'Download payment receipts'
]
}
]);
// Quick Links
const quickLinks = ref([
{
id: 1,
title: 'Monaco Government Portal',
description: 'Official Monaco government website',
url: 'https://www.gouv.mc',
icon: 'mdi-bank'
},
{
id: 2,
title: 'US Embassy in France',
description: 'Consular services for US citizens',
url: 'https://fr.usembassy.gov',
icon: 'mdi-flag'
},
{
id: 3,
title: 'Monaco Economic Board',
description: 'Business and investment opportunities',
url: 'https://www.monacoeconomicboard.mc',
icon: 'mdi-briefcase'
},
{
id: 4,
title: 'Visit Monaco',
description: 'Tourism and cultural information',
url: 'https://www.visitmonaco.com',
icon: 'mdi-map'
}
]);
// FAQs
const faqs = ref([
{
id: 1,
question: 'How do I update my contact information?',
answer: 'You can update your contact information by going to your Profile page and clicking the Edit button in the Contact Information section. Make your changes and click Save to update your information.',
expanded: false
},
{
id: 2,
question: 'When are membership dues payable?',
answer: 'Annual membership dues are payable at the beginning of each calendar year. You will receive a reminder email in December with payment instructions. You can pay online through the portal or by bank transfer.',
expanded: false
},
{
id: 3,
question: 'How do I cancel my event registration?',
answer: 'To cancel an event registration, go to the Events page, click on "My Registrations" tab, find the event you want to cancel, and click the Cancel button. Please note that cancellation policies may vary by event.',
expanded: false
},
{
id: 4,
question: 'Who can I contact for technical support?',
answer: 'For technical support, please email support@monacousa.org or use the Contact Support button in your dashboard. Our support team typically responds within 24-48 hours.',
expanded: false
},
{
id: 5,
question: 'How do I access member-only content?',
answer: 'Member-only content is automatically available once you log in to the portal. If you\'re having trouble accessing content, please ensure your membership is active and your dues are current.',
expanded: false
}
]);
// Computed
const filteredDocuments = computed(() => {
let filtered = documents.value;
if (selectedCategory.value) {
filtered = filtered.filter(doc => doc.category === selectedCategory.value);
}
if (searchQuery.value) {
const query = searchQuery.value.toLowerCase();
filtered = filtered.filter(doc =>
doc.title.toLowerCase().includes(query) ||
doc.description.toLowerCase().includes(query) ||
doc.category.toLowerCase().includes(query)
);
}
return filtered;
});
// Methods
const getFileIcon = (type: string) => {
const icons: Record<string, string> = {
pdf: 'mdi-file-pdf-box',
docx: 'mdi-file-word',
xlsx: 'mdi-file-excel',
pptx: 'mdi-file-powerpoint',
default: 'mdi-file-document'
};
return icons[type] || icons.default;
};
const getFileIconColor = (type: string) => {
const colors: Record<string, string> = {
pdf: 'red',
docx: 'blue',
xlsx: 'green',
pptx: 'orange',
default: 'grey'
};
return colors[type] || colors.default;
};
const viewDocument = (doc: any) => {
console.log('Viewing document:', doc.title);
// Open document in new tab or modal
};
const downloadDocument = (doc: any) => {
console.log('Downloading document:', doc.title);
// Trigger download
};
const startGuide = (guide: any) => {
console.log('Starting guide:', guide.title);
// Navigate to guide or open tutorial
};
</script>
<style scoped>
.cursor-pointer {
cursor: pointer;
}
.text-wrap {
white-space: pre-wrap;
}
</style>