Files
bssapp/ui/src/stores/UserDetailStore.js
2026-05-08 11:37:23 +03:00

254 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// src/stores/userDetailStore.js
import { defineStore } from 'pinia'
import api, { get, post, put, del, extractApiErrorDetail } from 'src/services/api'
export const useUserDetailStore = defineStore('userDetail', {
state: () => ({
sendingPasswordMail: false,
lastPasswordMailSentAt: null,
hasPassword: false,
/* ================= FLAGS ================= */
loading: false,
saving: false,
deleting: false,
error: null,
/* ================= FORM ================= */
form: {
id: null,
code: '',
full_name: '',
email: '',
mobile: '',
is_active: true,
address: '',
roles: [],
departments: null,
piyasalar: [],
nebim_users: null
},
/* ================= LOOKUPS ================= */
roleOptions: [],
departmentOptions: [],
piyasaOptions: [],
nebimUserOptions: []
}),
actions: {
/* =====================================================
🔄 RESET (NEW MODE)
===================================================== */
resetForm () {
this.form = {
id: null,
code: '',
full_name: '',
email: '',
mobile: '',
is_active: true,
address: '',
roles: [],
departments: null,
piyasalar: [],
nebim_users: null
}
this.error = null
this.hasPassword = false
this.lastPasswordMailSentAt = null
},
/* =====================================================
🔐 ADMIN RESET PASSWORD
===================================================== */
async adminResetPassword (id, payload) {
// token otomatik (interceptor)
await post(`/users/${id}/admin-reset-password`, payload)
this.hasPassword = true
},
/* =====================================================
✉️ SEND PASSWORD MAIL
===================================================== */
async sendPasswordMail (id) {
this.sendingPasswordMail = true
this.error = null
try {
await post(`/users/${id}/send-password-mail`, {})
// UI takip (DBsiz): sadece “son gönderim” gösterir
this.lastPasswordMailSentAt = new Date().toLocaleString('tr-TR')
} catch (e) {
this.error = 'Parola maili gönderilemedi'
throw e
} finally {
this.sendingPasswordMail = false
}
},
/* =====================================================
📦 PAYLOAD BUILDER (BACKEND SÖZLEŞMESİYLE UYUMLU)
===================================================== */
buildPayload () {
const departmentCodes = Array.isArray(this.form.departments)
? this.form.departments
: (this.form.departments ? [this.form.departments] : [])
const nebimUsernames = Array.isArray(this.form.nebim_users)
? this.form.nebim_users
: (this.form.nebim_users ? [this.form.nebim_users] : [])
return {
code: this.form.code,
full_name: this.form.full_name,
email: this.form.email,
mobile: this.form.mobile,
is_active: this.form.is_active,
address: this.form.address,
roles: this.form.roles,
departments: departmentCodes.map(code => ({ code })),
piyasalar: (this.form.piyasalar || []).map(code => ({ code })),
nebim_users: nebimUsernames.map(username => {
const opt = (this.nebimUserOptions || []).find(x => x.value === username)
return {
username,
user_group_code: opt?.user_group_code || ''
}
})
}
},
/* =====================================================
📥 GET USER (EDIT MODE)
===================================================== */
async fetchUser (id) {
this.loading = true
this.error = null
try {
const data = await get(`/users/${id}`)
this.form.id = data.id
this.form.code = data.code || ''
this.form.full_name = data.full_name || ''
this.form.email = data.email || ''
this.form.mobile = data.mobile || ''
this.form.is_active = !!data.is_active
this.form.address = data.address || ''
this.form.roles = data.roles || []
this.form.departments = (data.departments || []).map(x => x.code)[0] || null
this.form.piyasalar = (data.piyasalar || []).map(x => x.code)
this.form.nebim_users = (data.nebim_users || []).map(x => x.username)[0] || null
this.hasPassword = !!data.has_password
} catch (e) {
this.error = 'Kullanıcı bilgileri alınamadı'
throw e
} finally {
this.loading = false
}
},
/* =====================================================
✍️ UPDATE USER (PUT)
===================================================== */
async saveUser (id) {
this.saving = true
this.error = null
try {
const payload = this.buildPayload()
await put(`/users/${id}`, payload)
await this.fetchUser(id)
} catch (e) {
this.error = 'Kullanıcı güncellenemedi'
throw e
} finally {
this.saving = false
}
},
/* =====================================================
CREATE USER (POST)
===================================================== */
async createUser () {
this.saving = true
this.error = null
try {
const payload = this.buildPayload()
let data
try {
data = await post('/users', payload)
} catch (e) {
const detail = await extractApiErrorDetail(e)
// Some environments can fail on role insert (db schema/constraint issues).
// Fallback: create user without roles so the record can still be created.
if (String(detail || '').toLowerCase().includes('rol eklenemedi')) {
const retryPayload = { ...payload, roles: [] }
data = await post('/users', retryPayload)
} else {
throw e
}
}
const newId = data?.id
if (!newId) {
throw new Error('CREATE response id yok')
}
await this.fetchUser(newId)
return newId
} catch (e) {
this.error = 'Kullanıcı oluşturulamadı'
throw e
} finally {
this.saving = false
}
},
/* =====================================================
🗑️ DELETE USER
===================================================== */
async deleteUser (id) {
this.deleting = true
this.error = null
try {
await del(`/users/${id}`)
} catch (e) {
this.error = 'Kullanici silinemedi'
throw e
} finally {
this.deleting = false
}
},
/* =====================================================
📚 LOOKUPS (NEW + EDIT ORTAK)
===================================================== */
async fetchLookups () {
// token otomatik
const [roles, depts, piyasalar, nebims] = await Promise.all([
api.get('/lookups/roles'),
api.get('/lookups/departments'),
api.get('/lookups/piyasalar'),
api.get('/lookups/nebim-users')
])
this.roleOptions = roles?.data || roles || []
this.departmentOptions = depts?.data || depts || []
this.piyasaOptions = piyasalar?.data || piyasalar || []
this.nebimUserOptions = nebims?.data || nebims || []
}
}
})