feat: midterm shit done
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import { login } from '../../lib/api';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useAuthStore } from '../../stores/auth';
|
||||
|
||||
const username = ref('');
|
||||
const password = ref('');
|
||||
const router = useRouter();
|
||||
|
||||
const usernameError = ref('');
|
||||
const passwordError = ref('');
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
function validateUsername() {
|
||||
if (!username.value) {
|
||||
usernameError.value = 'Username is required.';
|
||||
} else if (username.value.length < 3) {
|
||||
usernameError.value = 'Username must be at least 3 characters.';
|
||||
} else {
|
||||
usernameError.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
function validatePassword() {
|
||||
if (!password.value) {
|
||||
passwordError.value = 'Password is required.';
|
||||
} else if (password.value.length < 8) {
|
||||
passwordError.value = 'Password must be at least 8 characters.';
|
||||
} else {
|
||||
passwordError.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => username.value,
|
||||
() => {
|
||||
validateUsername();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => password.value,
|
||||
() => {
|
||||
validatePassword();
|
||||
}
|
||||
);
|
||||
|
||||
const onSubmit = async () => {
|
||||
validateUsername();
|
||||
validatePassword();
|
||||
|
||||
if (usernameError.value || passwordError.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await login(username.value, password.value);
|
||||
const { jwt } = response;
|
||||
authStore.setJwt(jwt);
|
||||
alert('Login successful!');
|
||||
router.push('/profile');
|
||||
} catch (error) {
|
||||
alert("Login failed: " + error.message);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<fieldset class="ts-fieldset">
|
||||
<legend class="ts-legend">Login</legend>
|
||||
<div class="ts-wrap is-vertical">
|
||||
<div class="ts-control">
|
||||
<div class="label">Username</div>
|
||||
<div class="content is-fluid">
|
||||
<div class="ts-input" :class="{'is-negative': usernameError}">
|
||||
<input name="username" type="text" placeholder="Username" v-model="username" />
|
||||
</div>
|
||||
<div class="ts-text is-small is-negative" v-if="usernameError">{{ usernameError }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ts-control">
|
||||
<div class="label">Password</div>
|
||||
<div class="content is-fluid">
|
||||
<div class="ts-input" :class="{'is-negative': passwordError}">
|
||||
<input name="password" type="password" placeholder="Password" v-model="password" />
|
||||
</div>
|
||||
<div class="ts-text is-small is-negative" v-if="passwordError">{{ passwordError }}</div>
|
||||
<div class="ts-text is-small is-negative">Warning: This is for demonstration purposes only. Passwords are stored in plaintext!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ts-wrap has-top-spaced is-end-aligned">
|
||||
<button class="ts-button" type="submit" :class="{
|
||||
'is-disabled': username === '' || password === '' || usernameError !== '' || passwordError !== ''
|
||||
}">Submit</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ts-error {
|
||||
color: red;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user