Added login page.

This commit is contained in:
Andrew Lalis 2023-01-31 09:13:18 +01:00
parent c56f8f72c2
commit 6b1e20d544
7 changed files with 159 additions and 63 deletions

View File

@ -21,7 +21,7 @@
v-if="!authStore.loggedIn" v-if="!authStore.loggedIn"
no-caps no-caps
icon="person" icon="person"
to="/login" @click="goToLoginPage"
/> />
</div> </div>
</template> </template>
@ -29,8 +29,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAuthStore } from 'stores/auth-store'; import { useAuthStore } from 'stores/auth-store';
import api from 'src/api/main'; import api from 'src/api/main';
import {useRoute, useRouter} from 'vue-router';
const authStore = useAuthStore(); const authStore = useAuthStore();
const route = useRoute();
const router = useRouter();
async function goToLoginPage() {
await router.push({
path: '/login',
query: {
next: encodeURIComponent(route.path)
}
});
}
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -6,13 +6,11 @@ width for smaller screens.
Use this as the root component for any pages you create. Use this as the root component for any pages you create.
--> -->
<template> <template>
<q-page> <div class="row justify-center">
<div class="row justify-center"> <div class="col-xs-12 col-md-6 q-px-sm">
<div class="col-xs-12 col-md-6 q-px-sm"> <slot>
<slot> <p>Page content</p>
<p>Page content</p> </slot>
</slot>
</div>
</div> </div>
</q-page> </div>
</template> </template>

View File

@ -1,25 +1,27 @@
<template> <template>
<StandardCenteredPage> <q-page>
<q-input <StandardCenteredPage>
v-model="searchQuery" <q-input
:label="$t('indexPage.searchHint')" v-model="searchQuery"
clearable :label="$t('indexPage.searchHint')"
:loading="searchBarLoadingState" clearable
@update:modelValue="onSearchQueryUpdated" :loading="searchBarLoadingState"
class="q-mt-lg" @update:modelValue="onSearchQueryUpdated"
> class="q-mt-lg"
<template v-slot:append> >
<q-icon name="search" /> <template v-slot:append>
</template> <q-icon name="search" />
</q-input> </template>
<q-list> </q-input>
<GymSearchResultListItem <q-list>
v-for="result in searchResults" <GymSearchResultListItem
:gym="result" v-for="result in searchResults"
:key="result.compoundId" :gym="result"
/> :key="result.compoundId"
</q-list> />
</StandardCenteredPage> </q-list>
</StandardCenteredPage>
</q-page>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -0,0 +1,78 @@
<template>
<StandardCenteredPage>
<h3 class="text-center">Login to Gymboard</h3>
<q-form @submit="tryLogin" @reset="resetLogin">
<SlimForm>
<div class="row">
<q-input
:label="$t('loginPage.email')"
v-model="loginModel.email"
class="col-12"
/>
</div>
<div class="row">
<q-input
:label="$t('loginPage.password')"
v-model="loginModel.password"
:type="passwordVisible ? 'text' : 'password'"
class="col-12"
>
<template v-slot:append>
<q-icon
:name="passwordVisible ? 'visibility' : 'visibility_off'"
class="cursor-pointer"
@click="passwordVisible = !passwordVisible"
/>
</template>
</q-input>
</div>
<div class="row">
<q-btn type="submit" label="Log in" color="primary" class="q-mt-md col-12" no-caps/>
</div>
<div class="row">
<q-btn flat no-caps label="Create an account" color="secondary" class="q-mt-md col-12" style="text-decoration: underline"/>
</div>
</SlimForm>
</q-form>
</StandardCenteredPage>
</template>
<script setup lang="ts">
import StandardCenteredPage from 'src/components/StandardCenteredPage.vue';
import SlimForm from 'components/SlimForm.vue';
import {ref} from 'vue';
import api from 'src/api/main';
import {useAuthStore} from 'stores/auth-store';
import {useRoute, useRouter} from 'vue-router';
const authStore = useAuthStore();
const router = useRouter();
const route = useRoute();
const loginModel = ref({
email: '',
password: ''
});
const passwordVisible = ref(false);
async function tryLogin() {
console.log('logging in...');
try {
await api.auth.login(authStore, loginModel.value);
const dest = route.query.next ? decodeURIComponent(route.query.next as string) : '/';
await router.push(dest);
} catch (error) {
console.error(error);
}
}
function resetLogin() {
loginModel.value.email = '';
loginModel.value.password = '';
}
</script>
<style scoped>
</style>

