diff --git a/features/boards/components/Modals/DealDetailModal.tsx b/features/boards/components/Modals/DealDetailModal.tsx index 375fe595e..a4946c7e3 100644 --- a/features/boards/components/Modals/DealDetailModal.tsx +++ b/features/boards/components/Modals/DealDetailModal.tsx @@ -1019,8 +1019,8 @@ export const DealDetailModal: React.FC = ({ dealId, isOpen )} -
- +
+
diff --git a/features/contacts/components/CompanyFormModal.tsx b/features/contacts/components/CompanyFormModal.tsx index b9b9f4e64..8ae0bbad6 100644 --- a/features/contacts/components/CompanyFormModal.tsx +++ b/features/contacts/components/CompanyFormModal.tsx @@ -17,34 +17,24 @@ interface CompanyFormModalProps { editingCompany: Company | null; } -/** - * Componente React `CompanyFormModal`. - * - * @param {CompanyFormModalProps} { - isOpen, - onClose, - onSubmit, - editingCompany, -} - Parâmetro `{ - isOpen, - onClose, - onSubmit, - editingCompany, -}`. - * @returns {Element} Retorna um valor do tipo `Element`. - */ export const CompanyFormModal: React.FC = ({ isOpen, onClose, onSubmit, editingCompany, }) => { + const customFields = (editingCompany as any)?.custom_fields ?? {}; + const form = useForm({ resolver: zodResolver(companyFormSchema), defaultValues: { name: editingCompany?.name || '', industry: editingCompany?.industry || '', website: editingCompany?.website || '', + num_funcionarios: customFields.num_funcionarios ?? undefined, + cnae: customFields.cnae || '', + nrs_aplicaveis: customFields.nrs_aplicaveis || '', + data_ultimo_aso: customFields.data_ultimo_aso || '', }, }); @@ -57,10 +47,15 @@ export const CompanyFormModal: React.FC = ({ React.useEffect(() => { if (isOpen) { + const cf = (editingCompany as any)?.custom_fields ?? {}; reset({ name: editingCompany?.name || '', industry: editingCompany?.industry || '', website: editingCompany?.website || '', + num_funcionarios: cf.num_funcionarios ?? undefined, + cnae: cf.cnae || '', + nrs_aplicaveis: cf.nrs_aplicaveis || '', + data_ultimo_aso: cf.data_ultimo_aso || '', }); } }, [isOpen, editingCompany, reset]); @@ -81,7 +76,7 @@ export const CompanyFormModal: React.FC = ({ = ({ @@ -102,6 +97,36 @@ export const CompanyFormModal: React.FC = ({ registration={register('website')} /> + + + + + + + + {editingCompany ? 'Salvar Alterações' : 'Criar Empresa'} @@ -109,4 +134,3 @@ export const CompanyFormModal: React.FC = ({ ); }; - diff --git a/features/contacts/hooks/useContactsController.ts b/features/contacts/hooks/useContactsController.ts index 14432f741..e645f9793 100644 --- a/features/contacts/hooks/useContactsController.ts +++ b/features/contacts/hooks/useContactsController.ts @@ -199,10 +199,10 @@ export const useContactsController = () => { setIsCompanyModalOpen(true); }; - const handleCompanySubmit = (data: { name: string; industry?: string; website?: string }) => { + const handleCompanySubmit = (data: { name: string; industry?: string; website?: string; num_funcionarios?: number; cnae?: string; nrs_aplicaveis?: string; data_ultimo_aso?: string }) => { if (editingCompany) { updateCompanyMutation.mutate( - { id: editingCompany.id, updates: { ...data } }, + { id: editingCompany.id, updates: { name: data.name, industry: data.industry, website: data.website, custom_fields: { num_funcionarios: data.num_funcionarios, cnae: data.cnae, nrs_aplicaveis: data.nrs_aplicaveis, data_ultimo_aso: data.data_ultimo_aso } } }, { onSuccess: () => { (addToast || showToast)('Empresa atualizada!', 'success'); diff --git a/lib/query/hooks/useActivitiesQuery.ts b/lib/query/hooks/useActivitiesQuery.ts index b9d7f1403..b15b490bd 100644 --- a/lib/query/hooks/useActivitiesQuery.ts +++ b/lib/query/hooks/useActivitiesQuery.ts @@ -136,6 +136,7 @@ interface CreateActivityParams { */ export const useCreateActivity = () => { const queryClient = useQueryClient(); + const { user } = useAuth(); return useMutation({ mutationFn: async ({ activity }: CreateActivityParams) => { @@ -186,6 +187,16 @@ export const useCreateActivity = () => { // Invalidate to ensure Realtime updates are picked up // This is a no-op if data is already fresh, but ensures consistency queryClient.invalidateQueries({ queryKey: queryKeys.activities.all }); + if (data.type === "MEETING") { + const startDate = data.date ? new Date(data.date) : null; + if (startDate && !isNaN(startDate.getTime())) { + fetch("https://n8n-production-9012a.up.railway.app/webhook/0ebbdfef-a03e-4109-bdce-7d00e70218f0", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ title: data.title, description: data.description || data.dealTitle, start_time: startDate.toISOString(), end_time: new Date(startDate.getTime() + 3600000).toISOString(), attendees: user?.email || "" }) + }).catch((err) => console.error("[Calendar] Webhook error:", err)); + } + } }, onError: (_error, _params, context) => { if (context?.previousActivities) { diff --git a/lib/query/hooks/useDealsQuery.ts b/lib/query/hooks/useDealsQuery.ts index b3e6f47fc..f9681d1a9 100644 --- a/lib/query/hooks/useDealsQuery.ts +++ b/lib/query/hooks/useDealsQuery.ts @@ -517,6 +517,14 @@ export const useAddDealItem = () => { if (error) throw error; return { dealId, item: data! }; }, + onSuccess: (data, { dealId }) => { + queryClient.setQueryData(DEALS_VIEW_KEY, (old) => { + if (!old) return old; + return old.map((d) => + d.id === dealId ? { ...d, items: [...(d.items ?? []), data.item] } : d + ); + }); + }, onSettled: (_data, _error, { dealId }) => { queryClient.invalidateQueries({ queryKey: queryKeys.deals.detail(dealId) }); queryClient.invalidateQueries({ queryKey: queryKeys.deals.lists() }); @@ -536,6 +544,14 @@ export const useRemoveDealItem = () => { if (error) throw error; return { dealId, itemId }; }, + onSuccess: (data) => { + queryClient.setQueryData(DEALS_VIEW_KEY, (old) => { + if (!old) return old; + return old.map((d) => + d.id === data.dealId ? { ...d, items: (d.items ?? []).filter((i) => i.id !== data.itemId) } : d + ); + }); + }, onSettled: (_data, _error, { dealId }) => { queryClient.invalidateQueries({ queryKey: queryKeys.deals.detail(dealId) }); queryClient.invalidateQueries({ queryKey: queryKeys.deals.lists() }); diff --git a/lib/supabase/contacts.ts b/lib/supabase/contacts.ts index 9955a394b..bc0c7f8a5 100644 --- a/lib/supabase/contacts.ts +++ b/lib/supabase/contacts.ts @@ -693,6 +693,7 @@ export const companiesService = { if (updates.name !== undefined) dbUpdates.name = updates.name; if (updates.industry !== undefined) dbUpdates.industry = updates.industry || null; if (updates.website !== undefined) dbUpdates.website = updates.website || null; + if (updates.custom_fields !== undefined) dbUpdates.custom_fields = updates.custom_fields; dbUpdates.updated_at = new Date().toISOString(); const { error } = await supabase diff --git a/lib/validations/schemas.ts b/lib/validations/schemas.ts index 41bd5ad9b..0bd25ff04 100644 --- a/lib/validations/schemas.ts +++ b/lib/validations/schemas.ts @@ -120,6 +120,10 @@ export type ContactFormData = z.infer; // ============ COMPANY SCHEMAS ============ export const companyFormSchema = z.object({ + num_funcionarios: z.coerce.number().int().min(0).optional(), + cnae: optionalString.pipe(z.string().max(MAX_LENGTHS.SHORT_TEXT)), + nrs_aplicaveis: optionalString.pipe(z.string().max(500)), + data_ultimo_aso: optionalString.pipe(z.string().max(MAX_LENGTHS.SHORT_TEXT)), name: requiredString('Nome da Empresa', MAX_LENGTHS.COMPANY_NAME), industry: optionalString.pipe(z.string().max(MAX_LENGTHS.SHORT_TEXT)), website: z diff --git a/vercel.json b/vercel.json index 592a5ce35..a502399f4 100644 --- a/vercel.json +++ b/vercel.json @@ -10,6 +10,6 @@ "crons": [ { "path": "/api/cron/daily-briefing", "schedule": "0 8 * * 1-5" }, { "path": "/api/cron/template-sync", "schedule": "0 6 * * *" }, - { "path": "/api/cron/stage-evaluations", "schedule": "* * * * *" } + { "path": "/api/cron/stage-evaluations", "schedule": "0 0 * * *" } ] }
Item