Skip to content

chore: upgrade packages and migrations#351

Merged
dmnktoe merged 2 commits into
mainfrom
refactor-infrastructure
Apr 20, 2026
Merged

chore: upgrade packages and migrations#351
dmnktoe merged 2 commits into
mainfrom
refactor-infrastructure

Conversation

@dmnktoe

@dmnktoe dmnktoe commented Apr 20, 2026

Copy link
Copy Markdown
Owner

Description & Technical Solution

Describe problems, if any, clearly and concisely.
Summarize the impact to the system.
Please also include relevant motivation and context.
Please include a summary of the technical solution and how it solves the problem.

Checklist

  • I have commented my code, particularly in hard-to-understand areas.
  • Already rebased against main branch.

Screenshots

Provide screenshots or videos of the changes made if any.

Summary by CodeRabbit

  • New Features

    • Enhanced globe visualization with location badges highlighting key distribution markets.
    • Improved metadata across all pages for better search visibility.
  • Improvements

    • Upgraded core frameworks: Next.js, React, and Tailwind CSS (v4) for enhanced performance and compatibility.
  • Removed

    • TextReveal animation component.

@vercel

vercel Bot commented Apr 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
duecker-medizintechnik Ready Ready Preview, Comment Apr 20, 2026 2:27am

@dmnktoe dmnktoe changed the title chore: upgrade packages nad migrations chore: upgrade packages and migrations Apr 20, 2026
@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Warning

Rate limit exceeded

@dmnktoe has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 35 minutes and 58 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 35 minutes and 58 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8dd9db3c-d713-4e78-bc78-857b3b494af2

📥 Commits

Reviewing files that changed from the base of the PR and between d349955 and dfbc451.

📒 Files selected for processing (15)
  • .stylelintrc.json
  • src/app/[locale]/datenschutz/page.tsx
  • src/app/[locale]/newsroom/[slug]/page.tsx
  • src/app/[locale]/not-found.tsx
  • src/app/layout.tsx
  • src/components/templates/CompanyView.tsx
  • src/components/templates/DistributionOptic.tsx
  • src/components/templates/Globe.tsx
  • src/components/templates/Hero.tsx
  • src/components/templates/NewsCard.tsx
  • src/components/ui/Accordion.tsx
  • src/lib/fonts.ts
  • src/lib/site-page-metadata.ts
  • src/styles/globals.css
  • tailwind.config.ts
📝 Walkthrough

Walkthrough

Comprehensive upgrade of ESLint configuration to flat config format, Tailwind CSS v3 to v4, and Next.js/React framework versions. Includes image import path conversions to aliases, SEO metadata consolidation via new helper function, and removal of TextReveal component.

Changes

