Ajuste rotas, Menus, Layout, Permissãoes UserRoleGuard
This commit is contained in:
@@ -7,11 +7,39 @@ import { useConfirm } from 'primevue/useconfirm'
|
||||
|
||||
import { supabase } from '@/lib/supabase/client'
|
||||
|
||||
import { useTenantStore } from '@/stores/tenantStore'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const toast = useToast()
|
||||
const confirm = useConfirm()
|
||||
|
||||
const tenantStore = useTenantStore()
|
||||
|
||||
async function getCurrentTenantId () {
|
||||
// ajuste para o nome real no seu store
|
||||
return tenantStore.tenantId || tenantStore.currentTenantId || tenantStore.tenant?.id
|
||||
}
|
||||
|
||||
async function getCurrentMemberId (tenantId) {
|
||||
const { data: authData, error: authError } = await supabase.auth.getUser()
|
||||
if (authError) throw authError
|
||||
const uid = authData?.user?.id
|
||||
if (!uid) throw new Error('Sessão inválida.')
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('tenant_members')
|
||||
.select('id')
|
||||
.eq('tenant_id', tenantId)
|
||||
.eq('user_id', uid)
|
||||
.eq('status', 'active')
|
||||
.single()
|
||||
|
||||
if (error) throw error
|
||||
if (!data?.id) throw new Error('Responsible member not found')
|
||||
return data.id
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Accordion: abre 1 por vez + scroll
|
||||
// ------------------------------------------------------
|
||||
@@ -400,6 +428,8 @@ async function getOwnerId () {
|
||||
// ------------------------------------------------------
|
||||
const PACIENTES_COLUNAS_PERMITIDAS = new Set([
|
||||
'owner_id',
|
||||
'tenant_id',
|
||||
'responsible_member_id',
|
||||
|
||||
// Sessão 1
|
||||
'nome_completo',
|
||||
@@ -688,12 +718,14 @@ async function createPatient (payload) {
|
||||
}
|
||||
|
||||
async function updatePatient (id, payload) {
|
||||
const ownerId = await getOwnerId()
|
||||
const { error } = await supabase
|
||||
.from('patients')
|
||||
.update({ ...payload, updated_at: new Date().toISOString() })
|
||||
.update({
|
||||
...payload,
|
||||
updated_at: new Date().toISOString()
|
||||
})
|
||||
.eq('id', id)
|
||||
.eq('owner_id', ownerId)
|
||||
|
||||
if (error) throw error
|
||||
}
|
||||
|
||||
@@ -840,38 +872,55 @@ async function fetchAll () {
|
||||
watch(() => route.params?.id, fetchAll, { immediate: true })
|
||||
onMounted(fetchAll)
|
||||
|
||||
|
||||
async function resolveTenantContextOrFail () {
|
||||
const { data: authData, error: authError } = await supabase.auth.getUser()
|
||||
if (authError) throw authError
|
||||
const uid = authData?.user?.id
|
||||
if (!uid) throw new Error('Sessão inválida.')
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('tenant_members')
|
||||
.select('id, tenant_id')
|
||||
.eq('user_id', uid)
|
||||
.eq('status', 'active')
|
||||
.order('created_at', { ascending: false }) // se existir
|
||||
.limit(1)
|
||||
.single()
|
||||
|
||||
if (error) throw error
|
||||
if (!data?.tenant_id || !data?.id) throw new Error('Responsible member not found')
|
||||
|
||||
return { tenantId: data.tenant_id, memberId: data.id }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Submit
|
||||
// ------------------------------------------------------
|
||||
async function onSubmit () {
|
||||
if (saving.value) return
|
||||
|
||||
// validações...
|
||||
saving.value = true
|
||||
try {
|
||||
saving.value = true
|
||||
|
||||
const ownerId = await getOwnerId()
|
||||
const { tenantId, memberId } = await resolveTenantContextOrFail()
|
||||
|
||||
const payload = sanitizePayload(form.value, ownerId)
|
||||
|
||||
let id = patientId.value
|
||||
// multi-tenant obrigatório
|
||||
payload.tenant_id = tenantId
|
||||
payload.responsible_member_id = memberId
|
||||
|
||||
if (isEdit.value) {
|
||||
await updatePatient(id, payload)
|
||||
await updatePatient(patientId.value, payload)
|
||||
toast.add({ severity: 'success', summary: 'Salvo', detail: 'Paciente atualizado.', life: 2500 })
|
||||
} else {
|
||||
const created = await createPatient(payload)
|
||||
id = created?.id
|
||||
if (!id) throw new Error('Falha ao obter ID do paciente criado.')
|
||||
router.replace(`${getAreaBase()}/patients/cadastro/${id}`)
|
||||
toast.add({ severity: 'success', summary: 'Salvo', detail: 'Paciente cadastrado.', life: 2500 })
|
||||
// opcional: router.push(`${getAreaBase()}/patients/${created.id}`)
|
||||
}
|
||||
|
||||
await replacePatientGroups(id, grupoIdSelecionado.value || null)
|
||||
await replacePatientTags(id, tagIdsSelecionadas.value || [])
|
||||
|
||||
// Avatar por último, mas dentro do mesmo fluxo (sem toast de sucesso)
|
||||
await maybeUploadAvatar(ownerId, id)
|
||||
|
||||
// ✅ um sucesso só
|
||||
toast.add({ severity: 'success', summary: 'Salvo', detail: 'Paciente salvo.', life: 2500 })
|
||||
} catch (err) {
|
||||
toast.add({ severity: 'error', summary: 'Erro', detail: err?.message || 'Falha ao salvar paciente', life: 4000 })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || 'Falha ao salvar paciente.', life: 4000 })
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user