feat: add admin console and account settings

Implement the admin dashboard with review, user, and image management workflows. Add profile settings, password reset, pending upload defaults, community placeholder routing, Vercel SPA rewrites, refreshed header styling, and the OpenCloud color-system skill.
This commit is contained in:
2026-05-22 21:04:49 +08:00
parent 599c8107d1
commit 9150a17097
15 changed files with 1410 additions and 50 deletions
+69 -1
View File
@@ -24,6 +24,24 @@ export const useAuthStore = defineStore('auth', () => {
}
}
async function ensureUsernameAvailable(username: string, currentUserId?: string) {
let query = supabase
.from('profiles')
.select('id')
.eq('username', username)
.limit(1)
if (currentUserId) {
query = query.neq('id', currentUserId)
}
const { data, error } = await query
if (error) throw error
if (data?.length) {
throw new Error('这个昵称已经被使用,请换一个。')
}
}
async function login(email: string, password: string) {
const { data, error } = await supabase.auth.signInWithPassword({ email, password })
if (error) {
@@ -40,6 +58,8 @@ export const useAuthStore = defineStore('auth', () => {
}
async function register(email: string, password: string, username: string) {
await ensureUsernameAvailable(username)
const { error } = await supabase.auth.signUp({
email,
password,
@@ -66,6 +86,40 @@ export const useAuthStore = defineStore('auth', () => {
profile.value = null
}
async function updateUsername(username: string) {
if (!user.value) throw new Error('请先登录。')
await ensureUsernameAvailable(username, user.value.id)
const { data, error } = await supabase
.from('profiles')
.update({ username })
.eq('id', user.value.id)
.select('*')
.single()
if (error) {
if (error.code === '23505') {
throw new Error('这个昵称已经被使用,请换一个。')
}
throw error
}
profile.value = data as Profile
}
async function updatePassword(password: string) {
const { error } = await supabase.auth.updateUser({ password })
if (error) throw error
}
async function sendPasswordReset(email: string) {
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${window.location.origin}/auth/reset-password`,
})
if (error) throw error
}
async function initialize() {
const { data: { session } } = await supabase.auth.getSession()
user.value = session?.user ?? null
@@ -79,5 +133,19 @@ export const useAuthStore = defineStore('auth', () => {
})
}
return { user, profile, loading, isLoggedIn, isAdmin, login, register, logout, initialize }
return {
user,
profile,
loading,
isLoggedIn,
isAdmin,
fetchProfile,
login,
register,
logout,
updateUsername,
updatePassword,
sendPasswordReset,
initialize,
}
})