Cohort / File(s) Summary
ESLint & TypeScript Configuration
.eslintignore, .eslintrc.js, eslint.config.mjs, tsconfig.json
Migrated from .eslintrc.js to flat config format (eslint.config.mjs), removed node_modules ignore entry, and updated TypeScript target from ES5 to ES2017 with bundler module resolution and react-jsx support.
Tailwind & PostCSS Configuration
tailwind.config.ts, postcss.config.js, src/styles/globals.css
Upgraded Tailwind v3 to v4: moved plugins to global CSS via @plugin directives, removed plugin entries from config, updated PostCSS to use @tailwindcss/postcss, and migrated to v4 directive syntax.
Package Dependencies
package.json
Updated Next.js, React, TypeScript, ESLint, and related toolchain packages; upgraded Tailwind v3 to v4; modified lint script from next lint to eslint src.
Next.js Configuration
next.config.js
Removed ESLint directory configuration block (eslint.dirs).
SEO Metadata Consolidation
src/lib/site-page-metadata.ts, src/constants/services-page-hero.ts
Added new sitePageMetadata helper function and SitePageOgImage type for unified Open Graph/Twitter metadata generation; updated services page hero to use new type.
Page Metadata Refactoring
src/app/[locale]/*/page.tsx, src/app/[locale]/not-found.tsx, src/app/layout.tsx
Refactored generateMetadata exports across 15+ page components to use sitePageMetadata wrapper; updated root layout metadata with new title template and expanded description.
Service Page Component Renaming
src/components/templates/ProduktionLeistungenView.tsx, src/components/templates/ReparaturLeistungenView.tsx
Renamed exported components: ProduktionContentProduktionLeistungenView, ReparaturContentReparaturLeistungenView.
Image Import Path Conversions
src/components/templates/..., src/constants/services-page-hero.ts, and related files
Converted image imports from absolute /public/... paths to ~/images/... alias across 20+ component files.
Component Feature Updates
src/components/templates/Bento.tsx, src/components/templates/Globe.tsx, src/components/templates/distributionGlobeConfig.ts
Added distribution globe configuration with marker/arc definitions; extended Globe component to support anchorLabels for CSS anchor badges; refactored Bento tile to use new DistributionBentoGlobe wrapper with feature detection for anchor support.
Removed Components
src/components/templates/TextReveal.tsx, src/components/__tests__/TextReveal.test.tsx
Removed TextReveal component and its test suite; removed TextReveal rendering from downloads page.
German Locale Content
public/locales/de/*.json (15 files)
Updated SEO titles and descriptions across company, contact, distribution, downloads, home, imprint, news, notFound, privacy, production, repair, services, and termsAndConditions pages; added globeBadges to home page; removed textReveal from downloads.
English Locale Content
public/locales/en/*.json (15 files)
Parallel SEO metadata updates to English translations; updated titles/descriptions to focus on services and company positioning; added globeBadges to home page; removed textReveal from downloads; added fallbackArticleTitle to news.
Tailwind Class Reordering
60+ component files across src/components/
Reordered Tailwind utility classes across layout, header, template, and UI components for consistency; all changes are cosmetic class string reordering without functional impact.
Consent & Helper Utilities
src/components/helpers/ConsentProvider.tsx, src/components/helpers/consent/*.tsx, src/lib/google-analytics.ts, src/lib/i18n-testing.ts
Removed debug option from consent provider; updated Google Analytics calls to use optional chaining; converted i18n testing to use async dynamic imports instead of require.
Test & Type Updates
src/components/__tests__/*.test.tsx, src/lib/__tests__/helper.test.ts, src/types/globals.d.ts
Removed ESLint suppression comments from tests; updated test assertions for OG image URL parsing; added Swiper and GTM type declarations.

Sequence Diagram(s)

sequenceDiagram
    participant Browser as Browser/Client
    participant Page as Page Component
    participant Meta as sitePageMetadata()
    participant OG as og-image Handler
    participant CDN as Image CDN/API
    
    Browser->>Page: Request page
    Page->>Page: getTranslations()
    Page->>Meta: sitePageMetadata({title, description, alternates, openGraphImages?})
    
    alt openGraphImages provided
        Meta->>Meta: Normalize image URLs
        Meta->>Meta: Build OpenGraph metadata
    else no custom images
        Meta->>OG: Generate default /api/og?title=...&description=...
        OG->>CDN: Build 1200x630 image
        CDN-->>OG: Image URL
        OG-->>Meta: Return image URL
        Meta->>Meta: Build OpenGraph with generated image
    end
    
    Meta-->>Page: Return Metadata object
    Page-->>Browser: Send page + metadata headers
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • chore: replace cookiebot with c15t #334: Modifies consent provider code and related consent management behavior in overlapping files (src/components/helpers/ConsentProvider.tsx), sharing direct code-level integration with this PR's consent provider updates.

Poem

🐰 Hops with delight at the grand refactor day!
ESLint flat configs and Tailwind's new way,
Classes reordered, metadata refined,
Globe badges gleaming, sweet logic redesigned!
Onward we bound, the code shines so bright!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is entirely templated with no actual content filled in. All required sections (problem description, impact summary, motivation/context, technical solution, checklist items) remain as placeholder text. Fill in the description template with concrete details: what problems were addressed, what packages were upgraded and why, the impact on the system, and confirmation of code review readiness (commenting, rebasing).
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: upgrade packages and migrations' accurately summarizes the main objective of the changeset, which involves upgrading dependencies and making infrastructure migrations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-infrastructure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sentry

sentry Bot commented Apr 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 30.00000% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.06%. Comparing base (9a15b4a) to head (dfbc451).

Files with missing lines Patch % Lines
src/components/templates/Globe.tsx 9.67% 28 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #351      +/-   ##
==========================================
- Coverage   81.66%   80.06%   -1.61%     
==========================================
  Files          88       87       -1     
  Lines         960      963       +3     
  Branches      232      243      +11     
==========================================
- Hits          784      771      -13     
- Misses        176      192      +16     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (1)
eslint.config.mjs (1)

40-45: Stylistic rules conflict with Prettier.

no-multi-spaces, object-curly-spacing, and quotes are exactly the kinds of stylistic rules that eslint-config-prettier disables to avoid conflicts. Because this custom block is applied after eslintConfigPrettier and prettierRecommended, these rules are re-enabled and will fight Prettier on autofix (e.g., single vs. double quotes in JSX attrs, spacing). Recommend removing them and letting Prettier own formatting.

♻️ Proposed diff
     rules: {
       'no-console': 'warn',
-      'no-multi-spaces': 'error',
       '@typescript-eslint/explicit-module-boundary-types': 'off',
       '@typescript-eslint/no-unused-vars': 'off',
       'react/no-unescaped-entities': 'off',
-      'object-curly-spacing': ['warn', 'always'],
-      quotes: ['warn', 'single', { avoidEscape: true }],
       'react/display-name': 'off',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.mjs` around lines 40 - 45, The listed stylistic ESLint rules
('no-multi-spaces', 'object-curly-spacing', and 'quotes') conflict with Prettier
because this custom block runs after eslint-config-prettier and
prettierRecommended; remove or disable those three rules (or set them to 'off')
so Prettier controls formatting, leaving only non-formatting/semantic rules
(e.g., keep '@typescript-eslint/explicit-module-boundary-types' or
'@typescript-eslint/no-unused-vars' as appropriate) in the same config block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eslint.config.mjs`:
- Around line 10-20: globalIgnores pattern currently only excludes '*.config.js'
so config files with other extensions are still linted; update the pattern
passed to globalIgnores (the globalIgnores([...]) call) to include other config
file extensions such as .cjs, .mjs, and .ts by replacing the single
'*.config.js' entry with a glob like '**/*.config.{js,cjs,mjs,ts}' so
tailwind.config.ts, sentry.*.config.ts, eslint.config.mjs, etc. are ignored by
ESLint.

