feat: text content extraction

This commit is contained in:
Leon
2025-07-16 21:21:06 +02:00
parent 265e818780
commit 65902ed161
11 changed files with 568 additions and 446 deletions

View File

@@ -12,6 +12,7 @@ import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Plus } from "lucide-react"
import { createNewsletter } from "@/lib/api"
import { Checkbox } from "@/components/ui/checkbox"
interface AddNewsletterDialogProps {
isOpen: boolean
@@ -23,6 +24,7 @@ export function AddNewsletterDialog({ isOpen, onOpenChange, onSuccess }: AddNews
const [newNewsletter, setNewNewsletter] = useState({
name: "",
emails: [""],
extract_content: false,
})
const handleAddEmail = () => {
@@ -52,8 +54,9 @@ export function AddNewsletterDialog({ isOpen, onOpenChange, onSuccess }: AddNews
await createNewsletter({
name: newNewsletter.name,
sender_emails: newNewsletter.emails.filter((email) => email.trim()),
extract_content: newNewsletter.extract_content,
})
setNewNewsletter({ name: "", emails: [""] })
setNewNewsletter({ name: "", emails: [""], extract_content: false })
onOpenChange(false)
onSuccess()
} catch (error) {
@@ -102,6 +105,16 @@ export function AddNewsletterDialog({ isOpen, onOpenChange, onSuccess }: AddNews
Add Another Email
</Button>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="extract-content"
checked={newNewsletter.extract_content}
onCheckedChange={(checked) =>
setNewNewsletter((prev) => ({ ...prev, extract_content: !!checked }))
}
/>
<Label htmlFor="extract-content">Extract main content from emails</Label>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => onOpenChange(false)}>

View File

@@ -12,6 +12,7 @@ import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Plus } from "lucide-react"
import { Newsletter, updateNewsletter, deleteNewsletter } from "@/lib/api"
import { Checkbox } from "@/components/ui/checkbox"
interface EditNewsletterDialogProps {
newsletter: Newsletter | null
@@ -21,9 +22,10 @@ interface EditNewsletterDialogProps {
}
export function EditNewsletterDialog({ newsletter, isOpen, onOpenChange, onSuccess }: EditNewsletterDialogProps) {
const [editedDetails, setEditedDetails] = useState<{ name: string; emails: string[] }>({
const [editedDetails, setEditedDetails] = useState<{ name: string; emails: string[], extract_content: boolean }>({
name: "",
emails: [],
extract_content: false,
})
useEffect(() => {
@@ -31,6 +33,7 @@ export function EditNewsletterDialog({ newsletter, isOpen, onOpenChange, onSucce
setEditedDetails({
name: newsletter.name,
emails: newsletter.senders.map((s) => s.email),
extract_content: newsletter.extract_content,
})
}
}, [newsletter])
@@ -63,6 +66,7 @@ export function EditNewsletterDialog({ newsletter, isOpen, onOpenChange, onSucce
await updateNewsletter(newsletter.id, {
name: editedDetails.name,
sender_emails: editedDetails.emails.filter((email) => email.trim()),
extract_content: editedDetails.extract_content,
})
onOpenChange(false)
onSuccess()
@@ -121,6 +125,16 @@ export function EditNewsletterDialog({ newsletter, isOpen, onOpenChange, onSucce
Add Another Email
</Button>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="edit-extract-content"
checked={editedDetails.extract_content}
onCheckedChange={(checked) =>
setEditedDetails((prev) => ({ ...prev, extract_content: !!checked }))
}
/>
<Label htmlFor="edit-extract-content">Extract main content from emails</Label>
</div>
</div>
<DialogFooter className="sm:justify-between">
<Button variant="destructive" onClick={handleDelete}>

View File

@@ -25,6 +25,7 @@ describe("AddNewsletterDialog", () => {
id: 1,
name: "My New Newsletter",
is_active: true,
extract_content: false,
senders: [{ id: 1, email: "test@example.com", newsletter_id: 1 }],
entries_count: 0,
})
@@ -43,6 +44,7 @@ describe("AddNewsletterDialog", () => {
expect(mockedApi.createNewsletter).toHaveBeenCalledWith({
name: "My New Newsletter",
sender_emails: ["test@example.com"],
extract_content: false,
})
expect(handleSuccess).toHaveBeenCalledTimes(1)
expect(handleOpenChange).toHaveBeenCalledWith(false)