add admin login page at /login

This commit is contained in:
Yisroel Baum 2026-05-17 10:40:03 +03:00
parent f0da523ae4
commit e8e7cf9ea9
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
7 changed files with 289 additions and 7 deletions

View file

@ -0,0 +1,77 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
interface User {
id: number
email: string
}
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL as string
export const useAuthStore = defineStore('auth', () => {
const user = ref<User | null>(null)
const loginError = ref<string | null>(null)
const isSubmitting = ref(false)
const isAuthenticated = computed(() => user.value !== null)
async function login(email: string, password: string): Promise<boolean> {
loginError.value = null
isSubmitting.value = true
try {
const response = await fetch(`${API_BASE_URL}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password }),
})
if (!response.ok) {
const data: { error?: string } = await response.json()
loginError.value = data.error ?? 'Login failed'
return false
}
const data: { user: User } = await response.json()
user.value = data.user
return true
} catch {
loginError.value = 'Network error - could not reach server'
return false
} finally {
isSubmitting.value = false
}
}
async function fetchUser(): Promise<void> {
try {
const response = await fetch(`${API_BASE_URL}/me`, {
credentials: 'include',
})
if (!response.ok) {
user.value = null
return
}
const data: { user: User } = await response.json()
user.value = data.user
} catch {
user.value = null
}
}
async function logout(): Promise<void> {
try {
await fetch(`${API_BASE_URL}/logout`, {
method: 'POST',
credentials: 'include',
})
} finally {
user.value = null
}
}
return { user, loginError, isSubmitting, isAuthenticated, login, fetchUser, logout }
})