import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { InputWithLabel, WithLabel } from '@/components/forms/input-with-label'; import { ProjectMapper } from '@/components/project-mapper'; import { Button } from '@/components/ui/button'; import { useAppParams } from '@/hooks/use-app-params'; import { useTRPC } from '@/integrations/trpc/react'; import { cn } from '@/lib/utils'; import { zodResolver } from '@hookform/resolvers/zod'; import type { IImportConfig, IMixpanelImportConfig, IUmamiImportConfig, } from '@openpanel/validation'; import { zMixpanelImportConfig, zUmamiImportConfig, } from '@openpanel/validation'; import { format } from 'date-fns'; import { CalendarIcon } from 'lucide-react'; import { useFieldArray, useForm } from 'react-hook-form'; import type { z } from 'zod'; import { popModal, pushModal } from '.'; import { ModalContent, ModalHeader } from './Modal/Container'; type Provider = 'umami' | 'plausible' | 'mixpanel'; interface AddImportProps { provider: Provider; name: string; types: ('file' | 'api')[]; } type UmamiFormData = z.infer; type MixpanelFormData = z.infer; interface UmamiImportProps { onSubmit: (config: IUmamiImportConfig) => void; isPending: boolean; organizationId: string; } function UmamiImport({ onSubmit, isPending, organizationId, }: UmamiImportProps) { const trpc = useTRPC(); const { data: projects = [] } = useQuery( trpc.project.list.queryOptions({ organizationId, }), ); const form = useForm({ resolver: zodResolver(zUmamiImportConfig), defaultValues: { provider: 'umami', type: 'file', fileUrl: '', projectMapper: [], }, }); const { fields, append, remove } = useFieldArray({ control: form.control, name: 'projectMapper', }); const handleSubmit = form.handleSubmit((data) => { onSubmit(data); }); return (
); } interface MixpanelImportProps { onSubmit: (config: IMixpanelImportConfig) => void; isPending: boolean; organizationId: string; } function MixpanelImport({ onSubmit, isPending, organizationId, }: MixpanelImportProps) { const trpc = useTRPC(); const form = useForm({ resolver: zodResolver(zMixpanelImportConfig), defaultValues: { provider: 'mixpanel', type: 'api', serviceAccount: '', serviceSecret: '', projectId: '', from: '', to: '', }, }); const handleDateRangeSelect = () => { pushModal('DateRangerPicker', { startDate: form.getValues('from') ? new Date(form.getValues('from')) : undefined, endDate: form.getValues('to') ? new Date(form.getValues('to')) : undefined, onChange: ({ startDate, endDate }) => { form.setValue('from', format(startDate, 'yyyy-MM-dd')); form.setValue('to', format(endDate, 'yyyy-MM-dd')); form.trigger('from'); form.trigger('to'); }, }); }; const handleSubmit = form.handleSubmit((data) => { onSubmit(data); }); return (
); } export default function AddImport({ provider, name }: AddImportProps) { const { projectId, organizationId } = useAppParams(); const trpc = useTRPC(); const queryClient = useQueryClient(); const createImport = useMutation( trpc.import.create.mutationOptions({ onSuccess() { toast.success('Import started', { description: 'Your data import has been queued for processing.', }); popModal(); queryClient.invalidateQueries(trpc.import.list.pathFilter()); }, onError: (error) => { toast.error('Import failed', { description: error.message, }); }, }), ); const handleImportSubmit = (config: IImportConfig) => { createImport.mutate({ projectId, provider: config.provider, config, }); }; return ( {provider === 'umami' && ( )} {provider === 'mixpanel' && ( )} ); }