TIDE/frontend/blog_portal/src/stores/auth.ts
Yisroel Baum ae7db07ec3
add api client and auth store
apiFetch wrapper sends JSON with credentials, parses error
shapes off the backend's {error: '...'} responses, and exposes
typed helpers (apiGet, apiPost, apiDelete). Auth store now
drives the real /signup -> /confirm-email -> /login -> /me ->
/logout flow. Vite dev proxy points /api at the backend on
:8000.
2026-05-06 22:48:17 +03:00

104 lines
2.3 KiB
TypeScript

import { defineStore } from "pinia";
import { computed, ref } from "vue";
import { apiGet, apiPost } from "@/api/client";
export interface AuthUser {
id: number;
email: string;
displayName: string;
isAdmin: boolean;
}
interface MePayload {
user: AuthUser;
}
export const useAuthStore = defineStore("auth", () => {
const user = ref<AuthUser | null>(null);
const checked = ref(false);
const error = ref<string | null>(null);
const signupCompleted = ref(false);
const isAuthenticated = computed(() => user.value !== null);
const isAdmin = computed(() => user.value?.isAdmin === true);
async function fetchMe(): Promise<boolean> {
const result = await apiGet<MePayload>("/me");
checked.value = true;
if (result.ok && result.data) {
user.value = result.data.user;
return true;
}
user.value = null;
return false;
}
async function signup(email: string, displayName: string): Promise<boolean> {
error.value = null;
const result = await apiPost<null>("/signup", {
email,
displayName,
});
if (!result.ok) {
error.value = result.error;
return false;
}
signupCompleted.value = true;
return true;
}
async function confirmEmail(token: string, password: string): Promise<boolean> {
error.value = null;
const result = await apiPost<null>("/confirm-email", {
token,
password,
});
if (!result.ok) {
error.value = result.error;
return false;
}
return true;
}
async function login(email: string, password: string): Promise<boolean> {
error.value = null;
const result = await apiPost<MePayload>("/login", {
email,
password,
});
if (!result.ok) {
error.value = result.error;
return false;
}
if (result.data) {
user.value = result.data.user;
checked.value = true;
}
return true;
}
async function logout(): Promise<void> {
await apiPost<null>("/logout", {});
user.value = null;
signupCompleted.value = false;
}
function clearError(): void {
error.value = null;
}
return {
user,
checked,
error,
signupCompleted,
isAuthenticated,
isAdmin,
fetchMe,
signup,
confirmEmail,
login,
logout,
clearError,
};
});