implement UI for url and join

This commit is contained in:
Hayden 2022-10-03 21:36:51 -08:00
parent 505099ee26
commit 76c6d25850
4 changed files with 141 additions and 34 deletions

View file

@ -0,0 +1,38 @@
<template>
<button class="btn btn-outline btn-square btn-sm" @click="copyText">
<label
class="swap swap-rotate"
:class="{
'swap-active': copied,
}"
>
<Icon class="swap-off h-5 w-5" name="mdi-content-copy" />
<Icon class="swap-on h-5 w-5" name="mdi-clipboard" />
</label>
</button>
</template>
<script setup lang="ts">
const props = defineProps({
text: {
type: String as () => string,
default: "",
},
});
const copied = ref(false);
const { copy } = useClipboard();
function copyText() {
copy(props.text);
copied.value = true;
setTimeout(() => {
copied.value = false;
console.log(copied.value);
}, 1000);
}
</script>
<style scoped></style>

View file

@ -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<string>({
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 @@
</h2>
<FormTextField v-model="email" label="Set your email?" />
<FormTextField v-model="username" label="What's your name?" />
<FormTextField v-model="groupName" label="Name your group" />
<FormTextField v-if="groupToken == ''" v-model="groupName" label="Name your group" />
<div v-else class="pt-4 pb-1 text-center">
<p>You're Joining an Existing Group!</p>
<button type="button" class="text-xs underline" @click="groupToken = ''">
Don't Want To Join a Group?
</button>
</div>
<FormTextField v-model="password" label="Set your password" type="password" />
<PasswordScore v-model:valid="canRegister" :password="password" />
<div class="card-actions justify-end">

View file

@ -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;
}
}
</script>
@ -182,23 +199,28 @@
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-fill" class="mr-2 text-base-600" />
<Icon name="mdi-account" class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> User Profile </span>
<template #description> Invite users, and manage your account. </template>
</BaseSectionHeader>
</template>
<DetailsSection :details="details">
<template #invitation>
<BaseButton class="ml-auto" size="sm"> Generate Invite Link </BaseButton>
</template>
<template #change-password>
<BaseButton class="ml-auto" size="sm"> Change Password </BaseButton>
</template>
<template #delete-profile>
<BaseButton class="ml-auto btn-error" size="sm" @click="deleteProfile"> Delete Profile </BaseButton>
</template>
</DetailsSection>
<DetailsSection :details="details" />
<div class="p-4">
<div class="flex gap-2">
<BaseButton size="sm"> Change Password </BaseButton>
<BaseButton size="sm" @click="generateToken"> Generate Invite Link </BaseButton>
</div>
<div v-if="token" class="pt-4 flex items-center pl-1">
<CopyText class="mr-2 btn-primary" :text="tokenUrl" />
{{ tokenUrl }}
</div>
<div v-if="token" class="pt-4 flex items-center pl-1">
<CopyText class="mr-2 btn-primary" :text="token" />
{{ token }}
</div>
</div>
</BaseCard>
<BaseCard>
@ -251,6 +273,20 @@
</div>
</div>
</BaseCard>
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-delete" class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Delete Account</span>
<template #description> Delete your account and all it's associated data </template>
</BaseSectionHeader>
<div class="py-4 border-t-2 border-gray-300">
<BaseButton class="btn-error" @click="deleteProfile"> Delete Account </BaseButton>
</div>
</template>
</BaseCard>
</BaseContainer>
</template>

View file

@ -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 = "";