diff --git a/frontend/components/global/CopyText.vue b/frontend/components/global/CopyText.vue new file mode 100644 index 0000000..726ac74 --- /dev/null +++ b/frontend/components/global/CopyText.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 9b41094..e9d6af3 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -16,12 +16,34 @@ navigateTo("/home"); } + const route = useRoute(); + const router = useRouter(); + const username = ref(""); const email = ref(""); const groupName = ref(""); const password = ref(""); const canRegister = ref(false); + const groupToken = computed({ + get() { + const params = route.query.token; + + if (typeof params === "string") { + return params; + } + + return ""; + }, + set(v) { + router.push({ + query: { + token: v, + }, + }); + }, + }); + async function registerUser() { loading.value = true; const { error } = await api.register({ @@ -29,6 +51,7 @@ email: email.value, password: password.value, groupName: groupName.value, + token: groupToken.value, }); if (error) { @@ -42,6 +65,13 @@ registerForm.value = false; } + onMounted(() => { + console.log(groupToken.value); + if (groupToken.value !== "") { + registerForm.value = true; + } + }); + const loading = ref(false); const loginPassword = ref(""); @@ -57,6 +87,7 @@ toast.success("Logged in successfully"); + // @ts-expect-error - expires is either a date or a string, need to figure out store typing authStore.$patch({ token: data.token, expires: data.expiresAt, @@ -122,7 +153,13 @@ - + +
+

You're Joining an Existing Group!

+ +
diff --git a/frontend/pages/profile.vue b/frontend/pages/profile.vue index 013fda5..165b489 100644 --- a/frontend/pages/profile.vue +++ b/frontend/pages/profile.vue @@ -144,25 +144,12 @@ name: "Email", text: auth.self?.email || "Unknown", }, - { - name: "Invitation Code", - text: "", - slot: "invitation", - }, - { - name: "Change Password", - text: "", - slot: "change-password", - }, - { - name: "Delete Profile", - text: "", - slot: "delete-profile", - }, ] as Detail[]; }); + const api = useUserApi(); const confirm = useConfirm(); + const notify = useNotifier(); async function deleteProfile() { const result = await confirm.open( @@ -173,7 +160,37 @@ return; } - console.log("delete profile"); + const { response } = await api.user.delete(); + + if (response?.status === 204) { + notify.success("Your account has been deleted."); + auth.logout(api); + navigateTo("/"); + } + + notify.error("Failed to delete your account."); + } + + const token = ref(""); + const tokenUrl = computed(() => { + if (!window) { + return ""; + } + + return `${window.location.origin}?token=${token.value}`; + }); + + async function generateToken() { + const date = new Date(); + + const { response, data } = await api.group.createInvitation({ + expiresAt: new Date(date.setDate(date.getDate() + 7)), + uses: 1, + }); + + if (response?.status === 201) { + token.value = data.token; + } } @@ -182,23 +199,28 @@ - - - - - + + +
+
+ Change Password + Generate Invite Link +
+
+ + {{ tokenUrl }} +
+
+ + {{ token }} +
+
@@ -251,6 +273,20 @@
+ + + + diff --git a/frontend/stores/auth.ts b/frontend/stores/auth.ts index 2a2d2b7..a7e641f 100644 --- a/frontend/stores/auth.ts +++ b/frontend/stores/auth.ts @@ -24,11 +24,7 @@ export const useAuthStore = defineStore("auth", { }, actions: { async logout(api: UserClient) { - const result = await api.logout(); - - if (result.error) { - return result; - } + const result = await api.user.logout(); this.token = ""; this.expires = "";