Files
portfolio/messages/en.json
denshooter d7958b3841
All checks were successful
CI / CD / test-build (push) Successful in 11m5s
CI / CD / deploy-dev (push) Successful in 1m18s
CI / CD / deploy-production (push) Has been skipped
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>
2026-03-06 00:02:52 +01:00

164 lines
5.8 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"nav": {
"home": "Home",
"about": "About",
"projects": "Projects",
"contact": "Contact"
},
"common": {
"back": "Back",
"backToHome": "Back to Home",
"backToProjects": "Back to Projects",
"viewAllProjects": "View All Projects",
"loading": "Loading..."
},
"consent": {
"title": "Privacy settings",
"description": "We use optional services (analytics and chat) to improve the site. You can change your choice anytime.",
"essential": "Essential",
"analytics": "Analytics",
"chat": "Chatbot",
"alwaysOn": "Always on",
"acceptAll": "Accept all",
"acceptSelected": "Accept selected",
"rejectAll": "Reject all",
"hide": "Hide"
}
,
"home": {
"hero": {
"features": {
"f1": "Next.js & Flutter",
"f2": "Docker Swarm & CI/CD",
"f3": "Self-Hosted Infrastructure"
},
"description": "I'm Dennis a student from Germany and a passionate self-hoster. I build full-stack applications and love the challenge of managing the infrastructure they run on.",
"ctaWork": "View Projects",
"ctaContact": "Get in touch"
},
"about": {
"title": "Behind the Code",
"p1": "Ever since I set up my first home server, I've been hooked on infrastructure. Currently studying in Osnabrück, I split my time between developing modern web apps with Next.js and building mobile experiences with Flutter.",
"p2": "For me, it doesn't stop at the code. I genuinely enjoy managing my own Docker clusters, optimizing CI/CD pipelines, and making sure everything is stable and secure. DevOps isn't just a part of my job it's how I think about building things.",
"p3": "When the servers are running smoothly, you'll find me jogging through the city, gaming, or tinkering with new automation workflows in n8n.",
"funFactTitle": "Hardcore Analog",
"funFactBody": "Despite my love for automation and the cloud, my most important ideas are still born on paper with a fountain pen. It's my way of staying grounded.",
"techStackTitle": "My Tech Stack",
"hobbiesTitle": "When I'm Not Coding",
"techStack": {
"categories": {
"frontendMobile": "Frontend & Mobile",
"backendDevops": "Backend & DevOps",
"toolsAutomation": "Tools & Automation",
"securityAdmin": "Security & Admin"
},
"items": {
"selfHostedServices": "Self-hosted services"
}
},
"hobbies": {
"selfHosting": "Self-Hosting & DevOps",
"gaming": "Gaming",
"gameServers": "Setting up game servers",
"jogging": "Jogging to clear my mind and stay active"
},
"currentlyReading": {
"title": "Currently Reading",
"progress": "Progress"
},
"readBooks": {
"title": "Read",
"finishedAt": "Finished",
"showMore": "{count} more",
"showLess": "Show less",
"empty": "Books finished in Hardcover will appear here automatically."
},
"activity": {
"idleStatus": "System Idle / Mind Active",
"codingNow": "Coding Now",
"gaming": "Gaming",
"listening": "Listening",
"inGame": "In Game"
}
},
"projects": {
"title": "Selected Works",
"subtitle": "A collection of projects I've worked on, ranging from web applications to experiments.",
"featured": "Featured",
"viewAll": "View All Projects"
},
"contact": {
"title": "Contact Me",
"subtitle": "Interested in working together or have questions about my projects? Feel free to reach out!",
"getInTouch": "Get In Touch",
"getInTouchBody": "I'm always available to discuss new opportunities, interesting projects, or simply chat about technology and innovation.",
"info": {
"email": "Email",
"location": "Location",
"locationValue": "Osnabrück, Germany"
},
"form": {
"title": "Send Message",
"sending": "Sending message…",
"send": "Send Message",
"labels": {
"name": "Name",
"email": "Email",
"subject": "Subject",
"message": "Message",
"requiredMarker": "*"
},
"placeholders": {
"name": "Your name",
"email": "your@email.com",
"subject": "What's this about?",
"message": "Tell me more about your project or question…"
},
"errors": {
"nameRequired": "Name is required",
"nameMin": "Name must be at least 2 characters",
"emailRequired": "Email is required",
"emailInvalid": "Please enter a valid email address",
"subjectRequired": "Subject is required",
"subjectMin": "Subject must be at least 3 characters",
"messageRequired": "Message is required",
"messageMin": "Message must be at least 10 characters"
},
"characters": "{count} characters"
}
}
}
,
"projects": {
"shared": {
"featured": "Featured"
},
"list": {
"title": "My Projects",
"intro": "Explore my portfolio of projects, from web applications to mobile apps. Each project showcases different skills and technologies.",
"searchPlaceholder": "Search projects...",
"all": "All",
"noResults": "No projects found matching your criteria.",
"clearFilters": "Clear filters"
},
"detail": {
"links": "Project Links",
"liveDemo": "Live Demo",
"liveNotAvailable": "Live demo not available",
"viewSource": "View Source",
"techStack": "Tech Stack"
}
}
,
"footer": {
"role": "Software Engineer",
"madeIn": "Made in Germany",
"legalNotice": "Legal notice",
"privacyPolicy": "Privacy policy",
"privacySettings": "Privacy settings",
"privacySettingsTitle": "Show privacy settings banner again",
"builtWith": "Built with"
}
}