In `@public/locales/en/imprint.json`:
- Around line 47-48: Update the "title" value in the imprint locale entry to use
the same separator style as other page titles (replace the em dash in the
"title" string "Legal notice — provider details and disclaimers" with a colon or
hyphen to match company.json); locate the "title" key in
public/locales/en/imprint.json and change the separator character only, keeping
the rest of the text identical so localization keys remain consistent.

In `@src/app/`[locale]/newsroom/[slug]/page.tsx:
- Around line 38-43: The page component still dereferences posts.data[0] and can
crash for invalid slugs; update the PostPage rendering logic to mirror
generateMetadata by checking for a missing post (inspect post or posts.data[0])
and call Next.js notFound() (or return the same site-level fallback) instead of
proceeding, ensuring PostPage (the component that uses posts/posts.data[0])
never dereferences when post is undefined.

In `@src/app/`[locale]/not-found.tsx:
- Around line 14-18: The not-found metadata currently sets alternates via
getAlternates('/', locale) which points hreflang links to the site root; update
the not-found.tsx metadata generation (sitePageMetadata call) to omit or clear
the alternates field for the 404 page (remove or set alternates to
undefined/null) so the generated not-found page does not advertise localized
home URLs, or alternatively supply a true routable 404-equivalent path if you
intend language-specific 404 pages; modify the sitePageMetadata(...) invocation
in not-found.tsx and remove/getAlternates usage accordingly.

