Compare commits
8 commits
profile-mo
...
main
Author | SHA1 | Date | |
---|---|---|---|
8be948623b | |||
82e0e59617 | |||
b07a0aa5a0 | |||
eb2af0f7ec | |||
ddf173ee8b | |||
6a65b257e0 | |||
c87fffe6c9 | |||
08436fdce0 |
7 changed files with 194 additions and 5 deletions
|
@ -8,7 +8,6 @@ steps:
|
|||
- pnpm build
|
||||
when:
|
||||
- event: push
|
||||
- event: pull_request
|
||||
|
||||
- name: container-build-and-publish
|
||||
image: docker
|
||||
|
|
5
app.vue
5
app.vue
|
@ -55,7 +55,10 @@ function contextMenuHandler(e: MouseEvent) {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
html {
|
||||
background-color: #1f1e1d;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--preferred-font), Arial, Helvetica, sans-serif;
|
||||
box-sizing: border-box;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import Cropper from 'cropperjs';
|
||||
import Button from '../UserInterface/Button.vue';
|
||||
|
||||
const props = defineProps({
|
||||
imageSrc: String,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import CropPopup from '~/components/Popups/CropPopup.vue';
|
||||
import UserPopup from '~/components/User/UserPopup.vue';
|
||||
import Button from '~/components/UserInterface/Button.vue';
|
||||
|
||||
|
@ -41,7 +42,7 @@ import type { UserResponse } from '~/types/interfaces';
|
|||
let newPfpFile: File;
|
||||
const isCropPopupVisible = ref(false);
|
||||
const cropImageSrc = ref("")
|
||||
;
|
||||
|
||||
const { fetchUser } = useAuth();
|
||||
|
||||
const user: UserResponse | undefined = await fetchUser()
|
||||
|
|
|
@ -94,6 +94,10 @@ export const useApi = () => {
|
|||
await fetchWithApi("/auth/reset-password", { method: "POST", body: { password, token } });
|
||||
}
|
||||
|
||||
async function fetchInvite(id: string): Promise<GuildResponse | undefined> {
|
||||
return await fetchWithApi(`/invites/${id}`);
|
||||
}
|
||||
|
||||
return {
|
||||
fetchGuilds,
|
||||
fetchGuild,
|
||||
|
@ -115,6 +119,7 @@ export const useApi = () => {
|
|||
fetchInstanceStats,
|
||||
sendVerificationEmail,
|
||||
sendPasswordResetEmail,
|
||||
resetPassword
|
||||
resetPassword,
|
||||
fetchInvite
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ export const useAuth = () => {
|
|||
async function logout() {
|
||||
console.log("access:", accessToken.value);
|
||||
|
||||
await fetchWithApi("/auth/logout", { method: "GET", credentials: "include" });
|
||||
await fetchWithApi("/auth/logout", { method: "DELETE", credentials: "include" });
|
||||
clearAuth();
|
||||
|
||||
return await navigateTo("/login");
|
||||
|
|
180
pages/invite/[inviteId].vue
Normal file
180
pages/invite/[inviteId].vue
Normal file
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<div id="invite-root">
|
||||
<div id="invite-container">
|
||||
<div id="guild-container" v-if="guild">
|
||||
<h1>You have been invited to {{ guild.name }}!</h1>
|
||||
<div id="guild-card">
|
||||
<div id="card-grid">
|
||||
<div id="guild-details">
|
||||
<div id="guild-name" title="Server name">
|
||||
<span>{{ guild.name }}</span>
|
||||
</div>
|
||||
<div id="guild-member-count" :title="`${guild.member_count} members`">
|
||||
<Icon name="lucide:users" />
|
||||
<span>{{ guild.member_count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<VerticalSpacer id="space" />
|
||||
<div id="guild-description">
|
||||
<span>{{ guild.description }}</span>
|
||||
</div>
|
||||
<div id="guild-icon">
|
||||
<NuxtImg v-if="guild.icon" id="guild-icon-img" :src="guild.icon" :alt="`${guild.name} server icon`" />
|
||||
</div>
|
||||
</div>
|
||||
<Button :text="isMember ? 'Joined' : 'Join'" variant="normal" :callback="acceptInvite" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="errorMessage">
|
||||
<h1>{{ errorMessage }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Button from '~/components/UserInterface/Button.vue';
|
||||
import VerticalSpacer from '~/components/UserInterface/VerticalSpacer.vue';
|
||||
import type { GuildResponse } from '~/types/interfaces';
|
||||
|
||||
|
||||
const route = useRoute();
|
||||
const { fetchInvite, joinGuild, fetchMembers } = useApi();
|
||||
const { getUser } = useAuth();
|
||||
|
||||
const inviteId = route.params.inviteId as string;
|
||||
|
||||
const guild = ref<GuildResponse>();
|
||||
const errorMessage = ref<string>();
|
||||
const isMember = ref(false);
|
||||
|
||||
const accessToken = useCookie("access_token");
|
||||
|
||||
if (inviteId) {
|
||||
try {
|
||||
guild.value = await fetchInvite(inviteId);
|
||||
console.log("invite guild:", guild.value);
|
||||
if (accessToken.value && guild.value) {
|
||||
const members = await fetchMembers(guild.value.uuid);
|
||||
const me = await getUser();
|
||||
if (me && members.find(member => member.user.uuid == me.uuid)) {
|
||||
isMember.value = true;
|
||||
}
|
||||
}
|
||||
} catch (error: any) {
|
||||
if (error.response) {
|
||||
if (error.status == 404) {
|
||||
errorMessage.value = "That invite doesn't exist or has expired.";
|
||||
}
|
||||
}
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function acceptInvite() {
|
||||
if (accessToken.value && guild.value) {
|
||||
await joinGuild(inviteId);
|
||||
return await navigateTo(`/servers/${guild.value.uuid}`);
|
||||
}
|
||||
|
||||
return await navigateTo(`/login?redirect_to=${route.fullPath}`);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
#invite-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100dvh;
|
||||
}
|
||||
|
||||
#invite-container {
|
||||
border: .5rem solid var(--chat-highlighted-background-color);
|
||||
border-radius: var(--standard-radius);
|
||||
height: 50%;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
#guild-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 50%;
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
#guild-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--sidebar-highlighted-background-color);
|
||||
border: .5rem solid black;
|
||||
border-radius: var(--standard-radius);
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
#card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 5rem auto 1fr;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#guild-details {
|
||||
grid-row: 1;
|
||||
grid-column: span 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#guild-name {
|
||||
font-size: 2rem;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#guild-member-count {
|
||||
gap: .3rem;
|
||||
}
|
||||
|
||||
#space {
|
||||
grid-row: 2;
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
#guild-description {
|
||||
grid-row: 3;
|
||||
grid-column: span 3;
|
||||
word-break: break-all;
|
||||
padding: .3rem;
|
||||
}
|
||||
|
||||
#guild-name, #guild-member-count {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#guild-icon-img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: scale-down;
|
||||
}
|
||||
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue