pull/5171/head
parent
8e2905d6cd
commit
127fa42bfa
@ -0,0 +1,61 @@ |
|||||||
|
<template> |
||||||
|
<div class="friends-invitations"> |
||||||
|
<BaseCard plain class="bg-white mt-4"> |
||||||
|
<template #header> |
||||||
|
<div class="px-4 py-2 bg-gray-15"> |
||||||
|
<h2 class="text-h5">{{ title }}</h2> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<hr class="my-4"> |
||||||
|
<div v-if="invitations && invitations.length > 0" class="invitation-list"> |
||||||
|
<div v-for="invitation in invitations" :key="invitation.id" class="invitation-item"> |
||||||
|
<div class="invitation-content"> |
||||||
|
<img :src="invitation.itemPicture" class="item-picture" alt="Item picture"> |
||||||
|
<div class="invitation-info"> |
||||||
|
<h4><a :href="'profile.php?u=' + invitation.itemId">{{ invitation.itemName }}</a></h4> |
||||||
|
<p>{{ invitation.content }}</p> |
||||||
|
<span>{{ invitation.date }}</span> |
||||||
|
</div> |
||||||
|
<div class="invitation-actions"> |
||||||
|
<BaseButton |
||||||
|
v-if="invitation.canAccept" |
||||||
|
label="Accept" |
||||||
|
icon="check" |
||||||
|
type="success" |
||||||
|
@click="emitEvent('accept', invitation.id)" |
||||||
|
/> |
||||||
|
<BaseButton |
||||||
|
v-if="invitation.canDeny" |
||||||
|
label="Deny" |
||||||
|
icon="times" |
||||||
|
type="danger" |
||||||
|
@click="emitEvent('deny', invitation.id)" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div v-else class="no-invitations-message"> |
||||||
|
<p>{{ t("No invitations or records found") }}</p> |
||||||
|
</div> |
||||||
|
</BaseCard> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup> |
||||||
|
import BaseCard from "../basecomponents/BaseCard.vue" |
||||||
|
import BaseButton from "../basecomponents/BaseButton.vue" |
||||||
|
import { useI18n } from "vue-i18n" |
||||||
|
import { useFormatDate } from "../../composables/formatDate" |
||||||
|
|
||||||
|
const { t } = useI18n() |
||||||
|
const { relativeDatetime } = useFormatDate() |
||||||
|
const props = defineProps({ |
||||||
|
invitations: Array, |
||||||
|
title: String |
||||||
|
}) |
||||||
|
const emit = defineEmits(['accept', 'deny']) |
||||||
|
function emitEvent(event, id) { |
||||||
|
emit(event, id) |
||||||
|
} |
||||||
|
</script> |
@ -0,0 +1,292 @@ |
|||||||
|
<template> |
||||||
|
<div class="social-search p-2"> |
||||||
|
{{ query.value }} |
||||||
|
<BaseCard class="mb-2"> |
||||||
|
<template #header> |
||||||
|
<div class="px-4 py-2 -mb-2 bg-gray-15"> |
||||||
|
<h2 class="text-h5">{{ headerTitle }}</h2> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div class="flex flex-col items-end"> |
||||||
|
<div class="w-full flex justify-between items-center mb-2"> |
||||||
|
<label for="search-query" class="mr-2">{{ t('Users, Groups') }}</label> |
||||||
|
<BaseInputText |
||||||
|
id="search-query" |
||||||
|
v-model="query" |
||||||
|
class="flex-grow" |
||||||
|
label=""/> |
||||||
|
</div> |
||||||
|
<div class="w-full flex justify-between items-center mb-4"> |
||||||
|
<label for="search-type" class="mr-2">{{ t('Type') }}</label> |
||||||
|
<BaseSelect |
||||||
|
id="search-type" |
||||||
|
v-model="searchType" |
||||||
|
:options="searchOptions" |
||||||
|
optionLabel="name" |
||||||
|
optionValue="code" |
||||||
|
class="flex-grow" |
||||||
|
label=""/> |
||||||
|
</div> |
||||||
|
<BaseButton |
||||||
|
label="Search" |
||||||
|
icon="search" |
||||||
|
@click="performSearch" |
||||||
|
type="secondary" |
||||||
|
class="self-end" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</BaseCard> |
||||||
|
|
||||||
|
|
||||||
|
<BaseCard v-if="users.length" class="mb-2"> |
||||||
|
<template #header> |
||||||
|
<div class="px-4 py-2 -mb-2 bg-gray-15"> |
||||||
|
<h2 class="text-h5">{{ t('Users') }}</h2> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<ul> |
||||||
|
<li v-for="user in users" :key="user.id" class="flex items-center justify-between p-2 border-b-2"> |
||||||
|
<div class="flex items-center"> |
||||||
|
<img :src="user.avatar" class="w-16 h-16 rounded-full mr-4"> |
||||||
|
<span>{{ user.name }}</span> |
||||||
|
<span v-if="user.status === 'online'" class="mdi mdi-circle green mx-2" title="Online"></span> |
||||||
|
<span v-else class="mdi mdi-circle gray mx-2" title="Offline"></span> |
||||||
|
<span :class="getRoleIcon(user.role)" class="mx-2"></span> |
||||||
|
</div> |
||||||
|
<div> |
||||||
|
<BaseButton |
||||||
|
v-if="user.showInvitationButton" |
||||||
|
@click="openInvitationModal(user)" |
||||||
|
label="Send invitation" |
||||||
|
icon="account" |
||||||
|
type="secondary" |
||||||
|
class="mr-2" |
||||||
|
/> |
||||||
|
|
||||||
|
<BaseButton |
||||||
|
@click="openMessageModal(user)" |
||||||
|
label="Send message" |
||||||
|
icon="email" |
||||||
|
type="primary" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</li> |
||||||
|
</ul> |
||||||
|
</BaseCard> |
||||||
|
|
||||||
|
<BaseCard v-if="groups.length" class="mb-2"> |
||||||
|
<template #header> |
||||||
|
<div class="px-4 py-2 -mb-2 bg-gray-15"> |
||||||
|
<h2 class="text-h5">{{ t('Groups') }}</h2> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-4 p-4"> |
||||||
|
<div v-for="group in groups" :key="group.id" class="group-card"> |
||||||
|
<div class="group-image flex justify-center"> |
||||||
|
<img :src="group.image" class="rounded w-16 h-16" |
||||||
|
</div> |
||||||
|
<div class="group-info text-center"> |
||||||
|
<h3>{{ group.name }}</h3> |
||||||
|
<p>{{ group.description }}</p> |
||||||
|
<a :href="group.url"> |
||||||
|
<BaseButton label="See more" type="secondary" class="mt-2" icon=""/> |
||||||
|
</a> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</BaseCard> |
||||||
|
|
||||||
|
<!-- Invitation Modal --> |
||||||
|
<div v-if="showInvitationModal" class="invitation-modal-overlay" @click.self="closeInvitationModal"> |
||||||
|
<div class="invitation-modal"> |
||||||
|
<div class="invitation-modal-header"> |
||||||
|
<h3>Send invitation</h3> |
||||||
|
<button class="close-button" @click="closeInvitationModal">✕</button> |
||||||
|
</div> |
||||||
|
<textarea class="invitation-modal-textarea" placeholder="Add a personal message" v-model="invitationMessage"></textarea> |
||||||
|
<button class="invitation-modal-send" @click="sendInvitation">Send message</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<!-- Message Modal --> |
||||||
|
<div v-if="showMessageModal" class="message-modal-overlay" @click.self="closeMessageModal"> |
||||||
|
<div class="message-modal"> |
||||||
|
<div class="message-modal-header"> |
||||||
|
<h3>{{ t('Send message') }}</h3> |
||||||
|
<button class="message-modal-close" @click="closeMessageModal">✕</button> |
||||||
|
</div> |
||||||
|
<div class="message-modal-body"> |
||||||
|
<div class="message-user-info"> |
||||||
|
<img :src="selectedUser.avatar" class="message-user-avatar" alt="User avatar"> |
||||||
|
<span class="message-user-name">{{ selectedUser.name }}</span> |
||||||
|
</div> |
||||||
|
<input type="text" class="message-modal-input" placeholder="{{ t('Subject') }}" v-model="messageSubject"> |
||||||
|
<textarea class="message-modal-textarea" placeholder="{{ t('Message') }}" v-model="messageContent"></textarea> |
||||||
|
<button class="message-modal-send" @click="sendMessage">{{ t('Send message') }}</button> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup> |
||||||
|
|
||||||
|
import { nextTick, ref, computed } from "vue" |
||||||
|
import BaseCard from "../../components/basecomponents/BaseCard.vue" |
||||||
|
import BaseInputText from "../../components/basecomponents/BaseInputText.vue" |
||||||
|
import BaseSelect from "../../components/basecomponents/BaseSelect.vue" |
||||||
|
import BaseButton from "../../components/basecomponents/BaseButton.vue" |
||||||
|
import { useI18n } from "vue-i18n" |
||||||
|
import { useNotification } from "../../composables/notification" |
||||||
|
import { useSocialInfo } from "../../composables/useSocialInfo" |
||||||
|
|
||||||
|
const query = ref('') |
||||||
|
const searchType = ref('user') |
||||||
|
const searchPerformed = ref(false) |
||||||
|
const { t } = useI18n() |
||||||
|
const notification = useNotification() |
||||||
|
const selectedUser = ref(null) |
||||||
|
const showInvitationModal = ref(false) |
||||||
|
const showMessageModal = ref(false) |
||||||
|
const messageSubject = ref('') |
||||||
|
const messageContent = ref('') |
||||||
|
const invitationMessage = ref('') |
||||||
|
const { user, groupInfo, isGroup, loadGroup, isLoading } = useSocialInfo() |
||||||
|
const searchOptions = [ |
||||||
|
{ name: 'User', code: 'user' }, |
||||||
|
{ name: 'Group', code: 'group' } |
||||||
|
] |
||||||
|
const users = ref([]) |
||||||
|
const groups = ref([]) |
||||||
|
const getRoleIcon = (role) => { |
||||||
|
switch(role) { |
||||||
|
case 'student': |
||||||
|
return 'mdi mdi-school' |
||||||
|
case 'teacher': |
||||||
|
return 'mdi mdi-account-outline' |
||||||
|
case 'admin': |
||||||
|
return 'mdi mdi-briefcase-check' |
||||||
|
default: |
||||||
|
return 'mdi mdi-account' |
||||||
|
} |
||||||
|
} |
||||||
|
const headerTitle = computed(() => { |
||||||
|
return searchPerformed.value ? `${t('Results and feedback')} "${query.value}"` : t('Search') |
||||||
|
}) |
||||||
|
const performSearch = async () => { |
||||||
|
try { |
||||||
|
if (query.value.trim() === '') { |
||||||
|
notification.showWarningNotification('Please enter a search term.') |
||||||
|
return |
||||||
|
} |
||||||
|
searchPerformed.value = true |
||||||
|
await nextTick() |
||||||
|
const response = await fetch(`/social-network/search?query=${query.value}&type=${searchType.value}`) |
||||||
|
const data = await response.json() |
||||||
|
if (!response.ok) { |
||||||
|
throw new Error(data.message || 'Server response error') |
||||||
|
} |
||||||
|
if (searchType.value === 'user') { |
||||||
|
|
||||||
|
users.value = data.results.map(item => ({ |
||||||
|
...item, |
||||||
|
showInvitationButton: ![3, 4].includes(item.relationType) && item.id !== user.value.id |
||||||
|
})) |
||||||
|
groups.value = [] |
||||||
|
} else if (searchType.value === 'group') { |
||||||
|
groups.value = data.results |
||||||
|
users.value = [] |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
console.error('There has been a problem with your fetch operation:', error) |
||||||
|
} |
||||||
|
} |
||||||
|
const openMessageModal = (user) => { |
||||||
|
selectedUser.value = user |
||||||
|
showMessageModal.value = true |
||||||
|
} |
||||||
|
const closeMessageModal = () => { |
||||||
|
showMessageModal.value = false |
||||||
|
messageSubject.value = '' |
||||||
|
messageContent.value = '' |
||||||
|
} |
||||||
|
const openInvitationModal = (user) => { |
||||||
|
selectedUser.value = user |
||||||
|
showInvitationModal.value = true |
||||||
|
} |
||||||
|
const closeInvitationModal = () => { |
||||||
|
showInvitationModal.value = false |
||||||
|
invitationMessage.value = '' |
||||||
|
} |
||||||
|
const sendInvitation = async () => { |
||||||
|
if (!selectedUser.value) { |
||||||
|
notification.showErrorNotification('No user selected.') |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
const invitationData = { |
||||||
|
userId: user.value.id, |
||||||
|
targetUserId: selectedUser.value.id, |
||||||
|
action: 'send_invitation', |
||||||
|
subject: '', |
||||||
|
content: invitationMessage.value |
||||||
|
} |
||||||
|
try { |
||||||
|
const response = await fetch('/social-network/user-action', { |
||||||
|
method: 'POST', |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json', |
||||||
|
}, |
||||||
|
body: JSON.stringify(invitationData) |
||||||
|
}) |
||||||
|
const result = await response.json() |
||||||
|
if (result.success) { |
||||||
|
notification.showSuccessNotification('Invitation sent successfully.') |
||||||
|
users.value = users.value.filter((user) => user.id !== selectedUser.value.id) |
||||||
|
selectedUser.value = null |
||||||
|
} else { |
||||||
|
notification.showErrorNotification('Failed to send invitation.') |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
notification.showErrorNotification('An error occurred while sending the invitation.') |
||||||
|
console.error('Error sending invitation:', error) |
||||||
|
} |
||||||
|
|
||||||
|
showInvitationModal.value = false |
||||||
|
invitationMessage.value = '' |
||||||
|
} |
||||||
|
const sendMessage = async () => { |
||||||
|
if (!selectedUser.value) { |
||||||
|
notification.showErrorNotification('No user selected.') |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
const messageData = { |
||||||
|
userId: user.value.id, |
||||||
|
targetUserId: selectedUser.value.id, |
||||||
|
action: 'send_message', |
||||||
|
subject: messageSubject.value, |
||||||
|
content: messageContent.value |
||||||
|
} |
||||||
|
try { |
||||||
|
const response = await fetch('/social-network/user-action', { |
||||||
|
method: 'POST', |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json', |
||||||
|
}, |
||||||
|
body: JSON.stringify(messageData) |
||||||
|
}) |
||||||
|
const result = await response.json() |
||||||
|
if (result.success) { |
||||||
|
notification.showSuccessNotification('Message sent successfully.') |
||||||
|
} else { |
||||||
|
notification.showErrorNotification('Failed to send message.') |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
notification.showErrorNotification('An error occurred while sending the message.') |
||||||
|
console.error('Error sending message:', error) |
||||||
|
} |
||||||
|
|
||||||
|
closeMessageModal() |
||||||
|
} |
||||||
|
</script> |
@ -1,40 +1,74 @@ |
|||||||
<template> |
<template> |
||||||
<div class="social-group-show"> |
<div v-if="!isLoading && groupInfo.isMember" class="social-group-show"> |
||||||
<div class="group-header"> |
<div class="group-header"> |
||||||
<h1 class="group-title">mi grupo 0002</h1> |
<h1 class="group-title">{{ groupInfo?.title || '...' }}</h1> |
||||||
<p class="group-description">test</p> |
<p class="group-description">{{ groupInfo?.description }}</p> |
||||||
</div> |
</div> |
||||||
|
|
||||||
<ul class="tabs"> |
<ul class="tabs"> |
||||||
<li :class="{ active: activeTab === 'discussions' }" @click="activeTab = 'discussions'">Discussions</li> |
<li :class="{ active: activeTab === 'discussions' }" @click="activeTab = 'discussions'">{{ t('Discussions') }}</li> |
||||||
<li :class="{ active: activeTab === 'members' }" @click="activeTab = 'members'">Members</li> |
<li :class="{ active: activeTab === 'members' }" @click="activeTab = 'members'">{{ t('Members') }}</li> |
||||||
</ul> |
</ul> |
||||||
|
|
||||||
<div class="tab-content"> |
<div class="tab-content"> |
||||||
<GroupDiscussions v-if="activeTab === 'discussions'" :group-id="groupId" /> |
<GroupDiscussions v-if="activeTab === 'discussions'" :group-id="groupInfo.id" /> |
||||||
<GroupMembers v-if="activeTab === 'members'" :group-id="groupId" /> |
<GroupMembers v-if="activeTab === 'members'" :group-id="groupInfo.id" /> |
||||||
</div> |
</div> |
||||||
</div> |
</div> |
||||||
|
|
||||||
|
<div v-if="!isLoading && !groupInfo.isMember" class="text-center"> |
||||||
|
<div class="group-header"> |
||||||
|
<h1 class="group-title">{{ groupInfo?.title || '...' }}</h1> |
||||||
|
<p class="group-description">{{ groupInfo?.description }}</p> |
||||||
|
</div> |
||||||
|
<p v-if="groupInfo.visibility === 2">{{ t('This is a closed group.') }}</p> |
||||||
|
<p v-if="groupInfo.role === 3">{{ t('You already sent an invitation') }}</p> |
||||||
|
<p v-else>{{ t('Join this group to see the content.') }}</p> |
||||||
|
<BaseButton |
||||||
|
v-if="groupInfo.visibility === 1 && groupInfo.role !== 3" |
||||||
|
:label="t('Join to group')" |
||||||
|
type="primary" |
||||||
|
class="mt-4" |
||||||
|
@click="joinGroup" |
||||||
|
icon="mdi-account-multiple-plus" |
||||||
|
/> |
||||||
|
</div> |
||||||
</template> |
</template> |
||||||
|
|
||||||
<script setup> |
<script setup> |
||||||
import { ref, onMounted } from 'vue' |
import { ref, onMounted } from 'vue' |
||||||
import { useRoute } from 'vue-router' |
import { useRoute } from 'vue-router' |
||||||
import axios from 'axios' |
|
||||||
import GroupDiscussions from "../../components/usergroup/GroupDiscussions.vue" |
import GroupDiscussions from "../../components/usergroup/GroupDiscussions.vue" |
||||||
import GroupMembers from "../../components/usergroup/GroupMembers.vue" |
import GroupMembers from "../../components/usergroup/GroupMembers.vue" |
||||||
|
import { useI18n } from "vue-i18n" |
||||||
|
import { useSocialInfo } from "../../composables/useSocialInfo" |
||||||
|
import axios from "axios" |
||||||
|
import BaseButton from "../../components/basecomponents/BaseButton.vue" |
||||||
|
|
||||||
|
const { t } = useI18n() |
||||||
const route = useRoute() |
const route = useRoute() |
||||||
const activeTab = ref('discussions') |
const activeTab = ref('discussions') |
||||||
const groupId = ref(route.params.group_id) |
const { user, groupInfo, isGroup, loadGroup, isLoading } = useSocialInfo(); |
||||||
const group = ref(null) |
|
||||||
onMounted(async () => { |
const joinGroup = async () => { |
||||||
if (groupId.value) { |
|
||||||
try { |
try { |
||||||
const response = await axios.get(`/api/usergroup/${groupId.value}`) |
const response = await axios.post('/social-network/group-action', { |
||||||
group.value = response.data |
userId: user.value.id, |
||||||
|
groupId: groupInfo.value.id, |
||||||
|
action: 'join' |
||||||
|
}); |
||||||
|
|
||||||
|
if (response.data.success) { |
||||||
|
await loadGroup(groupInfo.value.id); |
||||||
|
} |
||||||
} catch (error) { |
} catch (error) { |
||||||
console.error('Error fetching group details:', error) |
console.error('Error joining the group:', error); |
||||||
} |
} |
||||||
|
}; |
||||||
|
|
||||||
|
onMounted(async () => { |
||||||
|
if (route.params.group_id) { |
||||||
|
await loadGroup(route.params.group_id); |
||||||
} |
} |
||||||
}) |
}); |
||||||
</script> |
</script> |
||||||
|
@ -0,0 +1,114 @@ |
|||||||
|
<template> |
||||||
|
<BaseButton |
||||||
|
label="Try and find some friends" |
||||||
|
icon="search" |
||||||
|
type="success" |
||||||
|
size="normal" |
||||||
|
@click="goToSearch" |
||||||
|
/> |
||||||
|
<div> |
||||||
|
<InvitationList |
||||||
|
:invitations="receivedInvitations" |
||||||
|
title="Invitations Received" |
||||||
|
@accept="acceptInvitation" |
||||||
|
@deny="denyInvitation" |
||||||
|
/> |
||||||
|
<InvitationList |
||||||
|
:invitations="sentInvitations" |
||||||
|
title="Invitations Sent" |
||||||
|
/> |
||||||
|
<InvitationList |
||||||
|
:invitations="pendingInvitations" |
||||||
|
title="Pending Group Invitations" |
||||||
|
@accept="acceptGroupInvitation" |
||||||
|
@deny="denyGroupInvitation" |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script setup> |
||||||
|
import axios from 'axios' |
||||||
|
import { inject, onMounted, ref, watchEffect } from "vue" |
||||||
|
import InvitationList from "../../components/userreluser/InvitationList.vue" |
||||||
|
import BaseButton from "../../components/basecomponents/BaseButton.vue" |
||||||
|
import { useRouter } from "vue-router" |
||||||
|
|
||||||
|
const receivedInvitations = ref([]) |
||||||
|
const sentInvitations = ref([]) |
||||||
|
const pendingInvitations = ref([]) |
||||||
|
const router = useRouter() |
||||||
|
|
||||||
|
const user = inject('social-user') |
||||||
|
const isCurrentUser = inject('is-current-user') |
||||||
|
|
||||||
|
|
||||||
|
watchEffect(() => { |
||||||
|
if (user.value && user.value.id) { |
||||||
|
fetchInvitations(user.value.id) |
||||||
|
} |
||||||
|
}) |
||||||
|
const fetchInvitations = async (userId) => { |
||||||
|
if (!userId) return |
||||||
|
try { |
||||||
|
const response = await axios.get(`/social-network/invitations/${userId}`) |
||||||
|
console.log('Invitations :::', response.data) |
||||||
|
receivedInvitations.value = response.data.receivedInvitations |
||||||
|
sentInvitations.value = response.data.sentInvitations |
||||||
|
pendingInvitations.value = response.data.pendingGroupInvitations |
||||||
|
} catch (error) { |
||||||
|
console.error('Error fetching invitations:', error) |
||||||
|
} |
||||||
|
} |
||||||
|
function goToSearch() { |
||||||
|
router.push({ name: 'SocialSearch' }) |
||||||
|
} |
||||||
|
|
||||||
|
const acceptInvitation = async (invitationId) => { |
||||||
|
const invitation = receivedInvitations.value.find(invite => invite.id === invitationId) |
||||||
|
if (!invitation) return |
||||||
|
console.log('Invitation object:', invitation) |
||||||
|
const data = { |
||||||
|
userId: user.value.id, |
||||||
|
targetUserId: invitation.itemId, |
||||||
|
action: 'add_friend', |
||||||
|
is_my_friend: true, |
||||||
|
} |
||||||
|
try { |
||||||
|
const response = await axios.post('/social-network/user-action', data) |
||||||
|
if (response.data.success) { |
||||||
|
console.log('Invitation accepted successfully') |
||||||
|
fetchInvitations(user.value.id) |
||||||
|
} else { |
||||||
|
console.error('Failed to accept invitation') |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
console.error('Error accepting invitation:', error) |
||||||
|
} |
||||||
|
} |
||||||
|
const denyInvitation = async (invitationId) => { |
||||||
|
const invitation = receivedInvitations.value.find(invite => invite.id === invitationId) |
||||||
|
if (!invitation) return |
||||||
|
const data = { |
||||||
|
userId: user.value.id, |
||||||
|
targetUserId: invitation.itemId, |
||||||
|
action: 'deny_friend', |
||||||
|
} |
||||||
|
try { |
||||||
|
const response = await axios.post('/social-network/user-action', data) |
||||||
|
if (response.data.success) { |
||||||
|
console.log('Invitation denied successfully') |
||||||
|
await fetchInvitations(user.value.id) |
||||||
|
} else { |
||||||
|
console.error('Failed to deny invitation') |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
console.error('Error denying invitation:', error) |
||||||
|
} |
||||||
|
} |
||||||
|
const acceptGroupInvitation = (groupId) => { |
||||||
|
console.log(`Accepted group invitation with ID: ${groupId}`) |
||||||
|
} |
||||||
|
const denyGroupInvitation = (groupId) => { |
||||||
|
console.log(`Denied group invitation with ID: ${groupId}`) |
||||||
|
} |
||||||
|
</script> |
Loading…
Reference in new issue