diff --git a/app/[locale]/contacts/page.tsx b/app/[locale]/contacts/page.tsx index 245c0b32..11ba0385 100644 --- a/app/[locale]/contacts/page.tsx +++ b/app/[locale]/contacts/page.tsx @@ -3,7 +3,7 @@ import { useState, useEffect, useCallback, useRef, useMemo } from "react"; import { useRouter } from "@/i18n/navigation"; import { useTranslations } from "next-intl"; -import { ArrowLeft, Upload, Download, Users, BookUser } from "lucide-react"; +import { ArrowLeft, Users, BookUser } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ConfirmDialog } from "@/components/ui/confirm-dialog"; import { useConfirmDialog } from "@/hooks/use-confirm-dialog"; @@ -13,7 +13,6 @@ import { ContactForm } from "@/components/contacts/contact-form"; import { ContactGroupList } from "@/components/contacts/contact-group-list"; import { ContactGroupForm } from "@/components/contacts/contact-group-form"; import { ContactGroupDetail } from "@/components/contacts/contact-group-detail"; -import { ContactImportDialog } from "@/components/contacts/contact-import-dialog"; import { exportContacts } from "@/components/contacts/contact-export"; import { useContactStore, getContactDisplayName } from "@/stores/contact-store"; import { useAuthStore } from "@/stores/auth-store"; @@ -32,7 +31,6 @@ type View = | "group-detail" | "group-create" | "group-edit" - | "import" | "bulk-add-to-group"; export default function ContactsPage() { @@ -69,7 +67,6 @@ export default function ContactsPage() { clearSelection, bulkDeleteContacts, bulkAddToGroup, - importContacts, } = useContactStore(); const [view, setView] = useState("list"); @@ -177,8 +174,6 @@ export default function ContactsPage() { const handleCancel = () => { if (view === "group-create" || view === "group-edit") { setView(selectedGroup ? "group-detail" : "list"); - } else if (view === "import") { - setView("list"); } else if (view === "bulk-add-to-group") { setView("list"); } else { @@ -313,13 +308,6 @@ export default function ContactsPage() { } }; - const handleImport = useCallback(async (importedContacts: ContactCard[]) => { - return importContacts( - supportsSync && client ? client : null, - importedContacts - ); - }, [supportsSync, client, importContacts]); - if (!isAuthenticated) return null; const renderRightPanel = () => { @@ -376,15 +364,6 @@ export default function ContactsPage() { /> ); - case "import": - return ( - - ); - case "bulk-add-to-group": return (
@@ -467,45 +446,6 @@ export default function ContactsPage() { "border-r border-border flex flex-col flex-shrink-0", isMobile ? "w-full" : "w-80" )}> -
-
- -
- - -
-
-
-
- {onImport && ( - - )}
)} diff --git a/components/settings/contacts-settings.tsx b/components/settings/contacts-settings.tsx new file mode 100644 index 00000000..e3e247db --- /dev/null +++ b/components/settings/contacts-settings.tsx @@ -0,0 +1,84 @@ +"use client"; + +import { useState, useCallback } from "react"; +import { useTranslations } from "next-intl"; +import { Upload, Download } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { SettingsSection, SettingItem } from "./settings-section"; +import { ContactImportDialog } from "@/components/contacts/contact-import-dialog"; +import { exportContacts } from "@/components/contacts/contact-export"; +import { useContactStore } from "@/stores/contact-store"; +import { useAuthStore } from "@/stores/auth-store"; +import { toast } from "@/stores/toast-store"; + +export function ContactsSettings() { + const t = useTranslations("contacts"); + const tSettings = useTranslations("settings.contacts"); + const { client } = useAuthStore(); + const { + contacts, + supportsSync, + importContacts, + } = useContactStore(); + const [showImport, setShowImport] = useState(false); + + const individuals = contacts.filter(c => c.kind !== "group"); + + const handleImport = useCallback(async (importedContacts: import("@/lib/jmap/types").ContactCard[]) => { + return importContacts( + supportsSync && client ? client : null, + importedContacts + ); + }, [supportsSync, client, importContacts]); + + const handleExport = () => { + if (individuals.length > 0) { + exportContacts(individuals); + toast.success(t("export.success", { count: individuals.length })); + } + }; + + if (showImport) { + return ( +
+ setShowImport(false)} + /> +
+ ); + } + + return ( + + + + + + + + + + ); +} diff --git a/locales/en/common.json b/locales/en/common.json index c9f9e686..6a8ed3cf 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -500,7 +500,8 @@ "folders": "Folders", "keywords": "Keywords", "security": "Security", - "files": "Files" + "files": "Files", + "contacts": "Contacts" }, "tab_groups": { "general": "General", @@ -917,6 +918,14 @@ "button": "Import" } }, + "contacts": { + "title": "Contacts", + "description": "Import and export your contacts", + "import_label": "Import Contacts", + "import_description": "Import contacts from a vCard (.vcf) file", + "export_label": "Export Contacts", + "export_description": "Export all contacts as a vCard (.vcf) file" + }, "filters": { "title": "Email Filters", "description": "Create rules to automatically sort, label, and manage incoming emails",