Ugraded all pages to vue 3 & typescript

This commit is contained in:
2022-08-06 16:10:37 +02:00
parent d12dfc3c8e
commit b7e7fe9c55
10 changed files with 623 additions and 737 deletions

View File

@@ -2,146 +2,159 @@
<section>
<h1>Register new user</h1>
<div class="form">
<form class="form" ref="formElement">
<seasoned-input
ref="username"
placeholder="username"
icon="Email"
type="email"
:value.sync="username"
@enter="submit"
v-model="username"
@keydown.enter="focusOnNextElement"
/>
<seasoned-input
placeholder="password"
icon="Keyhole"
type="password"
:value.sync="password"
@enter="submit"
v-model="password"
@keydown.enter="focusOnNextElement"
/>
<seasoned-input
placeholder="repeat password"
icon="Keyhole"
type="password"
:value.sync="passwordRepeat"
@enter="submit"
v-model="passwordRepeat"
@keydown.enter="submit"
/>
<seasoned-button @click="submit">Register</seasoned-button>
</div>
</form>
<router-link class="link" to="/signin"
>Have a user? Sign in here</router-link
>
<seasoned-messages :messages.sync="messages"></seasoned-messages>
<seasoned-messages v-model:messages="messages"></seasoned-messages>
</section>
</template>
<script>
import { mapActions } from "vuex";
import { register } from "@/api";
import SeasonedButton from "@/components/ui/SeasonedButton";
import SeasonedInput from "@/components/ui/SeasonedInput";
import SeasonedMessages from "@/components/ui/SeasonedMessages";
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import SeasonedButton from "@/components/ui/SeasonedButton.vue";
import SeasonedInput from "@/components/ui/SeasonedInput.vue";
import SeasonedMessages from "@/components/ui/SeasonedMessages.vue";
import { register } from "../api";
import { focusFirstFormInput, focusOnNextElement } from "../utils";
import type { Ref } from "vue";
import type IErrorMessage from "../interfaces/IErrorMessage";
export default {
components: { SeasonedButton, SeasonedInput, SeasonedMessages },
data() {
return {
messages: [],
username: null,
password: null,
passwordRepeat: null
};
},
methods: {
...mapActions("user", ["login"]),
submit() {
this.messages = [];
let { username, password, passwordRepeat } = this;
const username: Ref<string> = ref("");
const password: Ref<string> = ref("");
const passwordRepeat: Ref<string> = ref("");
const messages: Ref<IErrorMessage[]> = ref([]);
const formElement: Ref<HTMLFormElement> = ref(null);
if (username == null || username.length == 0) {
this.messages.push({ type: "error", title: "Missing username" });
return;
} else if (password == null || password.length == 0) {
this.messages.push({ type: "error", title: "Missing password" });
return;
} else if (passwordRepeat == null || passwordRepeat.length == 0) {
this.messages.push({ type: "error", title: "Missing repeat password" });
return;
} else if (passwordRepeat != password) {
this.messages.push({ type: "error", title: "Passwords do not match" });
return;
const store = useStore();
const router = useRouter();
onMounted(() => focusFirstFormInput(formElement.value));
function clearMessages() {
messages.value = [];
}
function addErrorMessage(message: string, title?: string) {
messages.value.push({ message, title, type: "error" });
}
function addWarningMessage(message: string, title?: string) {
messages.value.push({ message, title, type: "warning" });
}
function validate(): Promise<boolean> {
return new Promise((resolve, reject) => {
if (!username.value || username?.value?.length === 0) {
addWarningMessage("Missing username", "Validation error");
return reject();
}
this.registerUser(username, password);
},
registerUser(username, password) {
register(username, password)
.then(data => {
if (data.success && this.login()) {
this.$router.push({ name: "profile" });
}
})
.catch(error => {
if (error.status === 401) {
this.messages.push({
type: "error",
title: "Access denied",
message: "Incorrect username or password"
});
} else {
this.messages.push({
type: "error",
title: "Unexpected error",
message: error.message
});
}
});
}
},
mounted() {
try {
this.$refs.username.$el.getElementsByTagName("input")[0].focus();
} catch {}
if (!password.value || password?.value?.length === 0) {
addWarningMessage("Missing password", "Validation error");
return reject();
}
if (passwordRepeat.value == null || passwordRepeat.value.length == 0) {
addWarningMessage("Missing repeat password", "Validation error");
return reject();
}
if (passwordRepeat != password) {
addWarningMessage("Passwords do not match", "Validation error");
return reject();
}
resolve(true);
});
}
function submit() {
clearMessages();
validate().then(registerUser);
}
function registerUser() {
register(username.value, password.value)
.then(data => {
if (data?.success && store.dispatch("user/login")) {
router.push({ name: "profile" });
}
})
.catch(error => {
if (error?.status === 401) {
return addErrorMessage(
"Incorrect username or password",
"Access denied"
);
}
addErrorMessage(error?.message, "Unexpected error");
});
}
};
</script>
<style lang="scss" scoped>
@import "src/scss/variables";
@import "src/scss/variables";
section {
padding: 1.3rem;
section {
padding: 1.3rem;
@include tablet-min {
padding: 4rem;
}
@include tablet-min {
padding: 4rem;
}
.form > div,
input,
button {
margin-bottom: 1rem;
.form > div,
input,
button {
margin-bottom: 1rem;
&:last-child {
margin-bottom: 0px;
&:last-child {
margin-bottom: 0px;
}
}
h1 {
margin: 0;
line-height: 16px;
color: $text-color;
font-weight: 300;
margin-bottom: 20px;
text-transform: uppercase;
}
.link {
display: block;
width: max-content;
margin-top: 1rem;
}
}
h1 {
margin: 0;
line-height: 16px;
color: $text-color;
font-weight: 300;
margin-bottom: 20px;
text-transform: uppercase;
}
.link {
display: block;
width: max-content;
margin-top: 1rem;
}
}
</style>