From 20d3761c89d566cf28ef1a22db14ad4f6eef2f17 Mon Sep 17 00:00:00 2001
From: Mohamed Bassem <me@mbassem.com>
Date: Mon, 8 Dec 2025 10:35:17 +0000
Subject: fix: check import quota before importing bookmarks (#2232)

* feat: check import quota before importing bookmarks

Add quota validation before bookmark import to prevent users from
exceeding their bookmark limits. The implementation includes:

- New QuotaService.canImportBookmarks() method to check if user can import N bookmarks
- New tRPC checkImportQuota procedure for client-side quota validation
- Updated useBookmarkImport hook to parse files and check quota before import
- Added error banner in ImportExport component to display quota errors
- Optimized file parsing to avoid reading the file twice

The quota check displays remaining bookmarks and provides clear error
messages when the import would exceed the user's quota.

* fix

* some fixes

---------

Co-authored-by: Claude <noreply@anthropic.com>
---
 apps/web/components/settings/ImportExport.tsx | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

(limited to 'apps/web/components/settings/ImportExport.tsx')

diff --git a/apps/web/components/settings/ImportExport.tsx b/apps/web/components/settings/ImportExport.tsx
index 7d127443..b6e4da9a 100644
--- a/apps/web/components/settings/ImportExport.tsx
+++ b/apps/web/components/settings/ImportExport.tsx
@@ -1,6 +1,7 @@
 "use client";
 
 import { useCallback, useEffect, useState } from "react";
+import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
 import { Button, buttonVariants } from "@/components/ui/button";
 import FilePickerButton from "@/components/ui/file-picker-button";
 import { Progress } from "@/components/ui/progress";
@@ -15,7 +16,7 @@ import { useBookmarkImport } from "@/lib/hooks/useBookmarkImport";
 import { useTranslation } from "@/lib/i18n/client";
 import { cn } from "@/lib/utils";
 import { useQuery, useQueryClient } from "@tanstack/react-query";
-import { Download, Loader2, Upload } from "lucide-react";
+import { AlertCircle, Download, Loader2, Upload } from "lucide-react";
 
 import { Card, CardContent } from "../ui/card";
 import { toast } from "../ui/use-toast";
@@ -131,10 +132,18 @@ function ExportButton() {
 
 export function ImportExportRow() {
   const { t } = useTranslation();
-  const { importProgress, runUploadBookmarkFile } = useBookmarkImport();
+  const { importProgress, quotaError, runUploadBookmarkFile } =
+    useBookmarkImport();
 
   return (
     <div className="flex flex-col gap-3">
+      {quotaError && (
+        <Alert variant="destructive" className="relative">
+          <AlertCircle className="h-4 w-4" />
+          <AlertTitle>Import Quota Exceeded</AlertTitle>
+          <AlertDescription>{quotaError}</AlertDescription>
+        </Alert>
+      )}
       <div className="grid gap-4 md:grid-cols-2">
         <ImportCard
           text="HTML File"
-- 
cgit v1.2.3-70-g09d2

