mitlist/fe/src/pages/GroupDetailPage.vue

129 lines
3.4 KiB
Vue

<template>
<q-page padding>
<div v-if="group">
<h4 class="q-mt-none q-mb-sm">Group: {{ group.name }}</h4>
<!-- Invite Code Generation -->
<div class="q-mt-lg">
<h5>Invite Members</h5>
<q-btn
label="Generate Invite Code"
color="secondary"
@click="void generateInviteCode"
:loading="generatingInvite"
/>
<div v-if="inviteCode" class="q-mt-md">
<q-input readonly :model-value="inviteCode" label="Invite Code">
<template v-slot:append>
<q-btn round dense flat icon="content_copy" @click="copyInviteCode" />
</template>
</q-input>
<q-banner v-if="copySuccess" class="bg-green-2 text-green-9 q-mt-sm" dense>
Invite code copied to clipboard!
</q-banner>
</div>
</div>
</div>
<div v-else-if="loading"><q-spinner-dots size="2em" /> Loading group details...</div>
<div v-else>
<p>Group not found or an error occurred.</p>
</div>
</q-page>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import { apiClient, API_ENDPOINTS } from 'src/config/api';
import { copyToClipboard, useQuasar } from 'quasar';
interface Group {
id: string;
name: string;
// other properties if needed
}
const props = defineProps({
id: {
type: String,
required: true,
},
});
const route = useRoute();
const $q = useQuasar();
const group = ref<Group | null>(null);
const loading = ref(false);
const inviteCode = ref<string | null>(null);
const generatingInvite = ref(false);
const copySuccess = ref(false);
const groupId = computed(() => props.id || (route.params.id as string));
const fetchGroupDetails = async () => {
if (!groupId.value) return;
loading.value = true;
try {
const response = await apiClient.get(API_ENDPOINTS.GROUPS.BY_ID(groupId.value));
group.value = response.data;
} catch (error: unknown) {
console.error('Error fetching group details:', error);
$q.notify({
color: 'negative',
message: error instanceof Error ? error.message : 'Failed to fetch group details.',
icon: 'report_problem',
});
} finally {
loading.value = false;
}
};
const generateInviteCode = async () => {
if (!groupId.value) return;
generatingInvite.value = true;
inviteCode.value = null;
try {
const response = await apiClient.post(API_ENDPOINTS.INVITES.BASE, {
group_id: groupId.value,
});
inviteCode.value = response.data.invite_code;
$q.notify({
color: 'positive',
message: 'Invite code generated successfully!',
icon: 'check_circle',
});
} catch (error: unknown) {
console.error('Error generating invite code:', error);
$q.notify({
color: 'negative',
message: error instanceof Error ? error.message : 'Failed to generate invite code.',
icon: 'report_problem',
});
} finally {
generatingInvite.value = false;
}
};
const copyInviteCode = () => {
if (inviteCode.value) {
copyToClipboard(inviteCode.value)
.then(() => {
copySuccess.value = true;
setTimeout(() => (copySuccess.value = false), 2000);
})
.catch(() => {
console.error('Failed to copy invite code');
});
}
};
onMounted(() => {
void fetchGroupDetails();
});
</script>
<style scoped>
/* Add any page-specific styles here */
</style>