129 lines
3.4 KiB
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>
|