In `@src/components/layout/Footer.tsx`:
- Line 170: The LanguagePicker's interactive element in Footer.tsx currently
suppresses all focus indicators by using className with focus:ring-0,
focus:ring-transparent, focus:ring-offset-0, focus:ring-offset-transparent,
focus:ring-inset and focus:outline-none; remove the redundant/conflicting
focus-suppression classes from that className and instead apply a clear visible
focus style (for example use Tailwind's focus-visible:ring and
focus-visible:ring-offset with an accessible color) either on the LanguagePicker
element itself or on its parent container so keyboard users see a focus
indicator; update the className string used for the LanguagePicker element to
drop the suppression classes and add the appropriate focus-visible utilities.
- Line 161: In the Footer component's language picker element (in
src/components/layout/Footer.tsx) replace the Tailwind class 'focus:outline-0'
with 'focus:outline-2' so the focus styling reads 'focus:outline-2
focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed'; update the
class string on the language picker/select element in the Footer component to
ensure a visible dashed focus ring for keyboard users.

In `@src/components/templates/Globe.tsx`:
- Around line 143-155: Replace the truthy check that uses
pointerInteracting.current with an explicit null/undefined check so a numeric 0
(valid drag state) doesn't slip through; specifically, in the tick function
change if (!pointerInteracting.current) { phiRef.current += 0.005; } to if
(pointerInteracting.current == null) { phiRef.current += 0.005; } so
auto-rotation only runs when pointerInteracting is truly unset, leaving symbols:
pointerInteracting, phiRef, tick, requestAnimationFrame, and globe.update
unchanged.
- Around line 184-198: The portals are being keyed on the child <div> instead of
on the portal itself, which prevents proper reconciliation; update the map over
anchorLabels so the key is passed as the third argument to createPortal (use
label.markerId as the key) and remove the key prop from the div element; modify
the call around createPortal(...) in the block that uses globeHost,
anchorLabels, createPortal, and anchorBadgeStyle so the portal receives the key
and the child div no longer has a key attribute.

