feat(library): redesign empty-library onboarding (#4122)

First-run users opening Readest with no books now see a typographic
hero instead of the previous generic "Welcome to your library" hero.

Key UX changes:
- 64px PiBooks glyph at base-content/60 anchors a single-column
  composition (max-w-md container, max-w-xs button stack)
- Headline "Start your library" — action-led, not "Welcome to X"
- Platform-aware description:
    desktop: "Drop a book anywhere on this window, or pick one from
             your computer."
    mobile : "Pick a book from your device to add it to your library."
  Branched on appService.isMobile so the touch-only flows don't see
  drag-and-drop language.
- Auth-aware secondary action: a quiet underlined "Sign in to sync
  your library" text link renders only when logged out; signed-in
  users get just the Import CTA (sync runs automatically).
- Primary CTA "Import Books" unchanged; routes to existing file
  picker. The surrounding hero drop-zone wrapper is preserved so
  drag-and-drop import keeps working on desktop.
- TODO marker for a future "Browse free catalogs" entry above the
  secondary action slot.

Implementation:
- Extracted as src/app/library/components/LibraryEmptyState.tsx
  (~60 lines, single onImport prop) so the empty branch can be
  unit-tested without mounting the full LibraryPageContent.
- src/app/library/page.tsx swaps ~17 lines of inline hero JSX for
  one <LibraryEmptyState onImport={handleImportBooksFromFiles} />.
- Four unit tests cover desktop render, mobile render, auth-aware
  sync-button hide, and import-click callback.

i18n: four new strings translated across 33 locales; en/translation.json
untouched per the project convention (non-plural strings live in
code). Stale "Welcome to your library..." key removed by the scanner.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Huang Xin
2026-05-11 11:58:54 +08:00
committed by GitHub
parent d326e1c73d
commit 598eb77237
36 changed files with 309 additions and 79 deletions
@@ -101,7 +101,6 @@
"Updated": "تم التحديث",
"Version {{version}}": "الإصدار {{version}}",
"Vertical Direction": "الاتجاه العمودي",
"Welcome to your library. You can import your books here and read them anytime.": "مرحبًا بكم في مكتبتكم. يمكنكم استيراد كتبكم هنا وقراءتها في أي وقت.",
"Wikipedia": "ويكيبيديا",
"Writing Mode": "وضع الكتابة",
"Your Library": "المكتبة الخاصة بك",
@@ -1509,5 +1508,9 @@
"Content Sources": "مصادر المحتوى",
"Scroll tabs": "تمرير علامات التبويب",
"Catalog actions": "إجراءات الفهرس",
"File Content": "محتوى الملف"
"File Content": "محتوى الملف",
"Start your library": "ابدأ مكتبتك",
"Pick a book from your device to add it to your library.": "اختر كتابًا من جهازك لإضافته إلى مكتبتك.",
"Drop a book anywhere on this window, or pick one from your computer.": "أفلِت كتابًا في أي مكان على هذه النافذة، أو اختر واحدًا من حاسوبك.",
"Sign in to sync your library": "سجّل الدخول لمزامنة مكتبتك"
}
@@ -117,7 +117,6 @@
"Failed to delete book: {{title}}": "বই মুছতে ব্যর্থ: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "বইয়ের ক্লাউড ব্যাকআপ মুছতে ব্যর্থ: {{title}}",
"Failed to delete local copy of the book: {{title}}": "বইয়ের স্থানীয় কপি মুছতে ব্যর্থ: {{title}}",
"Welcome to your library. You can import your books here and read them anytime.": "আপনার লাইব্রেরিতে স্বাগতম। আপনি এখানে বই আমদানি করে যেকোনো সময় পড়তে পারেন।",
"Copied to notebook": "নোটবুকে কপি করা হয়েছে",
"No annotations to export": "রপ্তানি করার জন্য কোন টীকা নেই",
"Exported from Readest": "রিডেস্ট থেকে রপ্তানি করা হয়েছে",
@@ -1409,5 +1408,9 @@
"Content Sources": "কন্টেন্ট উৎস",
"Scroll tabs": "ট্যাব স্ক্রোল করুন",
"Catalog actions": "ক্যাটালগ অ্যাকশন",
"File Content": "ফাইল সামগ্রী"
"File Content": "ফাইল সামগ্রী",
"Start your library": "আপনার লাইব্রেরি শুরু করুন",
"Pick a book from your device to add it to your library.": "আপনার লাইব্রেরিতে যোগ করতে ডিভাইস থেকে একটি বই বেছে নিন।",
"Drop a book anywhere on this window, or pick one from your computer.": "এই উইন্ডোর যেকোনো জায়গায় একটি বই ছাড়ুন, অথবা আপনার কম্পিউটার থেকে একটি বেছে নিন।",
"Sign in to sync your library": "আপনার লাইব্রেরি সিঙ্ক করতে সাইন ইন করুন"
}
@@ -102,7 +102,6 @@
"Updated": "བསྐྱར་བརྗེའི་ཚེས་གྲངས།",
"Version {{version}}": "ཐོན་རིམ {{version}}",
"Vertical Direction": "ཀྲིང་རིམ།",
"Welcome to your library. You can import your books here and read them anytime.": "དཔེ་མཛོད་སྟོང་པ་ཡིན། ཁྱེད་ཀྱིས་ཁྱེད་རང་གི་དཔེ་དེབ་ནང་འདྲེན་བྱས་ནས་དུས་དང་རྣམ་པ་ཀུན་ཏུ་ཀློག་ཐུབ།",
"Wikipedia": "ཝེ་ཁི་པི་ཌི་ཡ།",
"Writing Mode": "པར་སྒྲིག་གི་རྣམ་པ།",
"Your Library": "དཔེ་མཛོད།",
@@ -1384,5 +1383,9 @@
"Content Sources": "ནང་དོན་འབྱུང་ཁུངས།",
"Scroll tabs": "ཤོག་བྱང་འགུལ་སྐྱོད།",
"Catalog actions": "དཔེ་ཐོའི་བྱ་སྤྱོད།",
"File Content": "ཡིག་ཆའི་ནང་དོན།"
"File Content": "ཡིག་ཆའི་ནང་དོན།",
"Start your library": "ཁྱེད་ཀྱི་དཔེ་མཛོད་འགོ་འཛུགས།",
"Pick a book from your device to add it to your library.": "ཁྱེད་ཀྱི་སྒྲིག་ཆས་ནས་དཔེ་དེབ་ཅིག་འདེམས་ནས་ཁྱེད་ཀྱི་དཔེ་མཛོད་ལ་ཁ་སྣོན་གྱིས།",
"Drop a book anywhere on this window, or pick one from your computer.": "སྒེའུ་ཁུང་འདིའི་གང་སར་དཔེ་དེབ་ཅིག་འཇོག་པའམ་ཡང་ན་ཁྱེད་ཀྱི་གློག་ཀླད་ནས་འདེམས་རོགས།",
"Sign in to sync your library": "ཁྱེད་ཀྱི་དཔེ་མཛོད་མཉམ་སྦྱོར་གྱི་ཆེད་ནང་བསྐྱོད་གནང་རོགས།"
}
@@ -101,7 +101,6 @@
"Updated": "Aktualisiert",
"Version {{version}}": "Version {{version}}",
"Vertical Direction": "Vertikale Richtung",
"Welcome to your library. You can import your books here and read them anytime.": "Willkommen in Ihrer Bibliothek. Sie können hier Ihre Bücher importieren und jederzeit lesen.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Schreibmodus",
"Your Library": "Ihre Bibliothek",
@@ -1409,5 +1408,9 @@
"Content Sources": "Inhaltsquellen",
"Scroll tabs": "Tabs scrollen",
"Catalog actions": "Katalogaktionen",
"File Content": "Dateiinhalt"
"File Content": "Dateiinhalt",
"Start your library": "Starten Sie Ihre Bibliothek",
"Pick a book from your device to add it to your library.": "Wählen Sie ein Buch von Ihrem Gerät, um es Ihrer Bibliothek hinzuzufügen.",
"Drop a book anywhere on this window, or pick one from your computer.": "Ziehen Sie ein Buch an eine beliebige Stelle dieses Fensters oder wählen Sie eines von Ihrem Computer aus.",
"Sign in to sync your library": "Melden Sie sich an, um Ihre Bibliothek zu synchronisieren"
}
@@ -102,7 +102,6 @@
"Updated": "Ενημερώθηκε",
"Version {{version}}": "Έκδοση {{version}}",
"Vertical Direction": "Κάθετη κατεύθυνση",
"Welcome to your library. You can import your books here and read them anytime.": "Καλώς ήρθατε στη βιβλιοθήκη σας. Μπορείτε να εισάγετε τα βιβλία σας εδώ και να τα διαβάσετε οποιαδήποτε στιγμή.",
"Wikipedia": "Βικιπαίδεια",
"Writing Mode": "Λειτουργία γραφής",
"Your Library": "Η βιβλιοθήκη σας",
@@ -1409,5 +1408,9 @@
"Content Sources": "Πηγές περιεχομένου",
"Scroll tabs": "Κύλιση καρτελών",
"Catalog actions": "Ενέργειες καταλόγου",
"File Content": "Περιεχόμενο αρχείου"
"File Content": "Περιεχόμενο αρχείου",
"Start your library": "Ξεκινήστε τη βιβλιοθήκη σας",
"Pick a book from your device to add it to your library.": "Επιλέξτε ένα βιβλίο από τη συσκευή σας για να το προσθέσετε στη βιβλιοθήκη σας.",
"Drop a book anywhere on this window, or pick one from your computer.": "Αφήστε ένα βιβλίο οπουδήποτε σε αυτό το παράθυρο ή επιλέξτε ένα από τον υπολογιστή σας.",
"Sign in to sync your library": "Συνδεθείτε για να συγχρονίσετε τη βιβλιοθήκη σας"
}
@@ -124,7 +124,6 @@
"Updated": "Actualizado",
"Version {{version}}": "Versión {{version}}",
"Vertical Direction": "Dirección vertical",
"Welcome to your library. You can import your books here and read them anytime.": "Bienvenido a tu biblioteca. Puedes importar tus libros aquí y leerlos en cualquier momento.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Modo de escritura",
"Your Library": "Tu biblioteca",
@@ -1434,5 +1433,9 @@
"Content Sources": "Fuentes de contenido",
"Scroll tabs": "Desplazar pestañas",
"Catalog actions": "Acciones del catálogo",
"File Content": "Contenido del archivo"
"File Content": "Contenido del archivo",
"Start your library": "Empieza tu biblioteca",
"Pick a book from your device to add it to your library.": "Elige un libro de tu dispositivo para añadirlo a tu biblioteca.",
"Drop a book anywhere on this window, or pick one from your computer.": "Suelta un libro en cualquier parte de esta ventana o elige uno desde tu computadora.",
"Sign in to sync your library": "Inicia sesión para sincronizar tu biblioteca"
}
@@ -101,7 +101,6 @@
"Updated": "به‌روزرسانی شده",
"Version {{version}}": "نسخه‌ی {{version}}",
"Vertical Direction": "جهت عمودی",
"Welcome to your library. You can import your books here and read them anytime.": "به کتابخانه‌تان خوش آمدید. می‌توانید کتاب‌هایتان را اینجا وارد کنید و هر زمان خواستید آن‌ها را بخوانید.",
"Wikipedia": "ویکی‌پدیا",
"Writing Mode": "حالت نوشتن",
"Your Library": "کتابخانه‌ی شما",
@@ -1409,5 +1408,9 @@
"Content Sources": "منابع محتوا",
"Scroll tabs": "پیمایش زبانه‌ها",
"Catalog actions": "اقدامات فهرست",
"File Content": "محتوای فایل"
"File Content": "محتوای فایل",
"Start your library": "کتابخانه‌ی خود را آغاز کنید",
"Pick a book from your device to add it to your library.": "از دستگاه خود کتابی انتخاب کنید تا به کتابخانه‌تان افزوده شود.",
"Drop a book anywhere on this window, or pick one from your computer.": "کتابی را در هر جای این پنجره رها کنید، یا یکی را از رایانه‌ی خود انتخاب کنید.",
"Sign in to sync your library": "برای همگام‌سازی کتابخانه‌ی خود وارد شوید"
}
@@ -102,7 +102,6 @@
"Updated": "Mis à jour",
"Version {{version}}": "Version {{version}}",
"Vertical Direction": "Direction verticale",
"Welcome to your library. You can import your books here and read them anytime.": "Bienvenue dans votre bibliothèque. Vous pouvez importer vos livres ici et les lire à tout moment.",
"Wikipedia": "Wikipédia",
"Writing Mode": "Mode écriture",
"Your Library": "Votre bibliothèque",
@@ -1434,5 +1433,9 @@
"Content Sources": "Sources de contenu",
"Scroll tabs": "Faire défiler les onglets",
"Catalog actions": "Actions du catalogue",
"File Content": "Contenu du fichier"
"File Content": "Contenu du fichier",
"Start your library": "Commencez votre bibliothèque",
"Pick a book from your device to add it to your library.": "Choisissez un livre depuis votre appareil à ajouter à votre bibliothèque.",
"Drop a book anywhere on this window, or pick one from your computer.": "Déposez un livre n'importe où sur cette fenêtre, ou choisissez-en un depuis votre ordinateur.",
"Sign in to sync your library": "Connectez-vous pour synchroniser votre bibliothèque"
}
@@ -217,7 +217,6 @@
"Failed to delete local copy of the book: {{title}}": "מחיקת העעותק המקומי של הספר נכשלה: {{title}}",
"Library Header": "כותרת הספרייה",
"Library Sync Progress": "התקדמות סנכרון הספרייה",
"Welcome to your library. You can import your books here and read them anytime.": "ברוכים הבאים לספרייה שלכם. כאן תוכלו לייבא את הספרים שלכם ולקרוא אותם בכל עת.",
"URL must start with http:// or https://": "הכתובת חייבת להתחיל ב-http:// או https://",
"Adding LAN addresses is not supported in the web app version.": "הוספת כתובות LAN אינה נתמכת בגרסת אפליקציית האינטרנט.",
"Invalid OPDS catalog. Please check the URL.": "קטלוג OPDS לא תקין. אנא בדוק את הכתובת.",
@@ -1434,5 +1433,9 @@
"Content Sources": "מקורות תוכן",
"Scroll tabs": "גלילת לשוניות",
"Catalog actions": "פעולות קטלוג",
"File Content": "תוכן הקובץ"
"File Content": "תוכן הקובץ",
"Start your library": "התחילו את הספרייה שלכם",
"Pick a book from your device to add it to your library.": "בחרו ספר מהמכשיר שלכם כדי להוסיף אותו לספרייה.",
"Drop a book anywhere on this window, or pick one from your computer.": "שחררו ספר בכל מקום בחלון הזה, או בחרו אחד מהמחשב שלכם.",
"Sign in to sync your library": "התחברו לסנכרון הספרייה שלכם"
}
@@ -102,7 +102,6 @@
"Updated": "अपडेट किया गया",
"Version {{version}}": "संस्करण {{version}}",
"Vertical Direction": "ऊर्ध्वाधर दिशा",
"Welcome to your library. You can import your books here and read them anytime.": "आपकी लाइब्रेरी में आपका स्वागत है। आप यहां अपनी पुस्तकें आयात कर सकते हैं और कभी भी पढ़ सकते हैं।",
"Wikipedia": "विकिपीडिया",
"Writing Mode": "लेखन मोड",
"Your Library": "आपकी लाइब्रेरी",
@@ -1409,5 +1408,9 @@
"Content Sources": "सामग्री स्रोत",
"Scroll tabs": "टैब स्क्रॉल करें",
"Catalog actions": "कैटलॉग क्रियाएँ",
"File Content": "फ़ाइल सामग्री"
"File Content": "फ़ाइल सामग्री",
"Start your library": "अपनी लाइब्रेरी शुरू करें",
"Pick a book from your device to add it to your library.": "अपनी लाइब्रेरी में जोड़ने के लिए अपने डिवाइस से एक किताब चुनें।",
"Drop a book anywhere on this window, or pick one from your computer.": "इस विंडो में कहीं भी एक किताब छोड़ें, या अपने कंप्यूटर से कोई एक चुनें।",
"Sign in to sync your library": "अपनी लाइब्रेरी सिंक करने के लिए साइन इन करें"
}
@@ -227,7 +227,6 @@
"Library Header": "Könyvtár fejléc",
"Library Sync Progress": "Könyvtár szinkronizálási állapot",
"Your Bookshelf": "Az Ön könyvespolca",
"Welcome to your library. You can import your books here and read them anytime.": "Üdvözöljük a könyvtárában. Importálhatja könyveit és bármikor olvashatja őket.",
"URL must start with http:// or https://": "Az URL-nek http:// vagy https:// előtaggal kell kezdődnie",
"Adding LAN addresses is not supported in the web app version.": "A LAN-címek hozzáadása nem támogatott a webes alkalmazásban.",
"Please confirm that this OPDS connection will be proxied through Readest servers on the web app before continuing.": "Kérjük, erősítse meg, hogy ez az OPDS-kapcsolat a Readest szerverein keresztül lesz továbbítva a webalkalmazásban.",
@@ -1409,5 +1408,9 @@
"Content Sources": "Tartalomforrások",
"Scroll tabs": "Lapok görgetése",
"Catalog actions": "Katalógusműveletek",
"File Content": "Fájl tartalma"
"File Content": "Fájl tartalma",
"Start your library": "Indítsa el a könyvtárát",
"Pick a book from your device to add it to your library.": "Válasszon egy könyvet az eszközéről, hogy hozzáadja a könyvtárához.",
"Drop a book anywhere on this window, or pick one from your computer.": "Húzzon egy könyvet bárhová ezen az ablakon, vagy válasszon egyet a számítógépéről.",
"Sign in to sync your library": "Jelentkezzen be a könyvtár szinkronizálásához"
}
@@ -102,7 +102,6 @@
"Updated": "Diperbarui",
"Version {{version}}": "Versi {{version}}",
"Vertical Direction": "Arah Vertikal",
"Welcome to your library. You can import your books here and read them anytime.": "Selamat datang di perpustakaan Anda. Anda dapat mengimpor buku-buku Anda di sini dan membacanya kapan saja.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Mode Menulis",
"Your Library": "Perpustakaan Anda",
@@ -1384,5 +1383,9 @@
"Content Sources": "Sumber Konten",
"Scroll tabs": "Gulir tab",
"Catalog actions": "Tindakan katalog",
"File Content": "Konten berkas"
"File Content": "Konten berkas",
"Start your library": "Mulai perpustakaan Anda",
"Pick a book from your device to add it to your library.": "Pilih buku dari perangkat Anda untuk ditambahkan ke perpustakaan Anda.",
"Drop a book anywhere on this window, or pick one from your computer.": "Jatuhkan buku di mana saja pada jendela ini, atau pilih satu dari komputer Anda.",
"Sign in to sync your library": "Masuk untuk menyinkronkan perpustakaan Anda"
}
@@ -102,7 +102,6 @@
"Updated": "Aggiornato",
"Version {{version}}": "Versione {{version}}",
"Vertical Direction": "Direzione verticale",
"Welcome to your library. You can import your books here and read them anytime.": "Benvenuto nella tua biblioteca. Puoi importare i tuoi libri qui e leggerli in qualsiasi momento.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Modalità scrittura",
"Your Library": "La tua biblioteca",
@@ -1434,5 +1433,9 @@
"Content Sources": "Fonti di contenuti",
"Scroll tabs": "Scorri schede",
"Catalog actions": "Azioni del catalogo",
"File Content": "Contenuto del file"
"File Content": "Contenuto del file",
"Start your library": "Inizia la tua biblioteca",
"Pick a book from your device to add it to your library.": "Scegli un libro dal tuo dispositivo per aggiungerlo alla tua biblioteca.",
"Drop a book anywhere on this window, or pick one from your computer.": "Trascina un libro in qualsiasi punto di questa finestra, o sceglilo dal tuo computer.",
"Sign in to sync your library": "Accedi per sincronizzare la tua biblioteca"
}
@@ -102,7 +102,6 @@
"Updated": "更新日",
"Version {{version}}": "バージョン {{version}}",
"Vertical Direction": "縦書",
"Welcome to your library. You can import your books here and read them anytime.": "ライブラリーへようこそ。ここに書籍をインポートして、いつでも読むことができます。",
"Wikipedia": "ウィキペディア",
"Writing Mode": "書き込みモード",
"Your Library": "ライブラリー",
@@ -1384,5 +1383,9 @@
"Content Sources": "コンテンツソース",
"Scroll tabs": "タブをスクロール",
"Catalog actions": "カタログ操作",
"File Content": "ファイル内容"
"File Content": "ファイル内容",
"Start your library": "ライブラリーを作成しましょう",
"Pick a book from your device to add it to your library.": "デバイスから本を選んでライブラリーに追加しましょう。",
"Drop a book anywhere on this window, or pick one from your computer.": "このウィンドウの好きな場所に本をドロップするか、コンピューターから選んでください。",
"Sign in to sync your library": "サインインしてライブラリーを同期"
}
@@ -102,7 +102,6 @@
"Updated": "업데이트일",
"Version {{version}}": "버전 {{version}}",
"Vertical Direction": "수직 방향",
"Welcome to your library. You can import your books here and read them anytime.": "내 서재에 오신 것을 환영합니다. 여기에서 책을 가져와 언제든지 읽을 수 있습니다.",
"Wikipedia": "위키피디아",
"Writing Mode": "글쓰기 모드",
"Your Library": "내 서재",
@@ -1384,5 +1383,9 @@
"Content Sources": "콘텐츠 소스",
"Scroll tabs": "탭 스크롤",
"Catalog actions": "카탈로그 작업",
"File Content": "파일 내용"
"File Content": "파일 내용",
"Start your library": "서재 만들기",
"Pick a book from your device to add it to your library.": "기기에서 책을 골라 서재에 추가하세요.",
"Drop a book anywhere on this window, or pick one from your computer.": "이 창의 아무 곳에나 책을 놓거나, 컴퓨터에서 골라 보세요.",
"Sign in to sync your library": "로그인하여 서재 동기화"
}
@@ -160,7 +160,6 @@
"Failed to delete cloud backup of the book: {{title}}": "Gagal memadam sandaran awan buku: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Gagal memadam salinan tempatan buku: {{title}}",
"Library Header": "Pengepala Perpustakaan",
"Welcome to your library. You can import your books here and read them anytime.": "Selamat datang ke perpustakaan anda. Anda boleh import buku anda di sini dan membacanya bila-bila masa.",
"Copied to notebook": "Disalin ke buku nota",
"No annotations to export": "Tiada anotasi untuk dieksport",
"Exported from Readest": "Dieksport dari Readest",
@@ -1384,5 +1383,9 @@
"Content Sources": "Sumber Kandungan",
"Scroll tabs": "Skrol tab",
"Catalog actions": "Tindakan katalog",
"File Content": "Kandungan fail"
"File Content": "Kandungan fail",
"Start your library": "Mulakan perpustakaan anda",
"Pick a book from your device to add it to your library.": "Pilih buku dari peranti anda untuk ditambahkan ke perpustakaan anda.",
"Drop a book anywhere on this window, or pick one from your computer.": "Lepaskan buku di mana-mana pada tetingkap ini, atau pilih satu dari komputer anda.",
"Sign in to sync your library": "Daftar masuk untuk menyegerakkan perpustakaan anda"
}
@@ -90,7 +90,6 @@
"Book deleted: {{title}}": "Boek verwijderd: {{title}}",
"Failed to delete book: {{title}}": "Verwijderen van boek mislukt: {{title}}",
"Your Library": "Uw bibliotheek",
"Welcome to your library. You can import your books here and read them anytime.": "Welkom bij uw bibliotheek. U kunt hier uw boeken importeren en ze op elk moment lezen.",
"Copied to notebook": "Gekopieerd naar notitieblok",
"No annotations to export": "Geen annotaties om te exporteren",
"Exported from Readest": "Geëxporteerd uit Readest",
@@ -1409,5 +1408,9 @@
"Content Sources": "Inhoudsbronnen",
"Scroll tabs": "Tabbladen scrollen",
"Catalog actions": "Catalogusacties",
"File Content": "Bestandsinhoud"
"File Content": "Bestandsinhoud",
"Start your library": "Begin je bibliotheek",
"Pick a book from your device to add it to your library.": "Kies een boek van je apparaat om aan je bibliotheek toe te voegen.",
"Drop a book anywhere on this window, or pick one from your computer.": "Sleep een boek ergens in dit venster, of kies er een van je computer.",
"Sign in to sync your library": "Meld je aan om je bibliotheek te synchroniseren"
}
@@ -102,7 +102,6 @@
"Updated": "Zaktualizowano",
"Version {{version}}": "Wersja {{version}}",
"Vertical Direction": "Kierunek pionowy",
"Welcome to your library. You can import your books here and read them anytime.": "Witaj w swojej bibliotece. Możesz tutaj zaimportować swoje książki i czytać je w dowolnym momencie.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Tryb pisania",
"Your Library": "Twoja biblioteka",
@@ -1459,5 +1458,9 @@
"Content Sources": "Źródła treści",
"Scroll tabs": "Przewiń karty",
"Catalog actions": "Akcje katalogu",
"File Content": "Zawartość pliku"
"File Content": "Zawartość pliku",
"Start your library": "Rozpocznij swoją bibliotekę",
"Pick a book from your device to add it to your library.": "Wybierz książkę z urządzenia, aby dodać ją do swojej biblioteki.",
"Drop a book anywhere on this window, or pick one from your computer.": "Upuść książkę w dowolnym miejscu tego okna lub wybierz ją z komputera.",
"Sign in to sync your library": "Zaloguj się, aby zsynchronizować bibliotekę"
}
@@ -256,7 +256,6 @@
"Library Header": "Cabeçalho da biblioteca",
"Library Sync Progress": "Progresso de sincronização da biblioteca",
"Your Bookshelf": "Sua estante",
"Welcome to your library. You can import your books here and read them anytime.": "Bem-vindo à sua biblioteca. Você pode importar seus livros aqui e lê-los a qualquer momento.",
"This link can't be opened": "Não foi possível abrir este link",
"The annotation link is missing required information. The original link may have been truncated.": "Faltam informações necessárias no link da anotação. O link original pode ter sido truncado.",
"Go to Readest": "Ir para o Readest",
@@ -1434,5 +1433,9 @@
"Content Sources": "Fontes de conteúdo",
"Scroll tabs": "Rolar abas",
"Catalog actions": "Ações do catálogo",
"File Content": "Conteúdo do arquivo"
"File Content": "Conteúdo do arquivo",
"Start your library": "Comece sua biblioteca",
"Pick a book from your device to add it to your library.": "Escolha um livro do seu dispositivo para adicionar à sua biblioteca.",
"Drop a book anywhere on this window, or pick one from your computer.": "Solte um livro em qualquer parte desta janela, ou escolha um do seu computador.",
"Sign in to sync your library": "Entre para sincronizar sua biblioteca"
}
@@ -102,7 +102,6 @@
"Updated": "Atualizado",
"Version {{version}}": "Versão {{version}}",
"Vertical Direction": "Direção Vertical",
"Welcome to your library. You can import your books here and read them anytime.": "Bem-vindo à sua biblioteca. Você pode importar seus livros aqui e lê-los a qualquer momento.",
"Wikipedia": "Wikipédia",
"Writing Mode": "Modo de Escrita",
"Your Library": "Sua Biblioteca",
@@ -1434,5 +1433,9 @@
"Content Sources": "Fontes de conteúdo",
"Scroll tabs": "Deslocar separadores",
"Catalog actions": "Ações do catálogo",
"File Content": "Conteúdo do ficheiro"
"File Content": "Conteúdo do ficheiro",
"Start your library": "Comece a sua biblioteca",
"Pick a book from your device to add it to your library.": "Escolha um livro do seu dispositivo para adicionar à sua biblioteca.",
"Drop a book anywhere on this window, or pick one from your computer.": "Largue um livro em qualquer parte desta janela, ou escolha um do seu computador.",
"Sign in to sync your library": "Inicie sessão para sincronizar a sua biblioteca"
}
@@ -233,7 +233,6 @@
"Library Header": "Antet bibliotecă",
"Library Sync Progress": "Progresul sincronizării bibliotecii",
"Your Bookshelf": "Raftul tău",
"Welcome to your library. You can import your books here and read them anytime.": "Bun venit la biblioteca dvs. Vă puteți importa cărțile aici și le puteți citi oricând.",
"URL must start with http:// or https://": "Adresa URL trebuie să înceapă cu http:// sau https://",
"Adding LAN addresses is not supported in the web app version.": "Adăugarea de adrese LAN nu este acceptată în versiunea aplicației web.",
"Invalid OPDS catalog. Please check the URL.": "Catalog OPDS nevalid. Vă rugăm să verificați adresa URL.",
@@ -1434,5 +1433,9 @@
"Content Sources": "Surse de conținut",
"Scroll tabs": "Derulează filele",
"Catalog actions": "Acțiuni catalog",
"File Content": "Conținutul fișierului"
"File Content": "Conținutul fișierului",
"Start your library": "Începe-ți biblioteca",
"Pick a book from your device to add it to your library.": "Alege o carte de pe dispozitiv pentru a o adăuga în biblioteca ta.",
"Drop a book anywhere on this window, or pick one from your computer.": "Lasă o carte oriunde în această fereastră sau alege una de pe computer.",
"Sign in to sync your library": "Conectează-te pentru a-ți sincroniza biblioteca"
}
@@ -102,7 +102,6 @@
"Updated": "Обновлено",
"Version {{version}}": "Версия {{version}}",
"Vertical Direction": "Вертикальное направление",
"Welcome to your library. You can import your books here and read them anytime.": "Добро пожаловать в вашу библиотеку. Вы можете импортировать сюда книги и читать их в любое время.",
"Wikipedia": "Википедия",
"Writing Mode": "Режим записи",
"Your Library": "Ваша библиотека",
@@ -1459,5 +1458,9 @@
"Content Sources": "Источники контента",
"Scroll tabs": "Прокрутить вкладки",
"Catalog actions": "Действия каталога",
"File Content": "Содержимое файла"
"File Content": "Содержимое файла",
"Start your library": "Создайте свою библиотеку",
"Pick a book from your device to add it to your library.": "Выберите книгу с устройства, чтобы добавить её в библиотеку.",
"Drop a book anywhere on this window, or pick one from your computer.": "Перетащите книгу в любое место этого окна или выберите её на компьютере.",
"Sign in to sync your library": "Войдите, чтобы синхронизировать библиотеку"
}
@@ -117,7 +117,6 @@
"Failed to delete book: {{title}}": "පොත මකා දැමීමට අසමත්: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "පොතේ cloud backup මකා දැමීමට අසමත්: {{title}}",
"Failed to delete local copy of the book: {{title}}": "පොතේ දේශීය පිටපත මකා දැමීමට අසමත්: {{title}}",
"Welcome to your library. You can import your books here and read them anytime.": "ඔබේ පුස්තකාලයට සාදරයෙන් පිළිගනිමු. ඔබට මෙහි ඔබේ පොත් ආයාත කර ඕනෑම වේලාවක කියවිය හැක.",
"Copied to notebook": "සටහන් පොතට පිටපත් කරන ලදී",
"No annotations to export": "නිර්යාත කිරීමට සටහන් නැත",
"Exported from Readest": "Readest වෙතින් නිර්යාත කරන ලදී",
@@ -1409,5 +1408,9 @@
"Content Sources": "අන්තර්ගත මූලාශ්‍ර",
"Scroll tabs": "ටැබ් අනුචලනය කරන්න",
"Catalog actions": "නාමාවලි ක්‍රියා",
"File Content": "ගොනුවේ අන්තර්ගතය"
"File Content": "ගොනුවේ අන්තර්ගතය",
"Start your library": "ඔබේ පුස්තකාලය ආරම්භ කරන්න",
"Pick a book from your device to add it to your library.": "ඔබේ පුස්තකාලයට එක් කිරීමට ඔබේ උපාංගයෙන් පොතක් තෝරන්න.",
"Drop a book anywhere on this window, or pick one from your computer.": "මෙම කවුළුවේ ඕනෑම තැනක පොතක් දමන්න, නැතහොත් ඔබේ පරිගණකයෙන් එකක් තෝරන්න.",
"Sign in to sync your library": "ඔබේ පුස්තකාලය සමමුහුර්ත කිරීමට පුරනය වන්න"
}
@@ -222,7 +222,6 @@
"Failed to delete local copy of the book: {{title}}": "Brisanje lokalne kopije knjige ni uspelo: {{title}}",
"Library Header": "Glava knjižnice",
"Library Sync Progress": "Napredek sinhronizacije knjižnice",
"Welcome to your library. You can import your books here and read them anytime.": "Dobrodošli v vaši knjižnici. Tukaj lahko uvozite svoje knjige in jih berete kadarkoli.",
"URL must start with http:// or https://": "URL se mora začeti s http:// ali https://",
"Adding LAN addresses is not supported in the web app version.": "Dodajanje naslovov LAN v različici spletne aplikacije ni podprto.",
"Invalid OPDS catalog. Please check the URL.": "Neveljaven OPDS katalog. Prosimo, preverite URL.",
@@ -1459,5 +1458,9 @@
"Content Sources": "Viri vsebin",
"Scroll tabs": "Drsenje zavihkov",
"Catalog actions": "Dejanja kataloga",
"File Content": "Vsebina datoteke"
"File Content": "Vsebina datoteke",
"Start your library": "Začnite svojo knjižnico",
"Pick a book from your device to add it to your library.": "Izberite knjigo iz svoje naprave, da jo dodate v svojo knjižnico.",
"Drop a book anywhere on this window, or pick one from your computer.": "Spustite knjigo kjer koli v tem oknu ali jo izberite iz svojega računalnika.",
"Sign in to sync your library": "Prijavite se za sinhronizacijo svoje knjižnice"
}
@@ -148,7 +148,6 @@
"Failed to delete cloud backup of the book: {{title}}": "Kunde inte radera molnkopia av bok: {{title}}",
"Failed to delete local copy of the book: {{title}}": "Kunde inte radera lokal kopia av bok: {{title}}",
"Library Header": "Bibliotekshuvud",
"Welcome to your library. You can import your books here and read them anytime.": "Välkommen till ditt bibliotek. Du kan importera dina böcker här och läsa dem när som helst.",
"Copied to notebook": "Kopierat till anteckningsbok",
"No annotations to export": "Inga anteckningar att exportera",
"Exported from Readest": "Exporterad från Readest",
@@ -1409,5 +1408,9 @@
"Content Sources": "Innehållskällor",
"Scroll tabs": "Bläddra mellan flikar",
"Catalog actions": "Katalogåtgärder",
"File Content": "Filinnehåll"
"File Content": "Filinnehåll",
"Start your library": "Starta ditt bibliotek",
"Pick a book from your device to add it to your library.": "Välj en bok från din enhet att lägga till i ditt bibliotek.",
"Drop a book anywhere on this window, or pick one from your computer.": "Släpp en bok var som helst på det här fönstret, eller välj en från din dator.",
"Sign in to sync your library": "Logga in för att synkronisera ditt bibliotek"
}
@@ -117,7 +117,6 @@
"Failed to delete book: {{title}}": "புத்தகத்தை நீக்க முடியவில்லை: {{title}}",
"Failed to delete cloud backup of the book: {{title}}": "புத்தகத்தின் cloud backup நீக்க முடியவில்லை: {{title}}",
"Failed to delete local copy of the book: {{title}}": "புத்தகத்தின் உள்ளூர் நகல் நீக்க முடியவில்லை: {{title}}",
"Welcome to your library. You can import your books here and read them anytime.": "உங்கள் நூலகத்திற்கு வரவேற்கிறோம். நீங்கள் இங்கே உங்கள் புத்தகங்களை இறக்குமதி செய்து எப்போது வேண்டுமானாலும் படிக்கலாம்.",
"Copied to notebook": "குறிப்பேட்டில் நகலெடுக்கப்பட்டது",
"No annotations to export": "ஏற்றுமதி செய்ய குறிப்புகள் இல்லை",
"Exported from Readest": "Readest இல் இருந்து ஏற்றுமதி செய்யப்பட்டது",
@@ -1409,5 +1408,9 @@
"Content Sources": "உள்ளடக்க மூலங்கள்",
"Scroll tabs": "தாவல்களை உருட்டவும்",
"Catalog actions": "பட்டியல் செயல்கள்",
"File Content": "கோப்பு உள்ளடக்கம்"
"File Content": "கோப்பு உள்ளடக்கம்",
"Start your library": "உங்கள் நூலகத்தைத் தொடங்குங்கள்",
"Pick a book from your device to add it to your library.": "உங்கள் நூலகத்தில் சேர்க்க உங்கள் சாதனத்திலிருந்து ஒரு புத்தகத்தைத் தேர்ந்தெடுக்கவும்.",
"Drop a book anywhere on this window, or pick one from your computer.": "இந்த சாளரத்தில் எங்கேனும் ஒரு புத்தகத்தை விடவும், அல்லது உங்கள் கணினியிலிருந்து ஒன்றைத் தேர்ந்தெடுக்கவும்.",
"Sign in to sync your library": "உங்கள் நூலகத்தை ஒத்திசைக்க உள்நுழையவும்"
}
@@ -110,7 +110,6 @@
"Book deleted: {{title}}": "ลบหนังสือแล้ว: {{title}}",
"Failed to delete book: {{title}}": "ไม่สามารถลบหนังสือ: {{title}}",
"Deleted cloud backup of the book: {{title}}": "ลบสำรองบนคลาวด์แล้ว: {{title}}",
"Welcome to your library. You can import your books here and read them anytime.": "ยินดีต้อนรับสู่คลังหนังสือ คุณสามารถนำเข้าหนังสือและอ่านได้ตลอดเวลา",
"Copied to notebook": "คัดลอกไปยังสมุดบันทึก",
"No annotations to export": "ไม่มีบันทึกให้ส่งออก",
"Exported from Readest": "ส่งออกจาก Readest",
@@ -1384,5 +1383,9 @@
"Content Sources": "แหล่งเนื้อหา",
"Scroll tabs": "เลื่อนแท็บ",
"Catalog actions": "การดำเนินการแคตตาล็อก",
"File Content": "เนื้อหาไฟล์"
"File Content": "เนื้อหาไฟล์",
"Start your library": "เริ่มต้นห้องสมุดของคุณ",
"Pick a book from your device to add it to your library.": "เลือกหนังสือจากอุปกรณ์ของคุณเพื่อเพิ่มลงในห้องสมุดของคุณ",
"Drop a book anywhere on this window, or pick one from your computer.": "วางหนังสือที่ใดก็ได้บนหน้าต่างนี้ หรือเลือกจากคอมพิวเตอร์ของคุณ",
"Sign in to sync your library": "ลงชื่อเข้าใช้เพื่อซิงค์ห้องสมุดของคุณ"
}
@@ -102,7 +102,6 @@
"Updated": "Güncellendi",
"Version {{version}}": "Sürüm {{version}}",
"Vertical Direction": "Dikey Yön",
"Welcome to your library. You can import your books here and read them anytime.": "Kütüphanenize hoş geldiniz. Buradan kitaplarınızı içe aktarabilir ve istediğiniz zaman okuyabilirsiniz.",
"Wikipedia": "Vikipedi",
"Writing Mode": "Yazma Modu",
"Your Library": "Kütüphaneniz",
@@ -1409,5 +1408,9 @@
"Content Sources": "İçerik kaynakları",
"Scroll tabs": "Sekmeleri kaydır",
"Catalog actions": "Katalog eylemleri",
"File Content": "Dosya içeriği"
"File Content": "Dosya içeriği",
"Start your library": "Kütüphanenizi başlatın",
"Pick a book from your device to add it to your library.": "Kütüphanenize eklemek için cihazınızdan bir kitap seçin.",
"Drop a book anywhere on this window, or pick one from your computer.": "Bu pencerede herhangi bir yere bir kitap bırakın veya bilgisayarınızdan birini seçin.",
"Sign in to sync your library": "Kütüphanenizi senkronize etmek için oturum açın"
}
@@ -102,7 +102,6 @@
"Updated": "Оновлено",
"Version {{version}}": "Версія {{version}}",
"Vertical Direction": "Вертикальний напрямок",
"Welcome to your library. You can import your books here and read them anytime.": "Ласкаво просимо до вашої бібліотеки. Ви можете імпортувати сюди свої книги та читати їх будь-коли.",
"Wikipedia": "Вікіпедія",
"Writing Mode": "Режим письма",
"Your Library": "Ваша бібліотека",
@@ -1459,5 +1458,9 @@
"Content Sources": "Джерела вмісту",
"Scroll tabs": "Прокрутити вкладки",
"Catalog actions": "Дії каталогу",
"File Content": "Вміст файлу"
"File Content": "Вміст файлу",
"Start your library": "Створіть свою бібліотеку",
"Pick a book from your device to add it to your library.": "Виберіть книжку з вашого пристрою, щоб додати її до бібліотеки.",
"Drop a book anywhere on this window, or pick one from your computer.": "Перетягніть книжку будь-куди у це вікно або виберіть її з комп’ютера.",
"Sign in to sync your library": "Увійдіть, щоб синхронізувати бібліотеку"
}
@@ -249,7 +249,6 @@
"Library Header": "Kutubxona sarlavhasi",
"Library Sync Progress": "Kutubxona sinxronlash jarayoni",
"Your Bookshelf": "Kitob javoningiz",
"Welcome to your library. You can import your books here and read them anytime.": "Kutubxonangizga xush kelibsiz. Bu yerga kitoblaringizni import qilib, istalgan vaqtda oʻqishingiz mumkin.",
"This link can't be opened": "Bu havolani ochib boʻlmadi",
"The annotation link is missing required information. The original link may have been truncated.": "Izoh havolasida kerakli maʼlumot yetishmaydi. Asl havola qisqartirilgan boʻlishi mumkin.",
"Go to Readest": "Readest-ga oʻtish",
@@ -1409,5 +1408,9 @@
"Content Sources": "Kontent manbalari",
"Scroll tabs": "Yorliqlarni aylantirish",
"Catalog actions": "Katalog amallari",
"File Content": "Fayl tarkibi"
"File Content": "Fayl tarkibi",
"Start your library": "Kutubxonangizni boshlang",
"Pick a book from your device to add it to your library.": "Kutubxonangizga qoshish uchun qurilmangizdan kitob tanlang.",
"Drop a book anywhere on this window, or pick one from your computer.": "Ushbu oynaning istalgan joyiga kitob tashlang yoki kompyuteringizdan birini tanlang.",
"Sign in to sync your library": "Kutubxonangizni sinxronlash uchun tizimga kiring"
}
@@ -102,7 +102,6 @@
"Updated": "Cập nhật",
"Version {{version}}": "Phiên bản {{version}}",
"Vertical Direction": "Hướng dọc",
"Welcome to your library. You can import your books here and read them anytime.": "Chào mừng đến với thư viện của bạn. Bạn có thể nhập sách vào đây và đọc bất cứ lúc nào.",
"Wikipedia": "Wikipedia",
"Writing Mode": "Chế độ viết",
"Your Library": "Thư viện của bạn",
@@ -1384,5 +1383,9 @@
"Content Sources": "Nguồn Nội dung",
"Scroll tabs": "Cuộn thẻ",
"Catalog actions": "Hành động danh mục",
"File Content": "Nội dung tệp"
"File Content": "Nội dung tệp",
"Start your library": "Bắt đầu thư viện của bạn",
"Pick a book from your device to add it to your library.": "Chọn một cuốn sách từ thiết bị để thêm vào thư viện của bạn.",
"Drop a book anywhere on this window, or pick one from your computer.": "Thả một cuốn sách vào bất kỳ đâu trên cửa sổ này, hoặc chọn một cuốn từ máy tính của bạn.",
"Sign in to sync your library": "Đăng nhập để đồng bộ thư viện của bạn"
}
@@ -103,7 +103,6 @@
"Updated": "更新日期",
"Version {{version}}": "版本 {{version}}",
"Vertical Direction": "竖排",
"Welcome to your library. You can import your books here and read them anytime.": "书库空空如也,您可以导入您的书籍并随时阅读。",
"Wikipedia": "维基百科",
"Writing Mode": "排版模式",
"Your Library": "书库",
@@ -1384,5 +1383,9 @@
"Content Sources": "内容来源",
"Scroll tabs": "滚动选项卡",
"Catalog actions": "目录操作",
"File Content": "文件内容"
"File Content": "文件内容",
"Start your library": "开启你的书库",
"Pick a book from your device to add it to your library.": "从设备中挑一本书加入书库吧。",
"Drop a book anywhere on this window, or pick one from your computer.": "把书拖到窗口任意位置,或从电脑中挑选一本。",
"Sign in to sync your library": "登录以同步书库"
}
@@ -102,7 +102,6 @@
"Updated": "更新日期",
"Version {{version}}": "版本 {{version}}",
"Vertical Direction": "豎排",
"Welcome to your library. You can import your books here and read them anytime.": "書庫空空如也,您可以導入您的書籍並隨時閱讀。",
"Wikipedia": "維基百科",
"Writing Mode": "排版模式",
"Your Library": "書庫",
@@ -1384,5 +1383,9 @@
"Content Sources": "內容來源",
"Scroll tabs": "捲動分頁",
"Catalog actions": "目錄操作",
"File Content": "檔案內容"
"File Content": "檔案內容",
"Start your library": "開啟你的書庫",
"Pick a book from your device to add it to your library.": "從裝置中挑一本書加入書庫吧。",
"Drop a book anywhere on this window, or pick one from your computer.": "把書拖到視窗任一處,或從電腦中挑選一本。",
"Sign in to sync your library": "登入以同步書庫"
}
@@ -0,0 +1,79 @@
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import LibraryEmptyState from '@/app/library/components/LibraryEmptyState';
vi.mock('@/hooks/useTranslation', () => ({
useTranslation: () => (key: string, options?: Record<string, string | number>) => {
if (!options) return key;
return key.replace(/{{(\w+)}}/g, (_match, name) => String(options[name] ?? ''));
},
}));
const useAuthMock = vi.fn();
vi.mock('@/context/AuthContext', () => ({
useAuth: () => useAuthMock(),
}));
const navigateToLoginMock = vi.fn();
const routerStub = { push: vi.fn(), replace: vi.fn(), back: vi.fn() };
vi.mock('@/hooks/useAppRouter', () => ({
useAppRouter: () => routerStub,
}));
vi.mock('@/utils/nav', () => ({
navigateToLogin: (...args: unknown[]) => navigateToLoginMock(...args),
}));
const useEnvMock = vi.fn();
vi.mock('@/context/EnvContext', () => ({
useEnv: () => useEnvMock(),
}));
afterEach(() => {
cleanup();
useAuthMock.mockReset();
navigateToLoginMock.mockReset();
useEnvMock.mockReset();
});
describe('LibraryEmptyState', () => {
it('renders title, desktop description, and both CTAs when logged out on desktop', () => {
useEnvMock.mockReturnValue({ appService: { isMobile: false } });
useAuthMock.mockReturnValue({ user: null });
render(<LibraryEmptyState onImport={vi.fn()} />);
expect(screen.getByRole('heading', { name: 'Start your library' })).toBeTruthy();
expect(screen.getByText(/drop a book anywhere on this window/i)).toBeTruthy();
expect(screen.getByRole('button', { name: 'Import Books' })).toBeTruthy();
expect(screen.getByRole('button', { name: 'Sign in to sync your library' })).toBeTruthy();
});
it('renders mobile description (no drag-drop language) when appService.isMobile', () => {
useEnvMock.mockReturnValue({ appService: { isMobile: true } });
useAuthMock.mockReturnValue({ user: null });
render(<LibraryEmptyState onImport={vi.fn()} />);
expect(screen.getByText(/pick a book from your device/i)).toBeTruthy();
expect(screen.queryByText(/drop a book anywhere on this window/i)).toBeNull();
});
it('hides the sync button when the user is logged in', () => {
useEnvMock.mockReturnValue({ appService: { isMobile: false } });
useAuthMock.mockReturnValue({ user: { id: 'stub-user' } });
render(<LibraryEmptyState onImport={vi.fn()} />);
expect(screen.getByRole('button', { name: 'Import Books' })).toBeTruthy();
expect(screen.queryByRole('button', { name: 'Sign in to sync your library' })).toBeNull();
});
it('calls onImport when the Import Books button is clicked', () => {
useEnvMock.mockReturnValue({ appService: { isMobile: false } });
useAuthMock.mockReturnValue({ user: null });
const handleImport = vi.fn();
render(<LibraryEmptyState onImport={handleImport} />);
fireEvent.click(screen.getByRole('button', { name: 'Import Books' }));
expect(handleImport).toHaveBeenCalledTimes(1);
});
});
@@ -0,0 +1,63 @@
import * as React from 'react';
import clsx from 'clsx';
import { PiBooks } from 'react-icons/pi';
import { useEnv } from '@/context/EnvContext';
import { useAuth } from '@/context/AuthContext';
import { useTranslation } from '@/hooks/useTranslation';
import { useAppRouter } from '@/hooks/useAppRouter';
import { navigateToLogin } from '@/utils/nav';
interface LibraryEmptyStateProps {
onImport: () => void;
}
const LibraryEmptyState: React.FC<LibraryEmptyStateProps> = ({ onImport }) => {
const _ = useTranslation();
const { appService } = useEnv();
const { user } = useAuth();
const router = useAppRouter();
const isMobile = appService?.isMobile ?? false;
return (
<div className='hero-content text-neutral-content text-center'>
<div className='flex max-w-md flex-col items-center'>
<PiBooks aria-hidden className='text-base-content/60 mb-10 size-16' />
<h1 className='mb-5 text-balance text-4xl font-semibold leading-tight tracking-tight'>
{_('Start your library')}
</h1>
<p className='text-base-content/70 mb-12 text-pretty text-base leading-relaxed'>
{isMobile
? _('Pick a book from your device to add it to your library.')
: _('Drop a book anywhere on this window, or pick one from your computer.')}
</p>
<div className='flex w-full max-w-xs flex-col gap-3'>
<button
type='button'
className='btn btn-primary h-11 min-h-11 rounded-lg'
onClick={onImport}
>
{_('Import Books')}
</button>
{/* TODO: add a 'Browse free catalogs' secondary action that opens the
OPDS dialog (handleShowOPDSDialog) once we settle on placement. */}
{!user && (
<button
type='button'
className={clsx(
'text-base-content/70 hover:text-base-content mt-1 py-2 text-sm font-medium',
'underline underline-offset-4',
'focus-visible:text-base-content focus-visible:outline-none',
)}
onClick={() => navigateToLogin(router)}
>
{_('Sign in to sync your library')}
</button>
)}
</div>
</div>
</div>
);
};
export default LibraryEmptyState;
+2 -13
View File
@@ -77,6 +77,7 @@ import {
import Spinner from '@/components/Spinner';
import LibraryHeader from './components/LibraryHeader';
import Bookshelf from './components/Bookshelf';
import LibraryEmptyState from './components/LibraryEmptyState';
import GroupHeader from './components/GroupHeader';
import useShortcuts from '@/hooks/useShortcuts';
import { useReplicaPull } from '@/hooks/useReplicaPull';
@@ -1013,19 +1014,7 @@ const LibraryPageContent = ({ searchParams }: { searchParams: ReadonlyURLSearchP
) : (
<div className='hero drop-zone h-screen items-center justify-center'>
<DropIndicator />
<div className='hero-content text-neutral-content text-center'>
<div className='max-w-md'>
<h1 className='mb-5 text-5xl font-bold'>{_('Your Library')}</h1>
<p className='mb-5'>
{_(
'Welcome to your library. You can import your books here and read them anytime.',
)}
</p>
<button className='btn btn-primary rounded-xl' onClick={handleImportBooksFromFiles}>
{_('Import Books')}
</button>
</div>
</div>
<LibraryEmptyState onImport={handleImportBooksFromFiles} />
</div>
))}
{showDetailsBook && (