Apply Supabase schema changes

Apply the SQL schema changes to Supabase, including the creation of the `grupos_whatsapp` table and the addition of the `grupo_id` column to the `transacoes` table.
This commit is contained in:
gpt-engineer-app[bot] 2025-05-20 00:04:49 +00:00
parent 908904f9b9
commit 5a16246b23
4 changed files with 165 additions and 24 deletions

View File

@ -30,7 +30,8 @@ const transactionSchema = z.object({
detalhes: z.string().min(1, { message: 'Detalhes são obrigatórios' }), detalhes: z.string().min(1, { message: 'Detalhes são obrigatórios' }),
categoria: z.string().min(1, { message: 'Categoria é obrigatória' }), categoria: z.string().min(1, { message: 'Categoria é obrigatória' }),
tipo: z.string().min(1, { message: 'Tipo é obrigatório' }), tipo: z.string().min(1, { message: 'Tipo é obrigatório' }),
quando: z.string().min(1, { message: 'Data é obrigatória' }) quando: z.string().min(1, { message: 'Data é obrigatória' }),
grupo_id: z.string().optional()
}); });
type TransactionFormValues = z.infer<typeof transactionSchema>; type TransactionFormValues = z.infer<typeof transactionSchema>;
@ -39,13 +40,34 @@ interface TransactionFormProps {
onSuccess: () => void; onSuccess: () => void;
onCancel: () => void; onCancel: () => void;
defaultTipo?: 'receita' | 'despesa'; defaultTipo?: 'receita' | 'despesa';
grupoId?: string;
} }
export function TransactionForm({ onSuccess, onCancel, defaultTipo = 'despesa' }: TransactionFormProps) { export function TransactionForm({ onSuccess, onCancel, defaultTipo = 'despesa', grupoId }: TransactionFormProps) {
const [isSubmitting, setIsSubmitting] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false);
const [grupos, setGrupos] = useState<{remote_jid: string, nome_grupo: string | null}[]>([]);
const { toast } = useToast(); const { toast } = useToast();
const navigate = useNavigate(); const navigate = useNavigate();
// Buscar grupos do usuário ao carregar o formulário
useState(() => {
const fetchGrupos = async () => {
const userId = localStorage.getItem('userId') || 'default';
const { data, error } = await supabase
.from('grupos_whatsapp')
.select('remote_jid, nome_grupo')
.eq('user_id', userId);
if (error) {
console.error('Erro ao buscar grupos:', error);
} else if (data) {
setGrupos(data);
}
};
fetchGrupos();
});
const form = useForm<TransactionFormValues>({ const form = useForm<TransactionFormValues>({
resolver: zodResolver(transactionSchema), resolver: zodResolver(transactionSchema),
defaultValues: { defaultValues: {
@ -54,7 +76,8 @@ export function TransactionForm({ onSuccess, onCancel, defaultTipo = 'despesa' }
detalhes: '', detalhes: '',
categoria: '', categoria: '',
tipo: defaultTipo, tipo: defaultTipo,
quando: new Date().toISOString().split('T')[0] quando: new Date().toISOString().split('T')[0],
grupo_id: grupoId || ''
} }
}); });
@ -85,20 +108,24 @@ export function TransactionForm({ onSuccess, onCancel, defaultTipo = 'despesa' }
console.log(`Salvando transação para usuário: ${userId} (${userEmail || userName})`); console.log(`Salvando transação para usuário: ${userId} (${userEmail || userName})`);
// Preparar dados da transação incluindo o grupo_id se fornecido
const transactionData = {
user: userId,
estabelecimento: data.estabelecimento,
valor: valorFinal,
detalhes: data.detalhes,
categoria: data.categoria,
tipo: data.tipo,
quando: data.quando,
grupo_id: data.grupo_id || null
};
console.log('Dados da transação a serem salvos:', transactionData);
// With RLS disabled, we can insert directly to the fixed table // With RLS disabled, we can insert directly to the fixed table
const { error } = await supabase const { error } = await supabase
.from('transacoes') // Using a fixed table name instead of dynamic one .from('transacoes')
.insert([ .insert([transactionData]);
{
user: userId, // Store user ID as reference only
estabelecimento: data.estabelecimento,
valor: valorFinal,
detalhes: data.detalhes,
categoria: data.categoria,
tipo: data.tipo,
quando: data.quando
}
]);
if (error) { if (error) {
console.error('Erro ao salvar transação:', error); console.error('Erro ao salvar transação:', error);
@ -230,6 +257,37 @@ export function TransactionForm({ onSuccess, onCancel, defaultTipo = 'despesa' }
)} )}
/> />
{grupos.length > 0 && (
<FormField
control={form.control}
name="grupo_id"
render={({ field }) => (
<FormItem>
<FormLabel>Grupo WhatsApp (opcional)</FormLabel>
<Select
onValueChange={field.onChange}
value={field.value || ""}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Selecione um grupo (opcional)" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="">Nenhum grupo</SelectItem>
{grupos.map((grupo) => (
<SelectItem key={grupo.remote_jid} value={grupo.remote_jid}>
{grupo.nome_grupo || grupo.remote_jid}
</SelectItem>
))}
</SelectContent>
</Select>
<FormMessage />
</FormItem>
)}
/>
)}
<div className="flex justify-end space-x-2 pt-2"> <div className="flex justify-end space-x-2 pt-2">
<Button variant="outline" type="button" onClick={onCancel} disabled={isSubmitting}> <Button variant="outline" type="button" onClick={onCancel} disabled={isSubmitting}>
Cancelar Cancelar

View File

@ -120,6 +120,30 @@ export type Database = {
} }
Relationships: [] Relationships: []
} }
grupos_whatsapp: {
Row: {
created_at: string | null
id: number
nome_grupo: string | null
remote_jid: string
user_id: string
}
Insert: {
created_at?: string | null
id?: number
nome_grupo?: string | null
remote_jid: string
user_id: string
}
Update: {
created_at?: string | null
id?: number
nome_grupo?: string | null
remote_jid?: string
user_id?: string
}
Relationships: []
}
metas: { metas: {
Row: { Row: {
ano: number ano: number
@ -189,6 +213,7 @@ export type Database = {
created_at: string created_at: string
detalhes: string | null detalhes: string | null
estabelecimento: string | null estabelecimento: string | null
grupo_id: string | null
id: number id: number
login: string | null login: string | null
quando: string | null quando: string | null
@ -201,6 +226,7 @@ export type Database = {
created_at?: string created_at?: string
detalhes?: string | null detalhes?: string | null
estabelecimento?: string | null estabelecimento?: string | null
grupo_id?: string | null
id?: number id?: number
login?: string | null login?: string | null
quando?: string | null quando?: string | null
@ -213,6 +239,7 @@ export type Database = {
created_at?: string created_at?: string
detalhes?: string | null detalhes?: string | null
estabelecimento?: string | null estabelecimento?: string | null
grupo_id?: string | null
id?: number id?: number
login?: string | null login?: string | null
quando?: string | null quando?: string | null

View File

@ -1,3 +1,4 @@
import { supabase } from "@/integrations/supabase/client"; import { supabase } from "@/integrations/supabase/client";
import { Transaction, CategorySummary } from "@/types/financialTypes"; import { Transaction, CategorySummary } from "@/types/financialTypes";
@ -9,11 +10,25 @@ export async function getTransacoes(): Promise<Transaction[]> {
console.log("Buscando transações para o usuário:", userId); console.log("Buscando transações para o usuário:", userId);
try { try {
// Buscar transações filtrando pelo usuário atual // Primeiro, buscar todos os grupos do usuário
const { data: userGroups, error: groupsError } = await supabase
.from('grupos_whatsapp')
.select('remote_jid')
.eq('user_id', userId);
if (groupsError) {
console.error('Erro ao buscar grupos do usuário:', groupsError);
}
// Extrair IDs dos grupos para usar no filtro
const groupIds = userGroups ? userGroups.map(group => group.remote_jid) : [];
console.log(`Encontrados ${groupIds.length} grupos vinculados ao usuário:`, groupIds);
// Buscar transações com filtro aprimorado
const { data, error } = await supabase const { data, error } = await supabase
.from('transacoes') .from('transacoes')
.select('*') .select('*')
.eq('user', userId) // Filtrar pelo ID do usuário .or(`user.eq.${userId},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`)
.order('quando', { ascending: false }); .order('quando', { ascending: false });
if (error) { if (error) {
@ -33,7 +48,8 @@ export async function getTransacoes(): Promise<Transaction[]> {
detalhes: item.detalhes || '', detalhes: item.detalhes || '',
estabelecimento: item.estabelecimento || '', estabelecimento: item.estabelecimento || '',
tipo: item.tipo?.toLowerCase() || 'despesa', tipo: item.tipo?.toLowerCase() || 'despesa',
categoria: item.categoria || 'Outros' categoria: item.categoria || 'Outros',
grupo_id: item.grupo_id || null
})); }));
} catch (error) { } catch (error) {
console.error('Erro ao buscar transações:', error); console.error('Erro ao buscar transações:', error);
@ -48,11 +64,24 @@ export async function getTransactionSummary() {
const userId = localStorage.getItem('userId') || 'default'; const userId = localStorage.getItem('userId') || 'default';
try { try {
// Buscar resumo filtrando pelo usuário atual // Primeiro, buscar todos os grupos do usuário
const { data: userGroups, error: groupsError } = await supabase
.from('grupos_whatsapp')
.select('remote_jid')
.eq('user_id', userId);
if (groupsError) {
console.error('Erro ao buscar grupos do usuário:', groupsError);
}
// Extrair IDs dos grupos para usar no filtro
const groupIds = userGroups ? userGroups.map(group => group.remote_jid) : [];
// Buscar resumo das transações com filtro aprimorado
const { data, error } = await supabase const { data, error } = await supabase
.from('transacoes') .from('transacoes')
.select('tipo, valor') .select('tipo, valor')
.eq('user', userId); // Filtrar pelo ID do usuário .or(`user.eq.${userId},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`);
if (error) { if (error) {
console.error('Erro ao buscar resumo das transações:', error); console.error('Erro ao buscar resumo das transações:', error);
@ -90,11 +119,24 @@ export async function getCategorySummary(tipoFiltro: string = 'despesa') {
const userId = localStorage.getItem('userId') || 'default'; const userId = localStorage.getItem('userId') || 'default';
try { try {
// Buscar resumo de categorias filtrando pelo usuário atual // Primeiro, buscar todos os grupos do usuário
const { data: userGroups, error: groupsError } = await supabase
.from('grupos_whatsapp')
.select('remote_jid')
.eq('user_id', userId);
if (groupsError) {
console.error('Erro ao buscar grupos do usuário:', groupsError);
}
// Extrair IDs dos grupos para usar no filtro
const groupIds = userGroups ? userGroups.map(group => group.remote_jid) : [];
// Buscar resumo de categorias com filtro aprimorado
const { data, error } = await supabase const { data, error } = await supabase
.from('transacoes') .from('transacoes')
.select('categoria, valor, tipo') .select('categoria, valor, tipo')
.eq('user', userId); // Filtrar pelo ID do usuário .or(`user.eq.${userId},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`);
if (error) { if (error) {
console.error('Erro ao buscar resumo de categorias:', error); console.error('Erro ao buscar resumo de categorias:', error);
@ -154,11 +196,24 @@ export async function getMonthlyData() {
const userId = localStorage.getItem('userId') || 'default'; const userId = localStorage.getItem('userId') || 'default';
try { try {
// Buscar dados mensais filtrando pelo usuário atual // Primeiro, buscar todos os grupos do usuário
const { data: userGroups, error: groupsError } = await supabase
.from('grupos_whatsapp')
.select('remote_jid')
.eq('user_id', userId);
if (groupsError) {
console.error('Erro ao buscar grupos do usuário:', groupsError);
}
// Extrair IDs dos grupos para usar no filtro
const groupIds = userGroups ? userGroups.map(group => group.remote_jid) : [];
// Buscar dados mensais com filtro aprimorado
const { data, error } = await supabase const { data, error } = await supabase
.from('transacoes') .from('transacoes')
.select('quando, valor, tipo') .select('quando, valor, tipo')
.eq('user', userId); // Filtrar pelo ID do usuário .or(`user.eq.${userId},${groupIds.length > 0 ? `grupo_id.in.(${groupIds.map(id => `"${id}"`).join(',')})` : ''}`);
if (error) { if (error) {
console.error('Erro ao buscar dados mensais:', error); console.error('Erro ao buscar dados mensais:', error);

View File

@ -9,6 +9,7 @@ export interface Transaction {
estabelecimento: string; estabelecimento: string;
tipo: string; tipo: string;
categoria: string; categoria: string;
grupo_id?: string | null;
} }
export interface TransactionSummary { export interface TransactionSummary {