aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/components')
-rw-r--r--apps/web/components/admin/AddUserDialog.tsx2
-rw-r--r--apps/web/components/admin/BackgroundJobs.tsx2
-rw-r--r--apps/web/components/admin/CreateInviteDialog.tsx2
-rw-r--r--apps/web/components/admin/InvitesList.tsx2
-rw-r--r--apps/web/components/admin/ResetPasswordDialog.tsx2
-rw-r--r--apps/web/components/admin/UpdateUserDialog.tsx2
-rw-r--r--apps/web/components/admin/UserList.tsx2
-rw-r--r--apps/web/components/dashboard/BulkBookmarksAction.tsx3
-rw-r--r--apps/web/components/dashboard/UploadDropzone.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx3
-rw-r--r--apps/web/components/dashboard/bookmarks/BookmarkTagsEditor.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/BulkManageListsModal.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/BulkTagModal.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/EditorCard.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/ManageListsModal.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/SummarizeBookmarkArea.tsx2
-rw-r--r--apps/web/components/dashboard/bookmarks/action-buttons/ArchiveBookmarkButton.tsx2
-rw-r--r--apps/web/components/dashboard/cleanups/TagDuplicationDetention.tsx2
-rw-r--r--apps/web/components/dashboard/highlights/HighlightCard.tsx2
-rw-r--r--apps/web/components/dashboard/lists/DeleteListConfirmationDialog.tsx2
-rw-r--r--apps/web/components/dashboard/lists/EditListModal.tsx2
-rw-r--r--apps/web/components/dashboard/lists/LeaveListConfirmationDialog.tsx2
-rw-r--r--apps/web/components/dashboard/lists/ManageCollaboratorsModal.tsx2
-rw-r--r--apps/web/components/dashboard/lists/MergeListModal.tsx2
-rw-r--r--apps/web/components/dashboard/lists/PendingInvitationsCard.tsx2
-rw-r--r--apps/web/components/dashboard/preview/ActionBar.tsx2
-rw-r--r--apps/web/components/dashboard/preview/AttachmentBox.tsx2
-rw-r--r--apps/web/components/dashboard/preview/NoteEditor.tsx2
-rw-r--r--apps/web/components/dashboard/preview/ReaderView.tsx2
-rw-r--r--apps/web/components/dashboard/rules/RuleEngineRuleEditor.tsx2
-rw-r--r--apps/web/components/dashboard/rules/RuleEngineRuleList.tsx2
-rw-r--r--apps/web/components/dashboard/tags/AllTagsView.tsx2
-rw-r--r--apps/web/components/dashboard/tags/BulkTagAction.tsx3
-rw-r--r--apps/web/components/dashboard/tags/CreateTagModal.tsx2
-rw-r--r--apps/web/components/dashboard/tags/DeleteTagConfirmationDialog.tsx2
-rw-r--r--apps/web/components/dashboard/tags/EditableTagName.tsx2
-rw-r--r--apps/web/components/dashboard/tags/MergeTagModal.tsx2
-rw-r--r--apps/web/components/dashboard/tags/TagPill.tsx2
-rw-r--r--apps/web/components/settings/AISettings.tsx2
-rw-r--r--apps/web/components/settings/AddApiKey.tsx2
-rw-r--r--apps/web/components/settings/BackupSettings.tsx2
-rw-r--r--apps/web/components/settings/ChangePassword.tsx2
-rw-r--r--apps/web/components/settings/DeleteAccount.tsx2
-rw-r--r--apps/web/components/settings/DeleteApiKey.tsx2
-rw-r--r--apps/web/components/settings/FeedSettings.tsx2
-rw-r--r--apps/web/components/settings/ImportExport.tsx2
-rw-r--r--apps/web/components/settings/ReaderSettings.tsx2
-rw-r--r--apps/web/components/settings/RegenerateApiKey.tsx2
-rw-r--r--apps/web/components/settings/SubscriptionSettings.tsx2
-rw-r--r--apps/web/components/settings/UserAvatar.tsx2
-rw-r--r--apps/web/components/settings/UserOptions.tsx2
-rw-r--r--apps/web/components/settings/WebhookSettings.tsx2
-rw-r--r--apps/web/components/ui/copy-button.tsx2
-rw-r--r--apps/web/components/ui/sonner.tsx71
-rw-r--r--apps/web/components/ui/toaster.tsx35
-rw-r--r--apps/web/components/ui/use-toast.ts188
59 files changed, 127 insertions, 282 deletions
diff --git a/apps/web/components/admin/AddUserDialog.tsx b/apps/web/components/admin/AddUserDialog.tsx
index 67c38501..3c578eca 100644
--- a/apps/web/components/admin/AddUserDialog.tsx
+++ b/apps/web/components/admin/AddUserDialog.tsx
@@ -26,7 +26,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
import { TRPCClientError } from "@trpc/client";
diff --git a/apps/web/components/admin/BackgroundJobs.tsx b/apps/web/components/admin/BackgroundJobs.tsx
index ba73db2e..26015eb4 100644
--- a/apps/web/components/admin/BackgroundJobs.tsx
+++ b/apps/web/components/admin/BackgroundJobs.tsx
@@ -11,7 +11,7 @@ import {
CardTitle,
} from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { keepPreviousData } from "@tanstack/react-query";
diff --git a/apps/web/components/admin/CreateInviteDialog.tsx b/apps/web/components/admin/CreateInviteDialog.tsx
index 84f5c60f..6738adc9 100644
--- a/apps/web/components/admin/CreateInviteDialog.tsx
+++ b/apps/web/components/admin/CreateInviteDialog.tsx
@@ -19,7 +19,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
import { TRPCClientError } from "@trpc/client";
diff --git a/apps/web/components/admin/InvitesList.tsx b/apps/web/components/admin/InvitesList.tsx
index 1418c9bb..fdc39798 100644
--- a/apps/web/components/admin/InvitesList.tsx
+++ b/apps/web/components/admin/InvitesList.tsx
@@ -2,6 +2,7 @@
import { ActionButton } from "@/components/ui/action-button";
import { ButtonWithTooltip } from "@/components/ui/button";
+import { toast } from "@/components/ui/sonner";
import LoadingSpinner from "@/components/ui/spinner";
import {
Table,
@@ -11,7 +12,6 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
-import { toast } from "@/components/ui/use-toast";
import { api } from "@/lib/trpc";
import { formatDistanceToNow } from "date-fns";
import { Mail, MailX, UserPlus } from "lucide-react";
diff --git a/apps/web/components/admin/ResetPasswordDialog.tsx b/apps/web/components/admin/ResetPasswordDialog.tsx
index cc2a95f5..4e71d42b 100644
--- a/apps/web/components/admin/ResetPasswordDialog.tsx
+++ b/apps/web/components/admin/ResetPasswordDialog.tsx
@@ -19,7 +19,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc"; // Adjust the import path as needed
import { zodResolver } from "@hookform/resolvers/zod";
import { TRPCClientError } from "@trpc/client";
diff --git a/apps/web/components/admin/UpdateUserDialog.tsx b/apps/web/components/admin/UpdateUserDialog.tsx
index 7093ccda..453f4fab 100644
--- a/apps/web/components/admin/UpdateUserDialog.tsx
+++ b/apps/web/components/admin/UpdateUserDialog.tsx
@@ -26,7 +26,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
import { TRPCClientError } from "@trpc/client";
diff --git a/apps/web/components/admin/UserList.tsx b/apps/web/components/admin/UserList.tsx
index f386a8cd..3a382a3b 100644
--- a/apps/web/components/admin/UserList.tsx
+++ b/apps/web/components/admin/UserList.tsx
@@ -2,6 +2,7 @@
import { ActionButton } from "@/components/ui/action-button";
import { ButtonWithTooltip } from "@/components/ui/button";
+import { toast } from "@/components/ui/sonner";
import LoadingSpinner from "@/components/ui/spinner";
import {
Table,
@@ -11,7 +12,6 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { Check, KeyRound, Pencil, Trash, UserPlus, X } from "lucide-react";
diff --git a/apps/web/components/dashboard/BulkBookmarksAction.tsx b/apps/web/components/dashboard/BulkBookmarksAction.tsx
index 817521ff..9e248c03 100644
--- a/apps/web/components/dashboard/BulkBookmarksAction.tsx
+++ b/apps/web/components/dashboard/BulkBookmarksAction.tsx
@@ -7,7 +7,7 @@ import {
ActionButtonWithTooltip,
} from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
-import { useToast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import useBulkActionsStore from "@/lib/bulkActions";
import { useTranslation } from "@/lib/i18n/client";
import {
@@ -49,7 +49,6 @@ export default function BulkBookmarksAction() {
const isEverythingSelected = useBulkActionsStore(
(state) => state.isEverythingSelected,
);
- const { toast } = useToast();
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [manageListsModal, setManageListsModalOpen] = useState(false);
const [bulkTagModal, setBulkTagModalOpen] = useState(false);
diff --git a/apps/web/components/dashboard/UploadDropzone.tsx b/apps/web/components/dashboard/UploadDropzone.tsx
index 8d119467..d3945cc3 100644
--- a/apps/web/components/dashboard/UploadDropzone.tsx
+++ b/apps/web/components/dashboard/UploadDropzone.tsx
@@ -1,6 +1,7 @@
"use client";
import React, { useCallback, useState } from "react";
+import { toast } from "@/components/ui/sonner";
import useUpload from "@/lib/hooks/upload-file";
import { cn } from "@/lib/utils";
import { TRPCClientError } from "@trpc/client";
@@ -10,7 +11,6 @@ import { useCreateBookmarkWithPostHook } from "@karakeep/shared-react/hooks/book
import { BookmarkTypes } from "@karakeep/shared/types/bookmarks";
import LoadingSpinner from "../ui/spinner";
-import { toast } from "../ui/use-toast";
import BookmarkAlreadyExistsToast from "../utils/BookmarkAlreadyExistsToast";
export function useUploadAsset() {
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx b/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
index e7fea2c3..a1eab830 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkMarkdownComponent.tsx
@@ -1,6 +1,6 @@
import MarkdownEditor from "@/components/ui/markdown/markdown-editor";
import { MarkdownReadonly } from "@/components/ui/markdown/markdown-readonly";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useUpdateBookmark } from "@karakeep/shared-react/hooks/bookmarks";
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
index eb746efc..696e1265 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkOptions.tsx
@@ -11,7 +11,7 @@ import {
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
-import { useToast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import {
@@ -74,7 +74,6 @@ function isSubsectionItem(item: ActionItemType): item is SubsectionItem {
export default function BookmarkOptions({ bookmark }: { bookmark: ZBookmark }) {
const { t } = useTranslation();
- const { toast } = useToast();
const linkId = bookmark.id;
const { data: session } = useSession();
diff --git a/apps/web/components/dashboard/bookmarks/BookmarkTagsEditor.tsx b/apps/web/components/dashboard/bookmarks/BookmarkTagsEditor.tsx
index 22b5408e..09843bce 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkTagsEditor.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkTagsEditor.tsx
@@ -1,4 +1,4 @@
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import type { ZBookmark } from "@karakeep/shared/types/bookmarks";
import { useUpdateBookmarkTags } from "@karakeep/shared-react/hooks/bookmarks";
diff --git a/apps/web/components/dashboard/bookmarks/BulkManageListsModal.tsx b/apps/web/components/dashboard/bookmarks/BulkManageListsModal.tsx
index 23afa7d2..1d4f5814 100644
--- a/apps/web/components/dashboard/bookmarks/BulkManageListsModal.tsx
+++ b/apps/web/components/dashboard/bookmarks/BulkManageListsModal.tsx
@@ -15,7 +15,7 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
diff --git a/apps/web/components/dashboard/bookmarks/BulkTagModal.tsx b/apps/web/components/dashboard/bookmarks/BulkTagModal.tsx
index 431f0fcd..53d2d013 100644
--- a/apps/web/components/dashboard/bookmarks/BulkTagModal.tsx
+++ b/apps/web/components/dashboard/bookmarks/BulkTagModal.tsx
@@ -7,7 +7,7 @@ import {
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useUpdateBookmarkTags } from "@karakeep/shared-react/hooks/bookmarks";
import { api } from "@karakeep/shared-react/trpc";
diff --git a/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx b/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx
index 7e680706..8e7a4d34 100644
--- a/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx
+++ b/apps/web/components/dashboard/bookmarks/DeleteBookmarkConfirmationDialog.tsx
@@ -1,7 +1,7 @@
import { usePathname, useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { useDeleteBookmark } from "@karakeep/shared-react/hooks//bookmarks";
diff --git a/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx b/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
index 49d27eaa..de6c1ff6 100644
--- a/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
+++ b/apps/web/components/dashboard/bookmarks/EditBookmarkDialog.tsx
@@ -25,8 +25,8 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
+import { toast } from "@/components/ui/sonner";
import { Textarea } from "@/components/ui/textarea";
-import { toast } from "@/components/ui/use-toast";
import { useDialogFormReset } from "@/lib/hooks/useDialogFormReset";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
diff --git a/apps/web/components/dashboard/bookmarks/EditorCard.tsx b/apps/web/components/dashboard/bookmarks/EditorCard.tsx
index fa752c5f..4636bcb9 100644
--- a/apps/web/components/dashboard/bookmarks/EditorCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/EditorCard.tsx
@@ -5,8 +5,8 @@ import { Form, FormControl, FormItem } from "@/components/ui/form";
import { Kbd } from "@/components/ui/kbd";
import MultipleChoiceDialog from "@/components/ui/multiple-choice-dialog";
import { Separator } from "@/components/ui/separator";
+import { toast } from "@/components/ui/sonner";
import { Textarea } from "@/components/ui/textarea";
-import { toast } from "@/components/ui/use-toast";
import BookmarkAlreadyExistsToast from "@/components/utils/BookmarkAlreadyExistsToast";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
diff --git a/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx b/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx
index 7c3827ab..34d797a6 100644
--- a/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx
+++ b/apps/web/components/dashboard/bookmarks/ManageListsModal.tsx
@@ -16,8 +16,8 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
+import { toast } from "@/components/ui/sonner";
import LoadingSpinner from "@/components/ui/spinner";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
diff --git a/apps/web/components/dashboard/bookmarks/SummarizeBookmarkArea.tsx b/apps/web/components/dashboard/bookmarks/SummarizeBookmarkArea.tsx
index b2cf118e..5f107663 100644
--- a/apps/web/components/dashboard/bookmarks/SummarizeBookmarkArea.tsx
+++ b/apps/web/components/dashboard/bookmarks/SummarizeBookmarkArea.tsx
@@ -1,8 +1,8 @@
import React from "react";
import { ActionButton } from "@/components/ui/action-button";
import { MarkdownReadonly } from "@/components/ui/markdown/markdown-readonly";
+import { toast } from "@/components/ui/sonner";
import LoadingSpinner from "@/components/ui/spinner";
-import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import { cn } from "@/lib/utils";
diff --git a/apps/web/components/dashboard/bookmarks/action-buttons/ArchiveBookmarkButton.tsx b/apps/web/components/dashboard/bookmarks/action-buttons/ArchiveBookmarkButton.tsx
index d45cfc82..fd2780cd 100644
--- a/apps/web/components/dashboard/bookmarks/action-buttons/ArchiveBookmarkButton.tsx
+++ b/apps/web/components/dashboard/bookmarks/action-buttons/ArchiveBookmarkButton.tsx
@@ -1,6 +1,6 @@
import React from "react";
import { ActionButton, ActionButtonProps } from "@/components/ui/action-button";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc";
import { useUpdateBookmark } from "@karakeep/shared-react/hooks/bookmarks";
diff --git a/apps/web/components/dashboard/cleanups/TagDuplicationDetention.tsx b/apps/web/components/dashboard/cleanups/TagDuplicationDetention.tsx
index 52a9ab0c..89aff598 100644
--- a/apps/web/components/dashboard/cleanups/TagDuplicationDetention.tsx
+++ b/apps/web/components/dashboard/cleanups/TagDuplicationDetention.tsx
@@ -11,6 +11,7 @@ import {
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
+import { toast } from "@/components/ui/sonner";
import LoadingSpinner from "@/components/ui/spinner";
import {
Table,
@@ -20,7 +21,6 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { cn } from "@/lib/utils";
diff --git a/apps/web/components/dashboard/highlights/HighlightCard.tsx b/apps/web/components/dashboard/highlights/HighlightCard.tsx
index 51421e0f..e7e7c519 100644
--- a/apps/web/components/dashboard/highlights/HighlightCard.tsx
+++ b/apps/web/components/dashboard/highlights/HighlightCard.tsx
@@ -1,5 +1,5 @@
import { ActionButton } from "@/components/ui/action-button";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { cn } from "@/lib/utils";
import { Trash2 } from "lucide-react";
diff --git a/apps/web/components/dashboard/lists/DeleteListConfirmationDialog.tsx b/apps/web/components/dashboard/lists/DeleteListConfirmationDialog.tsx
index 4996ddf1..6c091d7a 100644
--- a/apps/web/components/dashboard/lists/DeleteListConfirmationDialog.tsx
+++ b/apps/web/components/dashboard/lists/DeleteListConfirmationDialog.tsx
@@ -3,8 +3,8 @@ import { usePathname, useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
import { Label } from "@/components/ui/label";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import type { ZBookmarkList } from "@karakeep/shared/types/lists";
diff --git a/apps/web/components/dashboard/lists/EditListModal.tsx b/apps/web/components/dashboard/lists/EditListModal.tsx
index 5febf88c..4a14eccb 100644
--- a/apps/web/components/dashboard/lists/EditListModal.tsx
+++ b/apps/web/components/dashboard/lists/EditListModal.tsx
@@ -34,7 +34,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import data from "@emoji-mart/data";
import Picker from "@emoji-mart/react";
diff --git a/apps/web/components/dashboard/lists/LeaveListConfirmationDialog.tsx b/apps/web/components/dashboard/lists/LeaveListConfirmationDialog.tsx
index 62dbbcef..f2a48062 100644
--- a/apps/web/components/dashboard/lists/LeaveListConfirmationDialog.tsx
+++ b/apps/web/components/dashboard/lists/LeaveListConfirmationDialog.tsx
@@ -2,7 +2,7 @@ import React from "react";
import { usePathname, useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
diff --git a/apps/web/components/dashboard/lists/ManageCollaboratorsModal.tsx b/apps/web/components/dashboard/lists/ManageCollaboratorsModal.tsx
index 80dbcf65..6c5dac1e 100644
--- a/apps/web/components/dashboard/lists/ManageCollaboratorsModal.tsx
+++ b/apps/web/components/dashboard/lists/ManageCollaboratorsModal.tsx
@@ -22,7 +22,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { UserAvatar } from "@/components/ui/user-avatar";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
diff --git a/apps/web/components/dashboard/lists/MergeListModal.tsx b/apps/web/components/dashboard/lists/MergeListModal.tsx
index 0b7d362a..b22cd1a2 100644
--- a/apps/web/components/dashboard/lists/MergeListModal.tsx
+++ b/apps/web/components/dashboard/lists/MergeListModal.tsx
@@ -19,8 +19,8 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { X } from "lucide-react";
diff --git a/apps/web/components/dashboard/lists/PendingInvitationsCard.tsx b/apps/web/components/dashboard/lists/PendingInvitationsCard.tsx
index c453a91f..d893f4dc 100644
--- a/apps/web/components/dashboard/lists/PendingInvitationsCard.tsx
+++ b/apps/web/components/dashboard/lists/PendingInvitationsCard.tsx
@@ -8,7 +8,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { Check, Loader2, Mail, X } from "lucide-react";
diff --git a/apps/web/components/dashboard/preview/ActionBar.tsx b/apps/web/components/dashboard/preview/ActionBar.tsx
index 6e4cd5a2..9603465e 100644
--- a/apps/web/components/dashboard/preview/ActionBar.tsx
+++ b/apps/web/components/dashboard/preview/ActionBar.tsx
@@ -1,12 +1,12 @@
import { useState } from "react";
import { ActionButton } from "@/components/ui/action-button";
import { Button } from "@/components/ui/button";
+import { toast } from "@/components/ui/sonner";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { Pencil, Trash2 } from "lucide-react";
diff --git a/apps/web/components/dashboard/preview/AttachmentBox.tsx b/apps/web/components/dashboard/preview/AttachmentBox.tsx
index 73eea640..654f3211 100644
--- a/apps/web/components/dashboard/preview/AttachmentBox.tsx
+++ b/apps/web/components/dashboard/preview/AttachmentBox.tsx
@@ -8,7 +8,7 @@ import {
CollapsibleTrigger,
} from "@/components/ui/collapsible";
import FilePickerButton from "@/components/ui/file-picker-button";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { ASSET_TYPE_TO_ICON } from "@/lib/attachments";
import useUpload from "@/lib/hooks/upload-file";
import { useTranslation } from "@/lib/i18n/client";
diff --git a/apps/web/components/dashboard/preview/NoteEditor.tsx b/apps/web/components/dashboard/preview/NoteEditor.tsx
index 538aff2e..86807569 100644
--- a/apps/web/components/dashboard/preview/NoteEditor.tsx
+++ b/apps/web/components/dashboard/preview/NoteEditor.tsx
@@ -1,5 +1,5 @@
+import { toast } from "@/components/ui/sonner";
import { Textarea } from "@/components/ui/textarea";
-import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import type { ZBookmark } from "@karakeep/shared/types/bookmarks";
diff --git a/apps/web/components/dashboard/preview/ReaderView.tsx b/apps/web/components/dashboard/preview/ReaderView.tsx
index f2f843ee..9b765d55 100644
--- a/apps/web/components/dashboard/preview/ReaderView.tsx
+++ b/apps/web/components/dashboard/preview/ReaderView.tsx
@@ -1,5 +1,5 @@
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { api } from "@/lib/trpc";
import {
diff --git a/apps/web/components/dashboard/rules/RuleEngineRuleEditor.tsx b/apps/web/components/dashboard/rules/RuleEngineRuleEditor.tsx
index da10317a..d5658a70 100644
--- a/apps/web/components/dashboard/rules/RuleEngineRuleEditor.tsx
+++ b/apps/web/components/dashboard/rules/RuleEngineRuleEditor.tsx
@@ -8,8 +8,8 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
+import { toast } from "@/components/ui/sonner";
import { Textarea } from "@/components/ui/textarea";
-import { toast } from "@/components/ui/use-toast";
import { Save, X } from "lucide-react";
import { useTranslation } from "react-i18next";
diff --git a/apps/web/components/dashboard/rules/RuleEngineRuleList.tsx b/apps/web/components/dashboard/rules/RuleEngineRuleList.tsx
index 206a3550..32262b31 100644
--- a/apps/web/components/dashboard/rules/RuleEngineRuleList.tsx
+++ b/apps/web/components/dashboard/rules/RuleEngineRuleList.tsx
@@ -2,8 +2,8 @@ import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { Edit, Trash2 } from "lucide-react";
import { useTranslation } from "react-i18next";
diff --git a/apps/web/components/dashboard/tags/AllTagsView.tsx b/apps/web/components/dashboard/tags/AllTagsView.tsx
index c21f9aac..9708c37f 100644
--- a/apps/web/components/dashboard/tags/AllTagsView.tsx
+++ b/apps/web/components/dashboard/tags/AllTagsView.tsx
@@ -22,9 +22,9 @@ import {
import InfoTooltip from "@/components/ui/info-tooltip";
import { Input } from "@/components/ui/input";
import { Skeleton } from "@/components/ui/skeleton";
+import { toast } from "@/components/ui/sonner";
import Spinner from "@/components/ui/spinner";
import { Toggle } from "@/components/ui/toggle";
-import { toast } from "@/components/ui/use-toast";
import useBulkTagActionsStore from "@/lib/bulkTagActions";
import { useTranslation } from "@/lib/i18n/client";
import { ArrowDownAZ, ChevronDown, Combine, Search, Tag } from "lucide-react";
diff --git a/apps/web/components/dashboard/tags/BulkTagAction.tsx b/apps/web/components/dashboard/tags/BulkTagAction.tsx
index fbd044e0..c8061a1f 100644
--- a/apps/web/components/dashboard/tags/BulkTagAction.tsx
+++ b/apps/web/components/dashboard/tags/BulkTagAction.tsx
@@ -4,8 +4,8 @@ import { useEffect, useState } from "react";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
import { ButtonWithTooltip } from "@/components/ui/button";
+import { toast } from "@/components/ui/sonner";
import { Toggle } from "@/components/ui/toggle";
-import { useToast } from "@/components/ui/use-toast";
import useBulkTagActionsStore from "@/lib/bulkTagActions";
import { useTranslation } from "@/lib/i18n/client";
import { CheckCheck, Pencil, Trash2, X } from "lucide-react";
@@ -17,7 +17,6 @@ const MAX_CONCURRENT_BULK_ACTIONS = 50;
export default function BulkTagAction() {
const { t } = useTranslation();
- const { toast } = useToast();
const {
selectedTagIds,
diff --git a/apps/web/components/dashboard/tags/CreateTagModal.tsx b/apps/web/components/dashboard/tags/CreateTagModal.tsx
index 3a4c4995..e5cf4a45 100644
--- a/apps/web/components/dashboard/tags/CreateTagModal.tsx
+++ b/apps/web/components/dashboard/tags/CreateTagModal.tsx
@@ -22,7 +22,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { zodResolver } from "@hookform/resolvers/zod";
import { Plus } from "lucide-react";
diff --git a/apps/web/components/dashboard/tags/DeleteTagConfirmationDialog.tsx b/apps/web/components/dashboard/tags/DeleteTagConfirmationDialog.tsx
index 0a589ee6..7df04e20 100644
--- a/apps/web/components/dashboard/tags/DeleteTagConfirmationDialog.tsx
+++ b/apps/web/components/dashboard/tags/DeleteTagConfirmationDialog.tsx
@@ -1,7 +1,7 @@
import { usePathname, useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useDeleteTag } from "@karakeep/shared-react/hooks/tags";
diff --git a/apps/web/components/dashboard/tags/EditableTagName.tsx b/apps/web/components/dashboard/tags/EditableTagName.tsx
index 7854be32..e6df5086 100644
--- a/apps/web/components/dashboard/tags/EditableTagName.tsx
+++ b/apps/web/components/dashboard/tags/EditableTagName.tsx
@@ -1,7 +1,7 @@
"use client";
import { usePathname, useRouter } from "next/navigation";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { cn } from "@/lib/utils";
import { useUpdateTag } from "@karakeep/shared-react/hooks/tags";
diff --git a/apps/web/components/dashboard/tags/MergeTagModal.tsx b/apps/web/components/dashboard/tags/MergeTagModal.tsx
index 84dcd478..22b07c98 100644
--- a/apps/web/components/dashboard/tags/MergeTagModal.tsx
+++ b/apps/web/components/dashboard/tags/MergeTagModal.tsx
@@ -18,7 +18,7 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
diff --git a/apps/web/components/dashboard/tags/TagPill.tsx b/apps/web/components/dashboard/tags/TagPill.tsx
index 65a42e08..09310f9f 100644
--- a/apps/web/components/dashboard/tags/TagPill.tsx
+++ b/apps/web/components/dashboard/tags/TagPill.tsx
@@ -2,7 +2,7 @@ import React, { useRef, useState } from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useDragAndDrop } from "@/lib/drag-and-drop";
import { X } from "lucide-react";
import Draggable from "react-draggable";
diff --git a/apps/web/components/settings/AISettings.tsx b/apps/web/components/settings/AISettings.tsx
index 48c45633..78e3ef56 100644
--- a/apps/web/components/settings/AISettings.tsx
+++ b/apps/web/components/settings/AISettings.tsx
@@ -36,8 +36,8 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
diff --git a/apps/web/components/settings/AddApiKey.tsx b/apps/web/components/settings/AddApiKey.tsx
index c8baa626..9ef9047c 100644
--- a/apps/web/components/settings/AddApiKey.tsx
+++ b/apps/web/components/settings/AddApiKey.tsx
@@ -24,7 +24,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
diff --git a/apps/web/components/settings/BackupSettings.tsx b/apps/web/components/settings/BackupSettings.tsx
index 18a80993..ad2b66c6 100644
--- a/apps/web/components/settings/BackupSettings.tsx
+++ b/apps/web/components/settings/BackupSettings.tsx
@@ -21,8 +21,8 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { useUserSettings } from "@/lib/userSettings";
diff --git a/apps/web/components/settings/ChangePassword.tsx b/apps/web/components/settings/ChangePassword.tsx
index a27741d9..1da92267 100644
--- a/apps/web/components/settings/ChangePassword.tsx
+++ b/apps/web/components/settings/ChangePassword.tsx
@@ -12,7 +12,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
diff --git a/apps/web/components/settings/DeleteAccount.tsx b/apps/web/components/settings/DeleteAccount.tsx
index 6ebafff9..5ccbfaf7 100644
--- a/apps/web/components/settings/DeleteAccount.tsx
+++ b/apps/web/components/settings/DeleteAccount.tsx
@@ -13,7 +13,7 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle, Eye, EyeOff, Trash2 } from "lucide-react";
import { useForm } from "react-hook-form";
diff --git a/apps/web/components/settings/DeleteApiKey.tsx b/apps/web/components/settings/DeleteApiKey.tsx
index 4efb7ea8..392f3122 100644
--- a/apps/web/components/settings/DeleteApiKey.tsx
+++ b/apps/web/components/settings/DeleteApiKey.tsx
@@ -4,7 +4,7 @@ import { useRouter } from "next/navigation";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
import { Button } from "@/components/ui/button";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { Trash } from "lucide-react";
diff --git a/apps/web/components/settings/FeedSettings.tsx b/apps/web/components/settings/FeedSettings.tsx
index 23b639e4..a49bb0b2 100644
--- a/apps/web/components/settings/FeedSettings.tsx
+++ b/apps/web/components/settings/FeedSettings.tsx
@@ -13,8 +13,8 @@ import {
} from "@/components/ui/form";
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
import { Input } from "@/components/ui/input";
+import { toast } from "@/components/ui/sonner";
import { Switch } from "@/components/ui/switch";
-import { toast } from "@/components/ui/use-toast";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { cn } from "@/lib/utils";
diff --git a/apps/web/components/settings/ImportExport.tsx b/apps/web/components/settings/ImportExport.tsx
index 1cef8483..4aa84e44 100644
--- a/apps/web/components/settings/ImportExport.tsx
+++ b/apps/web/components/settings/ImportExport.tsx
@@ -12,6 +12,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
+import { toast } from "@/components/ui/sonner";
import { useBookmarkImport } from "@/lib/hooks/useBookmarkImport";
import { useTranslation } from "@/lib/i18n/client";
import { cn } from "@/lib/utils";
@@ -19,7 +20,6 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { AlertCircle, Download, Loader2, Upload } from "lucide-react";
import { Card, CardContent } from "../ui/card";
-import { toast } from "../ui/use-toast";
import { ImportSessionsSection } from "./ImportSessionsSection";
function ImportCard({
diff --git a/apps/web/components/settings/ReaderSettings.tsx b/apps/web/components/settings/ReaderSettings.tsx
index 28cc847e..d694bf02 100644
--- a/apps/web/components/settings/ReaderSettings.tsx
+++ b/apps/web/components/settings/ReaderSettings.tsx
@@ -1,6 +1,7 @@
"use client";
import { useState } from "react";
+import { toast } from "@/components/ui/sonner";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import { useReaderSettings } from "@/lib/readerSettings";
@@ -43,7 +44,6 @@ import {
SelectValue,
} from "../ui/select";
import { Slider } from "../ui/slider";
-import { toast } from "../ui/use-toast";
export default function ReaderSettings() {
const { t } = useTranslation();
diff --git a/apps/web/components/settings/RegenerateApiKey.tsx b/apps/web/components/settings/RegenerateApiKey.tsx
index 1c034026..f4914598 100644
--- a/apps/web/components/settings/RegenerateApiKey.tsx
+++ b/apps/web/components/settings/RegenerateApiKey.tsx
@@ -14,7 +14,7 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { RefreshCcw } from "lucide-react";
diff --git a/apps/web/components/settings/SubscriptionSettings.tsx b/apps/web/components/settings/SubscriptionSettings.tsx
index 53f1caf4..03337c1b 100644
--- a/apps/web/components/settings/SubscriptionSettings.tsx
+++ b/apps/web/components/settings/SubscriptionSettings.tsx
@@ -1,6 +1,7 @@
"use client";
import { useEffect } from "react";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { CreditCard, Loader2 } from "lucide-react";
@@ -16,7 +17,6 @@ import {
CardTitle,
} from "../ui/card";
import { Skeleton } from "../ui/skeleton";
-import { toast } from "../ui/use-toast";
export default function SubscriptionSettings() {
const { t } = useTranslation();
diff --git a/apps/web/components/settings/UserAvatar.tsx b/apps/web/components/settings/UserAvatar.tsx
index fd773697..6baff7c2 100644
--- a/apps/web/components/settings/UserAvatar.tsx
+++ b/apps/web/components/settings/UserAvatar.tsx
@@ -4,6 +4,7 @@ import type { ChangeEvent } from "react";
import { useRef } from "react";
import { ActionButton } from "@/components/ui/action-button";
import ActionConfirmingDialog from "@/components/ui/action-confirming-dialog";
+import { toast } from "@/components/ui/sonner";
import { UserAvatar as UserAvatarImage } from "@/components/ui/user-avatar";
import useUpload from "@/lib/hooks/upload-file";
import { useTranslation } from "@/lib/i18n/client";
@@ -16,7 +17,6 @@ import {
import { Button } from "../ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
-import { toast } from "../ui/use-toast";
export default function UserAvatar() {
const { t } = useTranslation();
diff --git a/apps/web/components/settings/UserOptions.tsx b/apps/web/components/settings/UserOptions.tsx
index 0df1085e..763695c5 100644
--- a/apps/web/components/settings/UserOptions.tsx
+++ b/apps/web/components/settings/UserOptions.tsx
@@ -1,6 +1,7 @@
"use client";
import { useEffect, useState } from "react";
+import { toast } from "@/components/ui/sonner";
import { useClientConfig } from "@/lib/clientConfig";
import { useTranslation } from "@/lib/i18n/client";
import { useInterfaceLang } from "@/lib/userLocalSettings/bookmarksLayout";
@@ -28,7 +29,6 @@ import {
SelectTrigger,
SelectValue,
} from "../ui/select";
-import { toast } from "../ui/use-toast";
const LanguageSelect = () => {
const lang = useInterfaceLang();
diff --git a/apps/web/components/settings/WebhookSettings.tsx b/apps/web/components/settings/WebhookSettings.tsx
index 8efd3ba6..73671787 100644
--- a/apps/web/components/settings/WebhookSettings.tsx
+++ b/apps/web/components/settings/WebhookSettings.tsx
@@ -12,7 +12,7 @@ import {
} from "@/components/ui/form";
import { FullPageSpinner } from "@/components/ui/full-page-spinner";
import { Input } from "@/components/ui/input";
-import { toast } from "@/components/ui/use-toast";
+import { toast } from "@/components/ui/sonner";
import { useTranslation } from "@/lib/i18n/client";
import { api } from "@/lib/trpc";
import { zodResolver } from "@hookform/resolvers/zod";
diff --git a/apps/web/components/ui/copy-button.tsx b/apps/web/components/ui/copy-button.tsx
index 8d8699f8..fb1f943f 100644
--- a/apps/web/components/ui/copy-button.tsx
+++ b/apps/web/components/ui/copy-button.tsx
@@ -1,9 +1,9 @@
import React, { useEffect, useState } from "react";
+import { toast } from "@/components/ui/sonner";
import { cn } from "@/lib/utils";
import { Check, Copy } from "lucide-react";
import { Button } from "./button";
-import { toast } from "./use-toast";
export default function CopyBtn({
className,
diff --git a/apps/web/components/ui/sonner.tsx b/apps/web/components/ui/sonner.tsx
new file mode 100644
index 00000000..d281f4ae
--- /dev/null
+++ b/apps/web/components/ui/sonner.tsx
@@ -0,0 +1,71 @@
+"use client";
+
+import {
+ CircleCheck,
+ Info,
+ LoaderCircle,
+ OctagonX,
+ TriangleAlert,
+} from "lucide-react";
+import { useTheme } from "next-themes";
+import { Toaster as Sonner, toast } from "sonner";
+
+type ToasterProps = React.ComponentProps<typeof Sonner>;
+
+const Toaster = ({ ...props }: ToasterProps) => {
+ const { theme = "system" } = useTheme();
+
+ return (
+ <Sonner
+ theme={theme as ToasterProps["theme"]}
+ className="toaster group"
+ icons={{
+ success: <CircleCheck className="h-4 w-4" />,
+ info: <Info className="h-4 w-4" />,
+ warning: <TriangleAlert className="h-4 w-4" />,
+ error: <OctagonX className="h-4 w-4" />,
+ loading: <LoaderCircle className="h-4 w-4 animate-spin" />,
+ }}
+ toastOptions={{
+ classNames: {
+ toast:
+ "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg",
+ description: "group-[.toast]:text-muted-foreground",
+ actionButton:
+ "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
+ cancelButton:
+ "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
+ },
+ }}
+ {...props}
+ />
+ );
+};
+
+/**
+ * Compat layer for migrating from old toaster to sonner
+ * @deprecated Use sonner's natie toast instead
+ */
+const legacyToast = ({
+ title,
+ description,
+ variant,
+}: {
+ title?: React.ReactNode;
+ description?: React.ReactNode;
+ variant?: "destructive" | "default";
+}) => {
+ let toastTitle = title;
+ let toastDescription: React.ReactNode | undefined = description;
+ if (!title) {
+ toastTitle = description;
+ toastDescription = undefined;
+ }
+ if (variant === "destructive") {
+ toast.error(toastTitle, { description: toastDescription });
+ } else {
+ toast(toastTitle, { description: toastDescription });
+ }
+};
+
+export { Toaster, legacyToast as toast };
diff --git a/apps/web/components/ui/toaster.tsx b/apps/web/components/ui/toaster.tsx
deleted file mode 100644
index 7d82ed55..00000000
--- a/apps/web/components/ui/toaster.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-"use client";
-
-import {
- Toast,
- ToastClose,
- ToastDescription,
- ToastProvider,
- ToastTitle,
- ToastViewport,
-} from "@/components/ui/toast";
-import { useToast } from "@/components/ui/use-toast";
-
-export function Toaster() {
- const { toasts } = useToast();
-
- return (
- <ToastProvider>
- {toasts.map(function ({ id, title, description, action, ...props }) {
- return (
- <Toast key={id} {...props}>
- <div className="grid gap-1">
- {title && <ToastTitle>{title}</ToastTitle>}
- {description && (
- <ToastDescription>{description}</ToastDescription>
- )}
- </div>
- {action}
- <ToastClose />
- </Toast>
- );
- })}
- <ToastViewport />
- </ToastProvider>
- );
-}
diff --git a/apps/web/components/ui/use-toast.ts b/apps/web/components/ui/use-toast.ts
deleted file mode 100644
index c3e7e884..00000000
--- a/apps/web/components/ui/use-toast.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-// Inspired by react-hot-toast library
-import type { ToastActionElement, ToastProps } from "@/components/ui/toast";
-import * as React from "react";
-
-const TOAST_LIMIT = 10;
-const TOAST_REMOVE_DELAY = 1000000;
-
-type ToasterToast = ToastProps & {
- id: string;
- title?: React.ReactNode;
- description?: React.ReactNode;
- action?: ToastActionElement;
-};
-
-const actionTypes = {
- ADD_TOAST: "ADD_TOAST",
- UPDATE_TOAST: "UPDATE_TOAST",
- DISMISS_TOAST: "DISMISS_TOAST",
- REMOVE_TOAST: "REMOVE_TOAST",
-} as const;
-
-let count = 0;
-
-function genId() {
- count = (count + 1) % Number.MAX_SAFE_INTEGER;
- return count.toString();
-}
-
-type ActionType = typeof actionTypes;
-
-type Action =
- | {
- type: ActionType["ADD_TOAST"];
- toast: ToasterToast;
- }
- | {
- type: ActionType["UPDATE_TOAST"];
- toast: Partial<ToasterToast>;
- }
- | {
- type: ActionType["DISMISS_TOAST"];
- toastId?: ToasterToast["id"];
- }
- | {
- type: ActionType["REMOVE_TOAST"];
- toastId?: ToasterToast["id"];
- };
-
-interface State {
- toasts: ToasterToast[];
-}
-
-const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
-
-const addToRemoveQueue = (toastId: string) => {
- if (toastTimeouts.has(toastId)) {
- return;
- }
-
- const timeout = setTimeout(() => {
- toastTimeouts.delete(toastId);
- dispatch({
- type: "REMOVE_TOAST",
- toastId: toastId,
- });
- }, TOAST_REMOVE_DELAY);
-
- toastTimeouts.set(toastId, timeout);
-};
-
-export const reducer = (state: State, action: Action): State => {
- switch (action.type) {
- case "ADD_TOAST":
- return {
- ...state,
- toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
- };
-
- case "UPDATE_TOAST":
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === action.toast.id ? { ...t, ...action.toast } : t,
- ),
- };
-
- case "DISMISS_TOAST": {
- const { toastId } = action;
-
- // ! Side effects ! - This could be extracted into a dismissToast() action,
- // but I'll keep it here for simplicity
- if (toastId) {
- addToRemoveQueue(toastId);
- } else {
- state.toasts.forEach((toast) => {
- addToRemoveQueue(toast.id);
- });
- }
-
- return {
- ...state,
- toasts: state.toasts.map((t) =>
- t.id === toastId || toastId === undefined
- ? {
- ...t,
- open: false,
- }
- : t,
- ),
- };
- }
- case "REMOVE_TOAST":
- if (action.toastId === undefined) {
- return {
- ...state,
- toasts: [],
- };
- }
- return {
- ...state,
- toasts: state.toasts.filter((t) => t.id !== action.toastId),
- };
- }
-};
-
-const listeners: ((_state: State) => void)[] = [];
-
-let memoryState: State = { toasts: [] };
-
-function dispatch(action: Action) {
- memoryState = reducer(memoryState, action);
- listeners.forEach((listener) => {
- listener(memoryState);
- });
-}
-
-type Toast = Omit<ToasterToast, "id">;
-
-function toast({ ...props }: Toast) {
- const id = genId();
-
- const update = (props: ToasterToast) =>
- dispatch({
- type: "UPDATE_TOAST",
- toast: { ...props, id },
- });
- const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id });
-
- dispatch({
- type: "ADD_TOAST",
- toast: {
- ...props,
- id,
- open: true,
- onOpenChange: (open) => {
- if (!open) dismiss();
- },
- },
- });
-
- return {
- id: id,
- dismiss,
- update,
- };
-}
-
-function useToast() {
- const [state, setState] = React.useState<State>(memoryState);
-
- React.useEffect(() => {
- listeners.push(setState);
- return () => {
- const index = listeners.indexOf(setState);
- if (index > -1) {
- listeners.splice(index, 1);
- }
- };
- }, [state]);
-
- return {
- ...state,
- toast,
- dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
- };
-}
-
-export { useToast, toast };