Correcao Sidebar Classico e Rail, Correcao Layout, Ajuste de Breakpoint para Tailwind, Ajuste AppTopbar, Ajuste Menu PopOver, Recriado Paleta de Cores, Inserido algumas animações leves, Reajuste Cor items NOVOS da tabela, Drawer Ajuda Corrigido no Logout, Whatsapp, sms, email, recursos extras

This commit is contained in:
Leonardo
2026-03-24 21:26:58 -03:00
parent a89d1f5560
commit 53a4980396
453 changed files with 121427 additions and 174407 deletions
@@ -25,93 +25,83 @@
// save(payload) cria ou atualiza (id presente = update dos campos editáveis)
// remove(id) hard delete (apenas registros do próprio owner)
import { ref } from 'vue'
import { supabase } from '@/lib/supabase/client'
import { ref } from 'vue';
import { supabase } from '@/lib/supabase/client';
export function useFinancialExceptions () {
const exceptions = ref([])
const loading = ref(false)
const error = ref('')
export function useFinancialExceptions() {
const exceptions = ref([]);
const loading = ref(false);
const error = ref('');
// ── Carregar exceções do owner + regras globais da clínica ───────────
async function load (ownerId) {
if (!ownerId) return
loading.value = true
error.value = ''
try {
const { data, error: err } = await supabase
.from('financial_exceptions')
.select('*')
.or(`owner_id.eq.${ownerId},owner_id.is.null`)
.order('exception_type', { ascending: true })
.order('created_at', { ascending: true })
// ── Carregar exceções do owner + regras globais da clínica ───────────
async function load(ownerId) {
if (!ownerId) return;
loading.value = true;
error.value = '';
try {
const { data, error: err } = await supabase.from('financial_exceptions').select('*').or(`owner_id.eq.${ownerId},owner_id.is.null`).order('exception_type', { ascending: true }).order('created_at', { ascending: true });
if (err) throw err
exceptions.value = data || []
} catch (e) {
error.value = e?.message || 'Falha ao carregar exceções financeiras.'
exceptions.value = []
} finally {
loading.value = false
if (err) throw err;
exceptions.value = data || [];
} catch (e) {
error.value = e?.message || 'Falha ao carregar exceções financeiras.';
exceptions.value = [];
} finally {
loading.value = false;
}
}
}
// ── Criar ou atualizar uma exceção ───────────────────────────────────
// Para UPDATE, apenas os campos editáveis são enviados:
// charge_mode, charge_value, charge_pct, min_hours_notice
// Regras globais (owner_id IS NULL) não devem ser editadas — o chamador
// é responsável por não chamar save() nesses registros.
async function save (payload) {
error.value = ''
try {
if (payload.id) {
const { error: err } = await supabase
.from('financial_exceptions')
.update({
charge_mode: payload.charge_mode,
charge_value: payload.charge_value ?? null,
charge_pct: payload.charge_pct ?? null,
min_hours_notice: payload.min_hours_notice ?? null,
})
.eq('id', payload.id)
if (err) throw err
} else {
const { error: err } = await supabase
.from('financial_exceptions')
.insert({
owner_id: payload.owner_id,
tenant_id: payload.tenant_id ?? null,
exception_type: payload.exception_type,
charge_mode: payload.charge_mode,
charge_value: payload.charge_value ?? null,
charge_pct: payload.charge_pct ?? null,
min_hours_notice: payload.min_hours_notice ?? null,
})
if (err) throw err
}
} catch (e) {
error.value = e?.message || 'Falha ao salvar exceção financeira.'
throw e
// ── Criar ou atualizar uma exceção ───────────────────────────────────
// Para UPDATE, apenas os campos editáveis são enviados:
// charge_mode, charge_value, charge_pct, min_hours_notice
// Regras globais (owner_id IS NULL) não devem ser editadas — o chamador
// é responsável por não chamar save() nesses registros.
async function save(payload) {
error.value = '';
try {
if (payload.id) {
const { error: err } = await supabase
.from('financial_exceptions')
.update({
charge_mode: payload.charge_mode,
charge_value: payload.charge_value ?? null,
charge_pct: payload.charge_pct ?? null,
min_hours_notice: payload.min_hours_notice ?? null
})
.eq('id', payload.id);
if (err) throw err;
} else {
const { error: err } = await supabase.from('financial_exceptions').insert({
owner_id: payload.owner_id,
tenant_id: payload.tenant_id ?? null,
exception_type: payload.exception_type,
charge_mode: payload.charge_mode,
charge_value: payload.charge_value ?? null,
charge_pct: payload.charge_pct ?? null,
min_hours_notice: payload.min_hours_notice ?? null
});
if (err) throw err;
}
} catch (e) {
error.value = e?.message || 'Falha ao salvar exceção financeira.';
throw e;
}
}
}
// ── Hard delete — apenas registros do próprio owner ──────────────────
// Regras globais (owner_id IS NULL) são protegidas pelo RLS do banco;
// a UI também deve esconder o botão de remover nesses casos.
async function remove (id) {
error.value = ''
try {
const { error: err } = await supabase
.from('financial_exceptions')
.delete()
.eq('id', id)
if (err) throw err
exceptions.value = exceptions.value.filter(e => e.id !== id)
} catch (e) {
error.value = e?.message || 'Falha ao remover exceção financeira.'
throw e
// ── Hard delete — apenas registros do próprio owner ──────────────────
// Regras globais (owner_id IS NULL) são protegidas pelo RLS do banco;
// a UI também deve esconder o botão de remover nesses casos.
async function remove(id) {
error.value = '';
try {
const { error: err } = await supabase.from('financial_exceptions').delete().eq('id', id);
if (err) throw err;
exceptions.value = exceptions.value.filter((e) => e.id !== id);
} catch (e) {
error.value = e?.message || 'Falha ao remover exceção financeira.';
throw e;
}
}
}
return { exceptions, loading, error, load, save, remove }
return { exceptions, loading, error, load, save, remove };
}