diff --git a/apps/api/src/services/EventService.ts b/apps/api/src/services/EventService.ts index 03a0ada..05e4364 100644 --- a/apps/api/src/services/EventService.ts +++ b/apps/api/src/services/EventService.ts @@ -5,7 +5,6 @@ import signale from 'signale'; import {prisma} from '../database/prisma.js'; import {redis} from '../database/redis.js'; -import {ValidationError} from '../exceptions/index.js'; import {Keys} from './keys.js'; import {WorkflowExecutionService} from './WorkflowExecutionService.js'; diff --git a/apps/api/src/services/__tests__/SegmentService.operators.test.ts b/apps/api/src/services/__tests__/SegmentService.operators.test.ts index 50f0bf3..f41d317 100644 --- a/apps/api/src/services/__tests__/SegmentService.operators.test.ts +++ b/apps/api/src/services/__tests__/SegmentService.operators.test.ts @@ -1342,7 +1342,6 @@ describe('SegmentService - Comprehensive Operator Tests', () => { it('should match contacts who have triggered the event', async () => { const prisma = getPrismaClient(); const match = await factories.createContact({projectId}); - const noMatch = await factories.createContact({projectId}); // Create event for match contact await prisma.event.create({ @@ -1365,7 +1364,6 @@ describe('SegmentService - Comprehensive Operator Tests', () => { it('should not match contacts who have not triggered the event', async () => { const prisma = getPrismaClient(); const contact1 = await factories.createContact({projectId}); - const contact2 = await factories.createContact({projectId}); // Create different event await prisma.event.create({ @@ -1682,10 +1680,6 @@ describe('SegmentService - Comprehensive Operator Tests', () => { projectId, data: {plan: 'basic'}, }); - const noMatch2 = await factories.createContact({ - projectId, - data: {plan: 'premium'}, - }); // match and noMatch1 have the event, but only match has premium plan await prisma.event.create({ diff --git a/apps/landing/src/components/PricingCalculator.tsx b/apps/landing/src/components/PricingCalculator.tsx deleted file mode 100644 index 8ad1aaf..0000000 --- a/apps/landing/src/components/PricingCalculator.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import {motion} from 'framer-motion'; -import React, {useState} from 'react'; - -interface PricingData { - name: string; - calculatePrice: (emails: number) => number; - color?: string; -} - -interface PricingCalculatorProps { - competitors: PricingData[]; - defaultVolume?: number; -} - -const volumeOptions = [ - {label: '10K emails/month', value: 10000}, - {label: '100K emails/month', value: 100000}, - {label: '500K emails/month', value: 500000}, - {label: '1M emails/month', value: 1000000}, -]; - -/** - * Interactive pricing calculator comparing Plunk with competitors - */ -export function PricingCalculator({competitors, defaultVolume = 100000}: PricingCalculatorProps) { - const [volume, setVolume] = useState(defaultVolume); - - const plunkPrice = volume * 0.001; - - return ( - - {/* Header */} -
-

Pricing Calculator

-

Compare costs across platforms at different email volumes

-
- - {/* Volume Selector */} -
- -
- {volumeOptions.map(option => ( - - ))} -
-
- - {/* Results */} -
- {/* Plunk */} -
-
-
- Plunk - - Cheapest - -
-
-
${plunkPrice.toFixed(2)}
-
per month
-
-
-
- - {/* Competitors */} - {competitors.map((competitor, index) => { - const price = competitor.calculatePrice(volume); - const savings = ((price - plunkPrice) / price) * 100; - - return ( -
-
-
- {competitor.name} -
-
-
${price.toFixed(2)}
-
per month
-
-
- {savings > 0 && ( -
- Save {savings.toFixed(0)}% with Plunk -
- )} -
- ); - })} -
-
- ); -} diff --git a/apps/landing/src/components/index.ts b/apps/landing/src/components/index.ts index 5198a4c..82de0e8 100644 --- a/apps/landing/src/components/index.ts +++ b/apps/landing/src/components/index.ts @@ -3,4 +3,3 @@ export * from './Footer'; export * from './ComparisonTable'; export * from './FAQSection'; export * from './CodeBlock'; -export * from './PricingCalculator'; diff --git a/apps/web/src/pages/contacts/index.tsx b/apps/web/src/pages/contacts/index.tsx index 5479063..a6d7c57 100644 --- a/apps/web/src/pages/contacts/index.tsx +++ b/apps/web/src/pages/contacts/index.tsx @@ -14,7 +14,7 @@ import { DialogTitle, Input, Label, - Switch + Switch, } from '@plunk/ui'; import type {Contact} from '@plunk/db'; import {DashboardLayout} from '../../components/DashboardLayout'; @@ -34,7 +34,7 @@ import { Search, Trash2, Upload, - XCircle + XCircle, } from 'lucide-react'; import {NextSeo} from 'next-seo'; import Link from 'next/link'; @@ -237,27 +237,15 @@ export default function ContactsPage() { {selectedContacts.size} contact{selectedContacts.size !== 1 ? 's' : ''} selected
- - - @@ -625,8 +613,7 @@ interface ImportResult { function ImportContactsDialog({open, onOpenChange, onSuccess}: ImportContactsDialogProps) { const [file, setFile] = useState(null); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [jobId, setJobId] = useState(null); + const [, setJobId] = useState(null); const [isUploading, setIsUploading] = useState(false); const [progress, setProgress] = useState(0); const [status, setStatus] = useState<'idle' | 'uploading' | 'processing' | 'completed' | 'failed'>('idle'); @@ -978,7 +965,7 @@ interface BulkActionResult { } function BulkActionsDialog({open, onOpenChange, operation, contactIds, onSuccess}: BulkActionsDialogProps) { - const [jobId, setJobId] = useState(null); + const [, setJobId] = useState(null); const [isProcessing, setIsProcessing] = useState(false); const [progress, setProgress] = useState(0); const [status, setStatus] = useState<'idle' | 'processing' | 'completed' | 'failed'>('idle'); @@ -1097,19 +1084,27 @@ function BulkActionsDialog({open, onOpenChange, operation, contactIds, onSuccess const getOperationLabel = () => { switch (operation) { - case 'subscribe': return 'Subscribe'; - case 'unsubscribe': return 'Unsubscribe'; - case 'delete': return 'Delete'; - default: return 'Process'; + case 'subscribe': + return 'Subscribe'; + case 'unsubscribe': + return 'Unsubscribe'; + case 'delete': + return 'Delete'; + default: + return 'Process'; } }; const getOperationColor = () => { switch (operation) { - case 'subscribe': return 'green'; - case 'unsubscribe': return 'yellow'; - case 'delete': return 'red'; - default: return 'blue'; + case 'subscribe': + return 'green'; + case 'unsubscribe': + return 'yellow'; + case 'delete': + return 'red'; + default: + return 'blue'; } }; @@ -1129,14 +1124,12 @@ function BulkActionsDialog({open, onOpenChange, operation, contactIds, onSuccess {contactIds.length !== 1 ? 's' : ''}?

{operation === 'delete' && ( -

- This action cannot be undone. -

+

This action cannot be undone.

)}
)} - {(status === 'processing') && ( + {status === 'processing' && (
Processing contacts... @@ -1196,9 +1189,7 @@ function BulkActionsDialog({open, onOpenChange, operation, contactIds, onSuccess Operation failed
-

- {errorMessage || 'Please try again.'} -

+

{errorMessage || 'Please try again.'}

)}