forked from mirrors/homebox
inject defaults + cleanup
This commit is contained in:
parent
9b46ea7874
commit
5f589f95b8
8 changed files with 212 additions and 85 deletions
|
@ -1,23 +1,31 @@
|
|||
import { PublicApi } from "~~/lib/api/public";
|
||||
import { UserApi } from "~~/lib/api/user";
|
||||
import { Requests } from "~~/lib/requests";
|
||||
import { useAuthStore } from "~~/stores/auth";
|
||||
import { PublicApi } from '~~/lib/api/public';
|
||||
import { UserApi } from '~~/lib/api/user';
|
||||
import { Requests } from '~~/lib/requests';
|
||||
import { useAuthStore } from '~~/stores/auth';
|
||||
|
||||
async function ApiDebugger(r: Response) {
|
||||
function ApiDebugger(r: Response) {
|
||||
console.table({
|
||||
"Request Url": r.url,
|
||||
"Response Status": r.status,
|
||||
"Response Status Text": r.statusText,
|
||||
'Request Url': r.url,
|
||||
'Response Status': r.status,
|
||||
'Response Status Text': r.statusText,
|
||||
});
|
||||
}
|
||||
|
||||
export function usePublicApi(): PublicApi {
|
||||
const requests = new Requests("", "", {}, ApiDebugger);
|
||||
const requests = new Requests('', '', {});
|
||||
return new PublicApi(requests);
|
||||
}
|
||||
|
||||
export function useUserApi(): UserApi {
|
||||
const authStore = useAuthStore();
|
||||
const requests = new Requests("", () => authStore.token, {}, ApiDebugger);
|
||||
|
||||
const requests = new Requests('', () => authStore.token, {});
|
||||
requests.addResponseInterceptor(ApiDebugger);
|
||||
requests.addResponseInterceptor(r => {
|
||||
if (r.status === 401) {
|
||||
authStore.clearSession();
|
||||
}
|
||||
});
|
||||
|
||||
return new UserApi(requests);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@ export enum Method {
|
|||
DELETE = 'DELETE',
|
||||
}
|
||||
|
||||
export type RequestInterceptor = (r: Response) => void;
|
||||
export type ResponseInterceptor = (r: Response) => void;
|
||||
|
||||
export interface TResponse<T> {
|
||||
status: number;
|
||||
error: boolean;
|
||||
|
@ -16,22 +19,24 @@ export class Requests {
|
|||
private baseUrl: string;
|
||||
private token: () => string;
|
||||
private headers: Record<string, string> = {};
|
||||
private logger?: (response: Response) => void;
|
||||
private responseInterceptors: ResponseInterceptor[] = [];
|
||||
|
||||
addResponseInterceptor(interceptor: ResponseInterceptor) {
|
||||
this.responseInterceptors.push(interceptor);
|
||||
}
|
||||
|
||||
private callResponseInterceptors(response: Response) {
|
||||
this.responseInterceptors.forEach(i => i(response));
|
||||
}
|
||||
|
||||
private url(rest: string): string {
|
||||
return this.baseUrl + rest;
|
||||
}
|
||||
|
||||
constructor(
|
||||
baseUrl: string,
|
||||
token: string | (() => string) = '',
|
||||
headers: Record<string, string> = {},
|
||||
logger?: (response: Response) => void
|
||||
) {
|
||||
constructor(baseUrl: string, token: string | (() => string) = '', headers: Record<string, string> = {}) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.token = typeof token === 'string' ? () => token : token;
|
||||
this.headers = headers;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public get<T>(url: string): Promise<TResponse<T>> {
|
||||
|
@ -73,10 +78,7 @@ export class Requests {
|
|||
}
|
||||
|
||||
const response = await fetch(this.url(url), args);
|
||||
|
||||
if (this.logger) {
|
||||
this.logger(response);
|
||||
}
|
||||
this.callResponseInterceptors(response);
|
||||
|
||||
const data: T = await (async () => {
|
||||
if (response.status === 204) {
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<BaseContainer class="space-y-16">
|
||||
<BaseContainer class="space-y-16 pb-16">
|
||||
<section aria-labelledby="profile-overview-title" class="mt-8">
|
||||
<div class="overflow-hidden rounded-lg bg-white shadow">
|
||||
<h2 class="sr-only" id="profile-overview-title">Profile Overview</h2>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
loading.value = true;
|
||||
// Print Values of registerFields
|
||||
|
||||
const { data, error } = await api.register({
|
||||
const { error } = await api.register({
|
||||
user: {
|
||||
name: registerFields[0].value,
|
||||
email: registerFields[1].value,
|
||||
|
@ -58,11 +58,14 @@
|
|||
|
||||
if (error) {
|
||||
toast.error('Problem registering user');
|
||||
} else {
|
||||
toast.success('User registered');
|
||||
return;
|
||||
}
|
||||
|
||||
toast.success('User registered');
|
||||
|
||||
loading.value = false;
|
||||
loginFields[0].value = registerFields[1].value;
|
||||
registerForm.value = false;
|
||||
}
|
||||
|
||||
const loginFields = [
|
||||
|
@ -116,55 +119,57 @@
|
|||
<p class="ml-1 text-lg text-base-content/50">Track, Organize, and Manage your Shit.</p>
|
||||
</header>
|
||||
<div class="grid p-6 sm:place-items-center min-h-[50vh]">
|
||||
<Transition name="slide-fade">
|
||||
<form v-if="registerForm" @submit.prevent="registerUser">
|
||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Register</h2>
|
||||
<TextField
|
||||
v-for="field in registerFields"
|
||||
v-model="field.value"
|
||||
:label="field.label"
|
||||
:key="field.label"
|
||||
:type="field.type"
|
||||
/>
|
||||
<div class="card-actions justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary mt-2"
|
||||
:class="loading ? 'loading' : ''"
|
||||
:disabled="loading"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
<div>
|
||||
<Transition name="slide-fade">
|
||||
<form v-if="registerForm" @submit.prevent="registerUser">
|
||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Register</h2>
|
||||
<TextField
|
||||
v-for="field in registerFields"
|
||||
v-model="field.value"
|
||||
:label="field.label"
|
||||
:key="field.label"
|
||||
:type="field.type"
|
||||
/>
|
||||
<div class="card-actions justify-end">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary mt-2"
|
||||
:class="loading ? 'loading' : ''"
|
||||
:disabled="loading"
|
||||
>
|
||||
Register
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form v-else @submit.prevent="login">
|
||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Login</h2>
|
||||
<TextField
|
||||
v-for="field in loginFields"
|
||||
v-model="field.value"
|
||||
:label="field.label"
|
||||
:key="field.label"
|
||||
:type="field.type"
|
||||
/>
|
||||
<div class="card-actions justify-end mt-2">
|
||||
<button type="submit" class="btn btn-primary" :class="loading ? 'loading' : ''" :disabled="loading">
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
<form v-else @submit.prevent="login">
|
||||
<div class="card w-max-[500px] md:w-[500px] bg-base-100 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">Login</h2>
|
||||
<TextField
|
||||
v-for="field in loginFields"
|
||||
v-model="field.value"
|
||||
:label="field.label"
|
||||
:key="field.label"
|
||||
:type="field.type"
|
||||
/>
|
||||
<div class="card-actions justify-end mt-2">
|
||||
<button type="submit" class="btn btn-primary" :class="loading ? 'loading' : ''" :disabled="loading">
|
||||
Login
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Transition>
|
||||
<div class="text-center mt-2">
|
||||
<button @click="toggleLogin">
|
||||
{{ registerForm ? 'Already a User? Login' : 'Not a User? Register' }}
|
||||
</button>
|
||||
</form>
|
||||
</Transition>
|
||||
<div class="text-center mt-4">
|
||||
<button @click="toggleLogin" class="text-primary-content text-lg">
|
||||
{{ registerForm ? 'Already a User? Login' : 'Not a User? Register' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="min-w-full absolute bottom-0 z-[-1]">
|
||||
|
|
|
@ -33,5 +33,14 @@ export const useAuthStore = defineStore('auth', {
|
|||
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* clearSession is used when the user cannot be logged out via the API and
|
||||
* must clear it's local session, usually when a 401 is received.
|
||||
*/
|
||||
clearSession() {
|
||||
this.token = '';
|
||||
this.expires = '';
|
||||
navigateTo('/');
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue