add register and login to frontend

This commit is contained in:
Branden J Brown 2024-02-02 08:28:36 -06:00
parent a044844d8b
commit 410d0fc587
4 changed files with 144 additions and 59 deletions

View File

@ -13,5 +13,6 @@ declare module 'vue' {
PlayerHP: typeof import('./src/components/PlayerHP.vue')['default'] PlayerHP: typeof import('./src/components/PlayerHP.vue')['default']
PlayerItems: typeof import('./src/components/PlayerItems.vue')['default'] PlayerItems: typeof import('./src/components/PlayerItems.vue')['default']
TheLanding: typeof import('./src/components/TheLanding.vue')['default'] TheLanding: typeof import('./src/components/TheLanding.vue')['default']
TheLogin: typeof import('./src/components/TheLogin.vue')['default']
} }
} }

View File

@ -7,7 +7,15 @@
</template> </template>
</v-app-bar> </v-app-bar>
<v-main> <v-main>
<TheLanding v-if="!playing && !loading" @play="clickPlay" /> <v-container v-if="!playing && !loading">
<TheLanding />
<v-row v-if="!loadingMe && !me" class="d-flex justify-center">
<TheLogin />
</v-row>
<v-row v-else-if="!loadingMe" class="d-flex justify-center">
<v-btn @click="clickPlay" color="primary">Play</v-btn>
</v-row>
</v-container>
<v-container v-else-if="loading" class="fill-height"> <v-container v-else-if="loading" class="fill-height">
<v-row class="d-flex justify-center"> <v-row class="d-flex justify-center">
<v-progress-circular class="pa-8" indeterminate size="128"></v-progress-circular> <v-progress-circular class="pa-8" indeterminate size="128"></v-progress-circular>
@ -20,7 +28,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useDark, useToggle } from '@vueuse/core'; import { useDark, useToggle } from '@vueuse/core';
import { computed, ref } from 'vue'; import { computed, onMounted, ref } from 'vue';
import type { Action, Game } from '@/lib/game'; import type { Action, Game } from '@/lib/game';
const dark = useDark(); const dark = useDark();
@ -54,4 +62,26 @@ const testGame = ref<Game>({
function action(evt: Action) { function action(evt: Action) {
console.log(evt); console.log(evt);
} }
const loadingMe = ref(true);
const me = ref<string | null>(null);
onMounted(async () => {
loadingMe.value = true;
try {
const resp = await fetch('/user/me', {
method: 'GET',
mode: 'same-origin',
credentials: 'same-origin',
})
loadingMe.value = false;
if (!resp.ok) {
me.value = null;
return;
}
const { id } = await resp.json();
me.value = id as string;
} catch {
me.value = null;
}
});
</script> </script>

View File

@ -1,5 +1,4 @@
<template> <template>
<v-container>
<v-row> <v-row>
<v-col> <v-col>
<v-sheet rounded :elevation="5" class="pa-4"> <v-sheet rounded :elevation="5" class="pa-4">
@ -40,20 +39,4 @@
</v-sheet> </v-sheet>
</v-col> </v-col>
</v-row> </v-row>
<v-row>
<v-col width="auto"></v-col>
<v-col cols="auto">
<v-btn color="primary" @click="emit('play')">Play</v-btn>
</v-col>
<v-col width="auto"></v-col>
</v-row>
</v-container>
</template> </template>
<script setup lang="ts">
type Emits = {
(e: 'play'): void;
}
const emit = defineEmits<Emits>();
</script>

View File

@ -0,0 +1,71 @@
<template>
<v-dialog v-model="register" max-width="800">
<template #activator="{ props }">
<v-btn @click="register = !register" class="mx-4" color="secondary">Register</v-btn>
</template>
<v-card title="Register for an account">
<v-card-text>
<p class="text-button">This website uses cookies to provide its basic functionality. By signing up for an account, you agree to these cookies.</p>
<p class="text-button mb-8">I strive to collect the least user information possible and will never use it for any purpose except to provide the service.</p>
<v-form v-model="valid" action="/user/register" method="post">
<v-text-field v-model="user" label="username" name="user" clearable :rules="userRules"></v-text-field>
<v-text-field v-model="pass" label="password" name="pass" clearable :rules="passRules" type="password"></v-text-field>
<v-row class="mx-4 my-2">
<v-btn variant="tonal" @click="doCancel">Cancel</v-btn>
<v-spacer></v-spacer>
<v-btn variant="tonal" color="success" type="submit" :disabled="!valid">Register</v-btn>
</v-row>
</v-form>
</v-card-text>
</v-card>
</v-dialog>
<v-dialog v-model="login" max-width="800">
<template #activator="{ props }">
<v-btn @click="login = !login" class="mx-4" color="primary">Log In</v-btn>
</template>
<v-card title="Log In">
<v-card-text>
<p class="text-button">This website uses cookies to provide its basic functionality. By signing into your account, you agree to these cookies.</p>
<p class="text-button mb-8">I strive to collect the least user information possible and will never use it for any purpose except to provide the service.</p>
<v-form v-model="valid" action="/user/login" method="post">
<v-text-field v-model="user" label="username" name="user" clearable :rules="userRules"></v-text-field>
<v-text-field v-model="pass" label="password" name="pass" clearable :rules="passRules" type="password"></v-text-field>
<v-row class="mx-4 my-2">
<v-btn variant="tonal" @click="doCancel">Cancel</v-btn>
<v-spacer></v-spacer>
<v-btn variant="tonal" color="success" type="submit" :disabled="!valid">Log In</v-btn>
</v-row>
</v-form>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const valid = ref<boolean | null>(null);
const register = ref(false);
const login = ref(false);
const user = ref('');
const pass = ref('');
const userRules = [
(v: string) => v.length >= 4 || 'username too short',
(v: string) => v.length <= 30 || 'username too long',
];
const passRules = [
(v: string) => v.length >= 8 || 'password too short',
(v: string) => v.length <= 256 || 'password too long',
]
function doCancel() {
user.value = '';
pass.value = '';
register.value = false;
login.value = false;
}
</script>