In `@src/components/templates/NewsCard.tsx`:
- Line 39: The Tailwind v4 utility group-hover:bg-opacity-10 is removed; update
the div in NewsCard (the element with class 'group-hover:bg-opacity-10 absolute
top-0 left-0 h-full w-full group-hover:bg-white') to use the slash-based opacity
modifier by replacing the combined classes with a single color/opacity class
(e.g., use group-hover:bg-white/10) and remove the deprecated bg-opacity-*
token, and scan for any other usages of bg-opacity-*, text-opacity-* or
border-opacity-* and convert them to the color/opacity syntax (color/opacity) to
match Tailwind v4.

In `@src/components/ui/Accordion.tsx`:
- Line 14: The Accordion component is hardcoding a light border class in the JSX
where className is set (className={clsx('border-b border-gray-200',
className)}); change that to use the semantic/tokenized border class or omit the
explicit color so themes can control it — e.g., replace 'border-gray-200' with
'border-border' or just use 'border-b' and let the incoming/class-level styles
determine color; update the same className expression in Accordion.tsx
accordingly.

In `@src/styles/globals.css`:
- Around line 1-4: Stylelint is flagging Tailwind v4 at-rules (`@config` and
`@plugin`) as unknown; update your Stylelint config (.stylelintrc.json) to allow
these by adding "at-rule-no-unknown": [true, { "ignoreAtRules": ["config",
"plugin", "tailwind", "apply", "variants", "responsive", "screen"] }] or
alternatively switch to a Tailwind-aware preset; edit the at-rule-no-unknown
rule (or replace with a preset) so `@config` and `@plugin` used in
src/styles/globals.css are recognized.

---

Nitpick comments:
In `@eslint.config.mjs`:
- Around line 40-45: The listed stylistic ESLint rules ('no-multi-spaces',
'object-curly-spacing', and 'quotes') conflict with Prettier because this custom
block runs after eslint-config-prettier and prettierRecommended; remove or
disable those three rules (or set them to 'off') so Prettier controls
formatting, leaving only non-formatting/semantic rules (e.g., keep
'@typescript-eslint/explicit-module-boundary-types' or
'@typescript-eslint/no-unused-vars' as appropriate) in the same config block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 541952bf-2f55-4a03-84f1-27246e9c1444

📥 Commits

Reviewing files that changed from the base of the PR and between 9a15b4a and d349955.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (119)
  • .eslintignore
  • .eslintrc.js
  • eslint.config.mjs
  • next.config.js
  • package.json
  • postcss.config.js
  • public/locales/de/company.json
  • public/locales/de/contact.json
  • public/locales/de/distribution.json
  • public/locales/de/downloads.json
  • public/locales/de/home.json
  • public/locales/de/imprint.json
  • public/locales/de/news.json
  • public/locales/de/notFound.json
  • public/locales/de/privacy.json
  • public/locales/de/production.json
  • public/locales/de/repair.json
  • public/locales/de/services.json
  • public/locales/de/termsAndConditions.json
  • public/locales/en/company.json
  • public/locales/en/contact.json
  • public/locales/en/distribution.json
  • public/locales/en/downloads.json
  • public/locales/en/home.json
  • public/locales/en/imprint.json
  • public/locales/en/news.json
  • public/locales/en/notFound.json
  • public/locales/en/privacy.json
  • public/locales/en/production.json
  • public/locales/en/repair.json
  • public/locales/en/services.json
  • public/locales/en/termsAndConditions.json
  • src/app/[locale]/agb/page.tsx
  • src/app/[locale]/cookie-richtlinie/page.tsx
  • src/app/[locale]/datenschutz/page.tsx
  • src/app/[locale]/downloads/page.tsx
  • src/app/[locale]/impressum/page.tsx
  • src/app/[locale]/kontakt/page.tsx
  • src/app/[locale]/leistungen/page.tsx
  • src/app/[locale]/leistungen/produktion/page.tsx
  • src/app/[locale]/leistungen/reparatur/page.tsx
  • src/app/[locale]/leistungen/vertrieb/page.tsx
  • src/app/[locale]/newsroom/[slug]/page.tsx
  • src/app/[locale]/newsroom/page.tsx
  • src/app/[locale]/not-found.tsx
  • src/app/[locale]/page.tsx
  • src/app/[locale]/unternehmen/page.tsx
  • src/app/layout.tsx
  • src/components/__tests__/Collapsible.test.tsx
  • src/components/__tests__/CookieConsentConditional.test.tsx
  • src/components/__tests__/TextReveal.test.tsx
  • src/components/helpers/ConsentProvider.tsx
  • src/components/helpers/consent/ConsentCategoryToggles.tsx
  • src/components/helpers/consent/ConsentSurfaces.tsx
  • src/components/layout/Footer.tsx
  • src/components/layout/InfoBar.tsx
  • src/components/layout/header/DesktopNav.tsx
  • src/components/layout/header/Header.tsx
  • src/components/layout/header/LeistungenMegaMenu.tsx
  • src/components/layout/header/MobileNavDrawer.tsx
  • src/components/templates/Bento.tsx
  • src/components/templates/CallToAction.tsx
  • src/components/templates/CompanyView.tsx
  • src/components/templates/ContactDecorators.tsx
  • src/components/templates/ContactForm.tsx
  • src/components/templates/ContactInfo.tsx
  • src/components/templates/ContactView.tsx
  • src/components/templates/CookieControlCenter.tsx
  • src/components/templates/CookiePolicyVendorList.tsx
  • src/components/templates/DistributionConsult.tsx
  • src/components/templates/DistributionIntro.tsx
  • src/components/templates/DistributionOptic.tsx
  • src/components/templates/DistributionProducts.tsx
  • src/components/templates/DownloadCenter.tsx
  • src/components/templates/Features.tsx
  • src/components/templates/Globe.tsx
  • src/components/templates/Hero.tsx
  • src/components/templates/Marquee.tsx
  • src/components/templates/NewsArticle.tsx
  • src/components/templates/NewsCard.tsx
  • src/components/templates/NewsSlider.tsx
  • src/components/templates/NotFound.tsx
  • src/components/templates/PrivacyContent.tsx
  • src/components/templates/ProductionIntro.tsx
  • src/components/templates/ProductionTiles.tsx
  • src/components/templates/ProduktionLeistungenView.tsx
  • src/components/templates/RepairSlideshow.tsx
  • src/components/templates/ReparaturLeistungenView.tsx
  • src/components/templates/ServicePageTiles.tsx
  • src/components/templates/ServicesView.tsx
  • src/components/templates/StickyScroll/StickyScroll.tsx
  • src/components/templates/StickyScroll/StickyScrollTitle.tsx
  • src/components/templates/TextReveal.tsx
  • src/components/templates/distributionGlobeConfig.ts
  • src/components/ui/Accordion.tsx
  • src/components/ui/Badges/AnimatedBadge.tsx
  • src/components/ui/Badges/Badge.tsx
  • src/components/ui/Buttons/Button.tsx
  • src/components/ui/Buttons/IconButton.tsx
  • src/components/ui/Buttons/MobileMenuButton.tsx
  • src/components/ui/Buttons/SliderButton.tsx
  • src/components/ui/Buttons/TextButton.tsx
  • src/components/ui/Checkbox.tsx
  • src/components/ui/Links/ButtonLink.tsx
  • src/components/ui/Links/IconLink.tsx
  • src/components/ui/Links/PrimaryLink.tsx
  • src/components/ui/Links/UnderlineLink.tsx
  • src/components/ui/RadixCheckbox.tsx
  • src/components/ui/Switch.tsx
  • src/components/ui/Typography/Title.tsx
  • src/constants/services-page-hero.ts
  • src/lib/__tests__/helper.test.ts
  • src/lib/google-analytics.ts
  • src/lib/i18n-testing.ts
  • src/lib/site-page-metadata.ts
  • src/styles/globals.css
  • src/types/globals.d.ts
  • tailwind.config.ts
  • tsconfig.json
💤 Files with no reviewable changes (9)
  • .eslintignore
  • src/components/tests/Collapsible.test.tsx
  • src/components/helpers/ConsentProvider.tsx
  • .eslintrc.js
  • src/components/tests/TextReveal.test.tsx
  • tailwind.config.ts
  • next.config.js
  • src/components/tests/CookieConsentConditional.test.tsx
  • src/components/templates/TextReveal.tsx

Comment thread eslint.config.mjs
Comment on lines +10 to +20
globalIgnores([
'**/node_modules/**',
'.next/**',
'out/**',
'build/**',
'coverage/**',
'public/**',
'next-env.d.ts',
'*.config.js',
'next-sitemap.config.js',
]),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
fd -H -t f -E node_modules -E .next '\.config\.(js|cjs|mjs|ts)$'

Repository: dmnktoe/duecker-medizintechnik

Length of output: 272


Expand globalIgnores pattern to cover config files with non-.js extensions.

Config files with .ts and .mjs extensions exist in the repo (tailwind.config.ts, sentry.client.config.ts, sentry.edge.config.ts, sentry.server.config.ts, eslint.config.mjs), but the pattern '*.config.js' won't match them. Use **/*.config.{js,cjs,mjs,ts} to ensure all config files are excluded from linting.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.mjs` around lines 10 - 20, globalIgnores pattern currently only
excludes '*.config.js' so config files with other extensions are still linted;
update the pattern passed to globalIgnores (the globalIgnores([...]) call) to
include other config file extensions such as .cjs, .mjs, and .ts by replacing
the single '*.config.js' entry with a glob like '**/*.config.{js,cjs,mjs,ts}' so
tailwind.config.ts, sentry.*.config.ts, eslint.config.mjs, etc. are ignored by
ESLint.

Comment on lines +47 to +48
"description": "Legal notice and provider information for Dücker Medizintechnik in Melsungen, Germany (German legal requirements).",
"title": "Legal notice — provider details and disclaimers"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: em dash in <title> may render inconsistently.

The em dash () in "Legal notice — provider details and disclaimers" is fine semantically but some SERP snippets/social cards prefer a simple hyphen or colon for consistency with other page titles in this PR (which use : — see company.json). Consider aligning the separator style across locales for a uniform SEO presentation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@public/locales/en/imprint.json` around lines 47 - 48, Update the "title"
value in the imprint locale entry to use the same separator style as other page
titles (replace the em dash in the "title" string "Legal notice — provider
details and disclaimers" with a colon or hyphen to match company.json); locate
the "title" key in public/locales/en/imprint.json and change the separator
character only, keeping the rest of the text identical so localization keys
remain consistent.

Comment thread src/app/[locale]/newsroom/[slug]/page.tsx Outdated
Comment thread src/app/[locale]/not-found.tsx
className={clsxm(
'order-first items-center justify-center bg-gray-100 p-2 align-middle lg:order-last lg:p-3',
'focus:outline-dashed focus:outline-0 focus:outline-offset-4 focus:outline-gray-300',
'focus:outline-0 focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Tailwind CSS v4 outline utilities: does outline-0disableoutline-dashed?

💡 Result:

No, outline-0 does not disable outline-dashed in Tailwind CSS v4. Outline utilities are independent and target different CSS properties: outline-0 sets outline-width: 0px (from v3 docs, and v4 supports arbitrary/small widths via outline-[] or spacing scale), while outline-dashed sets outline-style: dashed. A zero-width outline with dashed style renders nothing visible, but the style is still applied and not disabled—other utilities like outline-offset-2 or outline-{color} would still function. Tailwind v4 uses CSS variables like --tw-outline-style (default solid) for composition, so later classes override earlier ones without disabling unrelated properties. Examples in official docs combine width (outline-2), style (outline-dashed), offset, and color without conflict.

Citations:


🏁 Script executed:

# Check if the file exists and read the relevant section
if [ -f "src/components/layout/Footer.tsx" ]; then
  echo "=== File exists, checking line 161 context ==="
  sed -n '150,170p' src/components/layout/Footer.tsx
else
  echo "File not found, checking for Footer files"
  find . -name "Footer.tsx" -o -name "Footer.ts" -o -name "Footer.jsx" -o -name "Footer.js" 2>/dev/null | head -20
fi

Repository: dmnktoe/duecker-medizintechnik

Length of output: 1037


Remove focus:outline-0 — it creates an invisible focus ring for keyboard users.

focus:outline-0 sets the outline width to 0, making the dashed outline (with offset and color) invisible on focus. This is a keyboard accessibility issue for the language picker. Replace with focus:outline-2 to render a visible dashed focus indicator:

Suggested fix
-          'focus:outline-0 focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed',
+          'focus:outline-2 focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'focus:outline-0 focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed',
'focus:outline-2 focus:outline-offset-4 focus:outline-gray-300 focus:outline-dashed',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/layout/Footer.tsx` at line 161, In the Footer component's
language picker element (in src/components/layout/Footer.tsx) replace the
Tailwind class 'focus:outline-0' with 'focus:outline-2' so the focus styling
reads 'focus:outline-2 focus:outline-offset-4 focus:outline-gray-300
focus:outline-dashed'; update the class string on the language picker/select
element in the Footer component to ensure a visible dashed focus ring for
keyboard users.

Comment thread src/components/templates/Globe.tsx
Comment on lines +184 to +198
{globeHost && anchorLabels?.length
? anchorLabels.map((label) =>
createPortal(
<div
key={label.markerId}
style={anchorBadgeStyle(label.markerId)}
className={clsxm(
'border-primary-300/40 bg-primary-950/80 text-primary-50 inline-block rounded-full border px-2.5 py-1 text-center text-[10px] leading-tight font-semibold whitespace-nowrap shadow-lg backdrop-blur-md sm:px-3 sm:text-xs',
)}
>
{label.children}
</div>,
globeHost,
),
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's verify the file exists and check the code at those lines
head -198 src/components/templates/Globe.tsx | tail -30

Repository: dmnktoe/duecker-medizintechnik

Length of output: 1269


🌐 Web query:

React createPortal API signature third argument key parameter

💡 Result:

The React createPortal API signature is createPortal(children, domNode, key?). The third argument is an optional key parameter, described as "optional key: A unique string or number to be used as the portal's key." This key helps React identify the portal for reconciliation purposes when multiple portals are rendered in the same parent component.

Citations:


Move the key from the child element to createPortal's third argument.

When mapping portals, the key must be passed as createPortal's third argument, not on the child element. Per React's official API reference, the signature is createPortal(children, domNode, key?), and the key is used for proper portal reconciliation when rendering multiple portals.

♻️ Proposed fix
         ? anchorLabels.map((label) =>
             createPortal(
               <div
-                key={label.markerId}
                 style={anchorBadgeStyle(label.markerId)}
                 className={clsxm(
                   'border-primary-300/40 bg-primary-950/80 text-primary-50 inline-block rounded-full border px-2.5 py-1 text-center text-[10px] leading-tight font-semibold whitespace-nowrap shadow-lg backdrop-blur-md sm:px-3 sm:text-xs',
                 )}
               >
                 {label.children}
               </div>,
               globeHost,
+              label.markerId,
             ),
           )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{globeHost && anchorLabels?.length
? anchorLabels.map((label) =>
createPortal(
<div
key={label.markerId}
style={anchorBadgeStyle(label.markerId)}
className={clsxm(
'border-primary-300/40 bg-primary-950/80 text-primary-50 inline-block rounded-full border px-2.5 py-1 text-center text-[10px] leading-tight font-semibold whitespace-nowrap shadow-lg backdrop-blur-md sm:px-3 sm:text-xs',
)}
>
{label.children}
</div>,
globeHost,
),
)
{globeHost && anchorLabels?.length
? anchorLabels.map((label) =>
createPortal(
<div
style={anchorBadgeStyle(label.markerId)}
className={clsxm(
'border-primary-300/40 bg-primary-950/80 text-primary-50 inline-block rounded-full border px-2.5 py-1 text-center text-[10px] leading-tight font-semibold whitespace-nowrap shadow-lg backdrop-blur-md sm:px-3 sm:text-xs',
)}
>
{label.children}
</div>,
globeHost,
label.markerId,
),
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/templates/Globe.tsx` around lines 184 - 198, The portals are
being keyed on the child <div> instead of on the portal itself, which prevents
proper reconciliation; update the map over anchorLabels so the key is passed as
the third argument to createPortal (use label.markerId as the key) and remove
the key prop from the div element; modify the call around createPortal(...) in
the block that uses globeHost, anchorLabels, createPortal, and anchorBadgeStyle
so the portal receives the key and the child div no longer has a key attribute.

Comment thread src/components/templates/NewsCard.tsx Outdated
Comment thread src/components/ui/Accordion.tsx Outdated
Comment thread src/styles/globals.css
@dmnktoe dmnktoe merged commit f0819db into main Apr 20, 2026
10 checks passed
@dmnktoe dmnktoe deleted the refactor-infrastructure branch April 20, 2026 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant