- Added a new script for database migration to the Docker image.
- Adjusted Dockerfile to create the scripts directory and copy the migration script with the correct permissions.
- Enhanced the Gitea deployment workflow to ensure the proxy network exists before starting the container.
- Enhanced the deployment script to better handle port conflicts by checking for both Docker containers and non-Docker processes using the specified health port.
- Added logic to wait for the port to be released and attempt to use an alternative port if the original is still in use after a timeout.
- Improved feedback messages for better clarity during the deployment process.
- Updated deployment script to check for existing containers and free ports before starting a new container.
- Added a new script to check the status of the Gitea runner, including service checks, running processes, Docker containers, common directories, and network connections.
- Add CurrentlyReading component with beautiful design
- Integrate into About section
- Add German and English translations
- Add n8n API route for Hardcover integration
- Add comprehensive documentation for n8n setup
Move hardcoded labels/strings in About, Projects, Contact form, Footer and Consent banner into next-intl message files (en/de) so content is maintained in one place.
Co-authored-by: dennis <dennis@konkol.net>
The app performs background polling/analytics, so networkidle can hang. Use domcontentloaded + short waits to reliably catch hydration errors.
Co-authored-by: dennis <dennis@konkol.net>
Do not decide consent during SSR. Read consent cookie after mount and only render the banner once consent is loaded, avoiding both hydration errors and the brief banner flash on reload.
Co-authored-by: dennis <dennis@konkol.net>
Initialize consent state from cookie synchronously so the banner only shows when no choice was made.
fix(api): fail-soft when DB schema missing
Return null/empty content for CMS endpoints when migrations are not applied instead of crashing with Prisma P2021/P2022.
fix(n8n): parse status response defensively
Handle empty/invalid JSON bodies from n8n to prevent activity feed from getting stuck.
Co-authored-by: dennis <dennis@konkol.net>
Adds a browser-level regression test ensuring the feed renders with the dark container and remains visible after a full reload.
Co-authored-by: dennis <dennis@konkol.net>
Import locale JSON messages directly in the [locale] layout to ensure DE pages render DE strings instead of falling back to EN.
Co-authored-by: dennis <dennis@konkol.net>
Use locale-prefixed <Link> elements for EN/DE so language switching works even when client-side hydration is broken.
Co-authored-by: dennis <dennis@konkol.net>
Switch locales via window.location.assign to guarantee the URL and messages update even if client-side router navigation is blocked.
Co-authored-by: dennis <dennis@konkol.net>
Stop setting NEXT_LOCALE cookie client-side and refresh after navigation, avoiding swallowed cookie errors that can prevent router.push from switching languages.
Co-authored-by: dennis <dennis@konkol.net>
Prevents middleware Edge runtime from failing on eval-based dev bundles when NODE_ENV is set to a non-standard value in the environment.
Co-authored-by: dennis <dennis@konkol.net>
Move ConsentBanner rendering into the locale layout so next-intl context is always available (prevents missing provider errors).
fix(activity-feed): use dark styling for disabled state
Avoid white disabled cards so the feed never appears as a white/transparent block after reload.
test(e2e): assert nav text changes on locale switch
Strengthen i18n test to verify translated labels.
Co-authored-by: dennis <dennis@konkol.net>
Use next-intl translations instead of reading NEXT_LOCALE cookie once, so banner text updates immediately when switching languages.
fix(activity-feed): make loading UI match dark theme
Avoid the white loading card on hard reload by using the same dark styling as the normal feed.
Co-authored-by: dennis <dennis@konkol.net>
Disable initial animations for the feed's fallback UIs so a hard reload can't leave the component stuck small/transparent before any state updates.
Co-authored-by: dennis <dennis@konkol.net>
Read tracking preference after mount instead of during initial render to prevent SSR/client divergence that can leave the feed stuck in its initial (small/transparent) styles after page reload.
Co-authored-by: dennis <dennis@konkol.net>
Make HomePage a server component and mount ActivityFeed via a client-only wrapper to avoid Suspense/dynamic boundary differences between SSR and hydration.
Avoid shared dev rate-limit bucket for n8n status and fall back to a stable offline state when the status call fails, preventing the widget from getting stuck in the small translucent loading UI.
feat(api): require session authentication for admin routes and improve error handling
fix(api): streamline project image generation by fetching data directly from the database
fix(api): optimize project import/export functionality with session validation and improved error handling
fix(api): enhance analytics dashboard and email manager with session token for admin requests
fix(components): improve loading states and dynamic imports for better user experience
chore(security): update Content Security Policy to avoid unsafe-eval in production
chore(deps): update package.json scripts for consistent environment handling in linting and testing
- Update Content Security Policy (CSP) in next.config.ts to avoid `unsafe-eval` in production, improving security against XSS attacks.
- Refactor API routes to enforce admin authentication and session validation, ensuring secure access to sensitive endpoints.
- Optimize analytics data retrieval by using database aggregation instead of loading all records into memory, improving performance and reducing memory usage.
- Implement session token creation and verification for better session management and security across the application.
- Enhance error handling and input validation in various API routes to ensure robustness and prevent potential issues.