feat: Hardcover→Directus book sync + fix empty states for projects/books
- Add POST /api/n8n/hardcover/sync-books — n8n calls this after detecting
finished books in Hardcover. Authenticates via N8N_SECRET_TOKEN/N8N_API_KEY,
deduplicates by hardcover_id, creates new book_reviews entries in Directus.
- Add getBookReviewByHardcoverId() + createBookReview() to lib/directus.ts.
Check uses GraphQL filter; create uses Directus REST POST /items/book_reviews.
- ReadBooks: replace silent return null with a visible empty state so the
section stays visible with a hint until the n8n sync populates it.
- Projects: add "No projects yet." placeholder instead of blank grid when
both Directus and PostgreSQL return no data.
- Add home.about.readBooks.empty i18n key (EN + DE).
n8n workflow setup:
Schedule → HTTP Hardcover GraphQL (books_read) → Code (transform) →
POST /api/n8n/hardcover/sync-books with array of { hardcover_id, title,
author, image, rating, finished_at }
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,10 @@ const Projects = () => {
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
) : projects.length === 0 ? (
|
||||
<div className="col-span-2 py-12 text-center text-stone-400 dark:text-stone-600 text-sm">
|
||||
No projects yet.
|
||||
</div>
|
||||
) : (
|
||||
projects.map((project) => (
|
||||
<motion.div
|
||||
|
||||
@@ -101,7 +101,12 @@ const ReadBooks = () => {
|
||||
}
|
||||
|
||||
if (reviews.length === 0) {
|
||||
return null; // Hier kannst du temporär "Keine Bücher gefunden" reinschreiben zum Testen
|
||||
return (
|
||||
<div className="flex items-center gap-3 py-4 text-sm text-stone-400 dark:text-stone-500">
|
||||
<BookCheck size={16} className="shrink-0" />
|
||||
<span>{t("empty")}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const visibleReviews = expanded ? reviews : reviews.slice(0, INITIAL_SHOW);
|
||||
|
||||
Reference in New Issue
Block a user