View File

@ -1,16 +1,18 @@
<template> <template>
<StandardCenteredPage> <q-page>
<h3>Testing Page</h3> <StandardCenteredPage>
<p> <h3>Testing Page</h3>
Use this page to test new functionality, before adding it to the main app. <p>
This page should be hidden on production. Use this page to test new functionality, before adding it to the main app.
</p> This page should be hidden on production.
<div style="border: 3px solid red"> </p>
<h4>Auth Test</h4> <div style="border: 3px solid red">
<q-btn label="Do auth" @click="doAuth()" /> <h4>Auth Test</h4>
<q-btn label="Logout" @click="api.auth.logout(authStore)" /> <q-btn label="Do auth" @click="doAuth()" />
</div> <q-btn label="Logout" @click="api.auth.logout(authStore)" />
</StandardCenteredPage> </div>
</StandardCenteredPage>
</q-page>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -1,25 +1,27 @@
<template> <template>
<StandardCenteredPage v-if="gym"> <q-page>
<h3 class="q-my-md text-center">{{ gym.displayName }}</h3> <StandardCenteredPage v-if="gym">
<q-btn-group spread square push> <h3 class="q-my-md text-center">{{ gym.displayName }}</h3>
<q-btn <q-btn-group spread square push>
:label="$t('gymPage.home')" <q-btn
:to="getGymRoute(gym)" :label="$t('gymPage.home')"
:color="homePageSelected ? 'primary' : 'secondary'" :to="getGymRoute(gym)"
/> :color="homePageSelected ? 'primary' : 'secondary'"
<q-btn />
:label="$t('gymPage.submit')" <q-btn
:to="getGymRoute(gym) + '/submit'" :label="$t('gymPage.submit')"
:color="submitPageSelected ? 'primary' : 'secondary'" :to="getGymRoute(gym) + '/submit'"
/> :color="submitPageSelected ? 'primary' : 'secondary'"
<q-btn />
:label="$t('gymPage.leaderboard')" <q-btn
:to="getGymRoute(gym) + '/leaderboard'" :label="$t('gymPage.leaderboard')"
:color="leaderboardPageSelected ? 'primary' : 'secondary'" :to="getGymRoute(gym) + '/leaderboard'"
/> :color="leaderboardPageSelected ? 'primary' : 'secondary'"
</q-btn-group> />
<router-view /> </q-btn-group>
</StandardCenteredPage> <router-view />
</StandardCenteredPage>
</q-page>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">

View File

@ -6,6 +6,7 @@ import GymSubmissionPage from 'pages/gym/GymSubmissionPage.vue';
import GymHomePage from 'pages/gym/GymHomePage.vue'; import GymHomePage from 'pages/gym/GymHomePage.vue';
import GymLeaderboardsPage from 'pages/gym/GymLeaderboardsPage.vue'; import GymLeaderboardsPage from 'pages/gym/GymLeaderboardsPage.vue';
import TestingPage from 'pages/TestingPage.vue'; import TestingPage from 'pages/TestingPage.vue';
import LoginPage from 'pages/LoginPage.vue';
const routes: RouteRecordRaw[] = [ const routes: RouteRecordRaw[] = [
{ {
@ -25,6 +26,7 @@ const routes: RouteRecordRaw[] = [
}, },
], ],
}, },
{ path: '/login', component: LoginPage },
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it