Compare commits
7 Commits
v2.2.13-rc
...
v2.2.13-rc
| Author | SHA1 | Date | |
|---|---|---|---|
| 9de5f2938b | |||
| de41a0e29d | |||
| 6689dd3013 | |||
| 31fbcb32dd | |||
| 68eca73df2 | |||
| 3bb6eb3447 | |||
| a3c732dd13 |
1
.turbo/41698960411f6bf6-manifest.json
Normal file
1
.turbo/41698960411f6bf6-manifest.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"files":{".turbo/turbo-test.log":{"size":2776,"mtime_nanos":1781469605328811961,"mode":420,"is_dir":false}},"order":[".turbo/turbo-test.log"]}
|
||||||
1
.turbo/41698960411f6bf6-meta.json
Normal file
1
.turbo/41698960411f6bf6-meta.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"hash":"41698960411f6bf6","duration":4168,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}
|
||||||
BIN
.turbo/41698960411f6bf6.tar.zst
Normal file
BIN
.turbo/41698960411f6bf6.tar.zst
Normal file
Binary file not shown.
1
.turbo/bb46018d4a7bc516-manifest.json
Normal file
1
.turbo/bb46018d4a7bc516-manifest.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"files":{".turbo/turbo-lint.log":{"size":12987,"mtime_nanos":1781469609469080321,"mode":420,"is_dir":false}},"order":[".turbo/turbo-lint.log"]}
|
||||||
1
.turbo/bb46018d4a7bc516-meta.json
Normal file
1
.turbo/bb46018d4a7bc516-meta.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"hash":"bb46018d4a7bc516","duration":8307,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}
|
||||||
BIN
.turbo/bb46018d4a7bc516.tar.zst
Normal file
BIN
.turbo/bb46018d4a7bc516.tar.zst
Normal file
Binary file not shown.
1
.turbo/eb4eeeb717c1af0c-manifest.json
Normal file
1
.turbo/eb4eeeb717c1af0c-manifest.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"files":{".turbo/turbo-typecheck.log":{"size":85,"mtime_nanos":1781469608726900998,"mode":420,"is_dir":false}},"order":[".turbo/turbo-typecheck.log"]}
|
||||||
1
.turbo/eb4eeeb717c1af0c-meta.json
Normal file
1
.turbo/eb4eeeb717c1af0c-meta.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"hash":"eb4eeeb717c1af0c","duration":7565,"sha":"a3c732dd133b1b8261b19cf64b3bf684e269e839","dirty_hash":"1ef3b75af417f41468b9558671572e75e0fc055f9dbe6e805cfa6f59b1cddf70"}
|
||||||
BIN
.turbo/eb4eeeb717c1af0c.tar.zst
Normal file
BIN
.turbo/eb4eeeb717c1af0c.tar.zst
Normal file
Binary file not shown.
@@ -18,12 +18,17 @@
|
|||||||
6:10 warning 'Terminal' is defined but never used @typescript-eslint/no-unused-vars
|
6:10 warning 'Terminal' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/[slug]/page.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/[slug]/page.tsx
|
||||||
92:26 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
118:26 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
|
|
||||||
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/page.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/referenzen/page.tsx
|
||||||
1:21 warning 'Heading' is defined but never used @typescript-eslint/no-unused-vars
|
1:21 warning 'Heading' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
1:30 warning 'Badge' is defined but never used @typescript-eslint/no-unused-vars
|
1:30 warning 'Badge' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Volumes/Alpha SSD/Coding/e-tib.com/app/[locale]/standorte/[slug]/page.tsx
|
||||||
|
9:10 warning 'getButtonClasses' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
9:28 warning 'ButtonOverlay' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
58:9 warning 't' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
/Volumes/Alpha SSD/Coding/e-tib.com/components/JsonLd.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/components/JsonLd.tsx
|
||||||
1:30 warning 'Graph' is defined but never used @typescript-eslint/no-unused-vars
|
1:30 warning 'Graph' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
43:31 warning '_' is assigned a value but never used @typescript-eslint/no-unused-vars
|
43:31 warning '_' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
@@ -76,14 +81,17 @@ Calling setState synchronously within an effect body causes cascading renders th
|
|||||||
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/InteractiveGermanyMap.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/InteractiveGermanyMap.tsx
|
||||||
5:18 warning 'Factory' is defined but never used @typescript-eslint/no-unused-vars
|
5:18 warning 'Factory' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
5:27 warning 'Zap' is defined but never used @typescript-eslint/no-unused-vars
|
5:27 warning 'Zap' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
53:9 warning 'hq' is assigned a value but never used @typescript-eslint/no-unused-vars
|
56:9 warning 'hq' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
54:9 warning 'branch' is assigned a value but never used @typescript-eslint/no-unused-vars
|
57:9 warning 'branch' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
55:9 warning 'projects' is assigned a value but never used @typescript-eslint/no-unused-vars
|
58:9 warning 'projects' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
56:9 warning 'minorNodes' is assigned a value but never used @typescript-eslint/no-unused-vars
|
59:9 warning 'minorNodes' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/ReferencesSlider.test.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/ReferencesSlider.test.tsx
|
||||||
5:10 warning 'NextIntlClientProvider' is defined but never used @typescript-eslint/no-unused-vars
|
20:12 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
21:12 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
|
||||||
|
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/SubCompanyTiles.tsx
|
||||||
|
92:19 warning 'CardWrapper' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
|
93:19 warning 'wrapperProps' is assigned a value but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/TeamGridBlock.tsx
|
/Volumes/Alpha SSD/Coding/e-tib.com/components/blocks/TeamGridBlock.tsx
|
||||||
20:39 warning 'title' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
|
20:39 warning 'title' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
@@ -124,6 +132,15 @@ Calling setState synchronously within an effect body causes cascading renders th
|
|||||||
94:7 warning 'next' is never reassigned. Use 'const' instead prefer-const
|
94:7 warning 'next' is never reassigned. Use 'const' instead prefer-const
|
||||||
95:7 warning 'prev' is never reassigned. Use 'const' instead prefer-const
|
95:7 warning 'prev' is never reassigned. Use 'const' instead prefer-const
|
||||||
|
|
||||||
✖ 45 problems (0 errors, 45 warnings)
|
/Volumes/Alpha SSD/Coding/e-tib.com/lib/standorte-data.ts
|
||||||
|
1:10 warning 'LucideIcon' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:22 warning 'MapPin' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:30 warning 'Building2' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:41 warning 'HardHat' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:50 warning 'Phone' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:57 warning 'Mail' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
1:63 warning 'Navigation' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
✖ 56 problems (0 errors, 56 warnings)
|
||||||
0 errors and 2 warnings potentially fixable with the `--fix` option.
|
0 errors and 2 warnings potentially fixable with the `--fix` option.
|
||||||
|
|
||||||
|
|||||||
@@ -5,27 +5,33 @@
|
|||||||
|
|
||||||
[1m[46m RUN [49m[22m [36mv4.1.2 [39m[90m/Volumes/Alpha SSD/Coding/e-tib.com[39m
|
[1m[46m RUN [49m[22m [36mv4.1.2 [39m[90m/Volumes/Alpha SSD/Coding/e-tib.com[39m
|
||||||
|
|
||||||
[32m✓[39m tests/mdx-links.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
(node:74132) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead.
|
||||||
[32m✓[39m lib/mail/mailer.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 2[2mms[22m[39m
|
(Use `node --trace-deprecation ...` to show where the warning was created)
|
||||||
[32m✓[39m lib/env.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
[32m✓[39m tests/homepage-and-competence-content.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
||||||
|
[32m✓[39m tests/task-12-links.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
|
||||||
|
[32m✓[39m tests/mdx-links.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 11[2mms[22m[39m
|
||||||
|
[32m✓[39m tests/legal-pages.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
||||||
|
[32m✓[39m tests/messen-content.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 30[2mms[22m[39m
|
||||||
|
[32m✓[39m lib/mail/mailer.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 4[2mms[22m[39m
|
||||||
|
[32m✓[39m components/search/AISearchResults.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 25[2mms[22m[39m
|
||||||
[90mstderr[2m | components/layout/LanguageSwitcher.test.tsx[2m > [22m[2mLanguageSwitcher TDD[2m > [22m[2mtranslates /en/trade-fairs to /de/messen when switching to German
|
[90mstderr[2m | components/layout/LanguageSwitcher.test.tsx[2m > [22m[2mLanguageSwitcher TDD[2m > [22m[2mtranslates /en/trade-fairs to /de/messen when switching to German
|
||||||
[22m[39mReact does not recognize the `transitionMessage` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `transitionmessage` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
|
[22m[39mReact does not recognize the `transitionMessage` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `transitionmessage` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
|
||||||
|
|
||||||
[32m✓[39m components/layout/LanguageSwitcher.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 21[2mms[22m[39m
|
[32m✓[39m components/layout/LanguageSwitcher.test.tsx [2m([22m[2m5 tests[22m[2m)[22m[32m 26[2mms[22m[39m
|
||||||
[32m✓[39m components/search/AISearchResults.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 26[2mms[22m[39m
|
[32m✓[39m lib/env.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
||||||
[90mstderr[2m | components/blocks/ReferencesSlider.test.tsx[2m > [22m[2mReferencesSlider TDD[2m > [22m[2mrenders reference tiles correctly
|
[90mstderr[2m | components/blocks/ReferencesSlider.test.tsx[2m > [22m[2mReferencesSlider TDD[2m > [22m[2mrenders reference tiles correctly
|
||||||
[22m[39mReceived `true` for a non-boolean attribute `fill`.
|
[22m[39mReceived `true` for a non-boolean attribute `fill`.
|
||||||
|
|
||||||
If you want to write it to the DOM, pass a string instead: fill="true" or fill={value.toString()}.
|
If you want to write it to the DOM, pass a string instead: fill="true" or fill={value.toString()}.
|
||||||
|
|
||||||
[32m✓[39m components/blocks/ReferencesSlider.test.tsx [2m([22m[2m4 tests[22m[2m)[22m[32m 40[2mms[22m[39m
|
[32m✓[39m components/blocks/ReferencesSlider.test.tsx [2m([22m[2m2 tests[22m[2m)[22m[32m 43[2mms[22m[39m
|
||||||
[90mstdout[2m | app/[locale]/referenzen/[slug]/page.test.tsx
|
[90mstdout[2m | app/[locale]/referenzen/[slug]/page.test.tsx
|
||||||
[22m[39m[Config] Initializing Toggles: { feedbackEnabled: [33mfalse[39m }
|
[22m[39m[Config] Initializing Toggles: { feedbackEnabled: [33mfalse[39m }
|
||||||
|
|
||||||
[32m✓[39m app/[locale]/referenzen/[slug]/page.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
|
[32m✓[39m app/[locale]/referenzen/[slug]/page.test.tsx [2m([22m[2m1 test[22m[2m)[22m[32m 7[2mms[22m[39m
|
||||||
|
|
||||||
[2m Test Files [22m [1m[32m7 passed[39m[22m[90m (7)[39m
|
[2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
|
||||||
[2m Tests [22m [1m[32m19 passed[39m[22m[90m (19)[39m
|
[2m Tests [22m [1m[32m27 passed[39m[22m[90m (27)[39m
|
||||||
[2m Start at [22m 14:12:48
|
[2m Start at [22m 22:40:02
|
||||||
[2m Duration [22m 1.80s[2m (transform 863ms, setup 0ms, import 2.94s, tests 105ms, environment 3.18s)[22m
|
[2m Duration [22m 2.69s[2m (transform 2.09s, setup 0ms, import 4.45s, tests 179ms, environment 8.10s)[22m
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import TrackedLink from '@/components/analytics/TrackedLink';
|
|||||||
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
|
import { getButtonClasses, ButtonOverlay } from '@/components/ui/Button';
|
||||||
import { getAllReferences } from '@/lib/references';
|
import { getAllReferences } from '@/lib/references';
|
||||||
import { defaultLocations, minorLocations } from '@/lib/map-data';
|
import { defaultLocations, minorLocations } from '@/lib/map-data';
|
||||||
|
import { standorteLocations } from '@/lib/standorte-data';
|
||||||
// Import components used in MDX
|
// Import components used in MDX
|
||||||
import { HeroVideo as HomeHero } from '@/components/blocks/HeroVideo';
|
import { HeroVideo as HomeHero } from '@/components/blocks/HeroVideo';
|
||||||
import { SubCompanyTiles as HomeSubCompanyTiles } from '@/components/blocks/SubCompanyTiles';
|
import { SubCompanyTiles as HomeSubCompanyTiles } from '@/components/blocks/SubCompanyTiles';
|
||||||
@@ -153,7 +153,7 @@ export default async function Page(props: { params: Promise<{ locale: string; sl
|
|||||||
|
|
||||||
// Fetch references to enrich the map if it's used
|
// Fetch references to enrich the map if it's used
|
||||||
const references = await getAllReferences(locale);
|
const references = await getAllReferences(locale);
|
||||||
const allLocations = [...defaultLocations, ...minorLocations];
|
const allLocations = [...standorteLocations, ...defaultLocations, ...minorLocations];
|
||||||
const enrichedLocations = allLocations.map(loc => {
|
const enrichedLocations = allLocations.map(loc => {
|
||||||
if (loc.type === 'project') {
|
if (loc.type === 'project') {
|
||||||
const ref = references.find(r => r.slug === loc.id);
|
const ref = references.find(r => r.slug === loc.id);
|
||||||
|
|||||||
@@ -92,9 +92,9 @@ export default async function Layout(props: {
|
|||||||
url: `/${safeLocale}/${await mapFileSlugToTranslated('ueber-uns', safeLocale)}`,
|
url: `/${safeLocale}/${await mapFileSlugToTranslated('ueber-uns', safeLocale)}`,
|
||||||
children: [
|
children: [
|
||||||
{ label: safeLocale === 'de' ? 'Firma' : 'Company', url: `/${safeLocale}/${await mapFileSlugToTranslated('ueber-uns', safeLocale)}` },
|
{ label: safeLocale === 'de' ? 'Firma' : 'Company', url: `/${safeLocale}/${await mapFileSlugToTranslated('ueber-uns', safeLocale)}` },
|
||||||
{ label: safeLocale === 'de' ? 'Standorte' : 'Locations', url: `/${safeLocale}/standorte` },
|
|
||||||
{ label: safeLocale === 'de' ? 'Unser Team' : 'Our Team', url: `/${safeLocale}/team` },
|
{ label: safeLocale === 'de' ? 'Unser Team' : 'Our Team', url: `/${safeLocale}/team` },
|
||||||
{ label: safeLocale === 'de' ? 'Zertifikate' : 'Certificates', url: `/${safeLocale}/zertifikate` }
|
{ label: safeLocale === 'de' ? 'Zertifikate' : 'Certificates', url: `/${safeLocale}/zertifikate` },
|
||||||
|
{ label: safeLocale === 'de' ? 'Standorte' : 'Locations', url: `/${safeLocale}/standorte` }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Container } from '@/components/ui';
|
import { Container, Badge, Heading } from '@/components/ui';
|
||||||
import { getTranslations, setRequestLocale } from 'next-intl/server';
|
import { getTranslations, setRequestLocale } from 'next-intl/server';
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
@@ -63,21 +63,29 @@ export default async function StandortDetail(props: { params: Promise<{ locale:
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col min-h-screen bg-neutral-50 pb-16 md:pb-24 pt-32">
|
<div className="flex flex-col min-h-screen bg-neutral-50 pb-16 md:pb-24">
|
||||||
<Container>
|
{/* Industrial Hero Section */}
|
||||||
{/* Header Section */}
|
<section className="bg-primary-dark text-white pt-40 pb-12 md:pt-48 md:pb-16 min-h-[40vh] md:min-h-[45vh] flex flex-col justify-end relative overflow-hidden">
|
||||||
<div className="mb-12 md:mb-16">
|
<div className="absolute inset-0 opacity-20 pointer-events-none">
|
||||||
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-primary/10 border border-primary/20 text-primary text-xs font-bold uppercase tracking-wider mb-6">
|
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent/50 via-transparent to-transparent" />
|
||||||
<MapPin className="w-4 h-4" />
|
|
||||||
<span>{standort.type === 'hq' ? (safeLocale === 'de' ? 'Hauptsitz' : 'Headquarters') : (safeLocale === 'de' ? 'Niederlassung' : 'Branch')}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<h1 className="font-heading text-4xl lg:text-5xl xl:text-6xl font-extrabold mb-6 leading-[1.1] text-neutral-dark text-balance">
|
<Container className="relative z-10">
|
||||||
|
<div className="max-w-4xl">
|
||||||
|
<Badge variant="accent" className="mb-4 md:mb-6 shadow-sm flex inline-flex items-center gap-2">
|
||||||
|
<MapPin className="w-4 h-4" />
|
||||||
|
{standort.type === 'hq' ? (safeLocale === 'de' ? 'Hauptsitz' : 'Headquarters') : (safeLocale === 'de' ? 'Niederlassung' : 'Branch')}
|
||||||
|
</Badge>
|
||||||
|
<Heading level={1} variant="white" className="mb-6 drop-shadow-sm">
|
||||||
{standort.name}
|
{standort.name}
|
||||||
</h1>
|
</Heading>
|
||||||
<p className="text-xl text-neutral-500 max-w-3xl leading-relaxed">
|
<p className="text-xl md:text-2xl text-white/80 max-w-3xl leading-relaxed font-medium">
|
||||||
{standort.description[safeLocale]}
|
{standort.description[safeLocale]}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<Container className="relative z-20 mt-12 md:mt-16">
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12">
|
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 lg:gap-12">
|
||||||
{/* Main Content (Images & Description) */}
|
{/* Main Content (Images & Description) */}
|
||||||
@@ -149,8 +157,12 @@ export default async function StandortDetail(props: { params: Promise<{ locale:
|
|||||||
{standort.address.street}<br />
|
{standort.address.street}<br />
|
||||||
{standort.address.city}
|
{standort.address.city}
|
||||||
</div>
|
</div>
|
||||||
|
{(() => {
|
||||||
|
const baseUrl = 'https://maps.google.com/';
|
||||||
|
const mapsUrl = `${baseUrl}?q=${encodeURIComponent(`${standort.address.street}, ${standort.address.city}`)}`;
|
||||||
|
return (
|
||||||
<TrackedLink
|
<TrackedLink
|
||||||
href={`https://maps.google.com/?q=${encodeURIComponent(`${standort.address.street}, ${standort.address.city}`)}`}
|
href={mapsUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="inline-flex items-center gap-1 mt-2 text-primary hover:text-white transition-colors text-sm font-bold"
|
className="inline-flex items-center gap-1 mt-2 text-primary hover:text-white transition-colors text-sm font-bold"
|
||||||
@@ -159,6 +171,8 @@ export default async function StandortDetail(props: { params: Promise<{ locale:
|
|||||||
{safeLocale === 'de' ? 'In Google Maps öffnen' : 'Open in Google Maps'}
|
{safeLocale === 'de' ? 'In Google Maps öffnen' : 'Open in Google Maps'}
|
||||||
<ArrowUpRight className="w-3.5 h-3.5" />
|
<ArrowUpRight className="w-3.5 h-3.5" />
|
||||||
</TrackedLink>
|
</TrackedLink>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default async function StandorteOverview(props: { params: Promise<{ local
|
|||||||
badge={safeLocale === 'en' ? 'Our Locations' : 'Unsere Standorte'}
|
badge={safeLocale === 'en' ? 'Our Locations' : 'Unsere Standorte'}
|
||||||
title={safeLocale === 'en' ? 'Nationwide operational for you.' : 'Deutschlandweit für Sie im Einsatz.'}
|
title={safeLocale === 'en' ? 'Nationwide operational for you.' : 'Deutschlandweit für Sie im Einsatz.'}
|
||||||
description={safeLocale === 'en'
|
description={safeLocale === 'en'
|
||||||
? 'From our strategic locations in Guben, Kirchheilingen, and Bülstedt, we control and implement complex infrastructure projects nationwide.'
|
? 'From our strategic locations in Guben, Kirchheilingen and Bülstedt, we control and implement complex infrastructure projects nationwide.'
|
||||||
: 'Von unseren strategischen Standorten in Guben, Kirchheilingen und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.'}
|
: 'Von unseren strategischen Standorten in Guben, Kirchheilingen und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export function InteractiveGermanyMap({
|
|||||||
const finalBadge = badge || tStandard('badge');
|
const finalBadge = badge || tStandard('badge');
|
||||||
// the map is mostly used with specific props, so we leave title & description to fallbacks if not provided
|
// the map is mostly used with specific props, so we leave title & description to fallbacks if not provided
|
||||||
const finalTitle = title || (locale === 'en' ? <>Nationwide<br/>in operation for you.</> : <>Deutschlandweit<br/>für Sie im Einsatz.</>);
|
const finalTitle = title || (locale === 'en' ? <>Nationwide<br/>in operation for you.</> : <>Deutschlandweit<br/>für Sie im Einsatz.</>);
|
||||||
const finalDescription = description || (locale === 'en' ? 'From our strategic locations in Guben and Bülstedt, we control and implement complex infrastructure projects nationwide.' : 'Von unseren strategischen Standorten in Guben und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.');
|
const finalDescription = description || (locale === 'en' ? 'From our strategic locations in Guben, Kirchheilingen and Bülstedt, we control and implement complex infrastructure projects nationwide.' : 'Von unseren strategischen Standorten in Guben, Kirchheilingen und Bülstedt steuern und realisieren wir komplexe Infrastrukturprojekte im gesamten Bundesgebiet.');
|
||||||
|
|
||||||
const hq = locations.find((l) => l.type === 'hq');
|
const hq = locations.find((l) => l.type === 'hq');
|
||||||
const branch = locations.find((l) => l.type === 'branch');
|
const branch = locations.find((l) => l.type === 'branch');
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface NavLink {
|
|||||||
label: string;
|
label: string;
|
||||||
url: string;
|
url: string;
|
||||||
children?: NavLink[];
|
children?: NavLink[];
|
||||||
|
isGroupLabel?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HeaderProps {
|
interface HeaderProps {
|
||||||
@@ -218,11 +219,20 @@ function NavItem({ link, currentLocale, pathname, isSolidMode }: { link: NavLink
|
|||||||
{/* Top glowing accent line */}
|
{/* Top glowing accent line */}
|
||||||
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-primary to-transparent opacity-70" />
|
<div className="absolute top-0 left-0 w-full h-[2px] bg-gradient-to-r from-transparent via-primary to-transparent opacity-70" />
|
||||||
|
|
||||||
{link.children.map((child) => {
|
{link.children.map((child, idx) => {
|
||||||
const childUrl = child.url.startsWith('/') && !child.url.match(/^\/(en|de)/)
|
const childUrl = child.url.startsWith('/') && !child.url.match(/^\/(en|de)/)
|
||||||
? `/${currentLocale}${child.url}`
|
? `/${currentLocale}${child.url}`
|
||||||
: child.url;
|
: child.url;
|
||||||
const isChildActive = pathname === childUrl;
|
const isChildActive = pathname === childUrl;
|
||||||
|
|
||||||
|
if (child.isGroupLabel) {
|
||||||
|
return (
|
||||||
|
<div key={`group-${idx}`} className={`mt-2 mb-1 px-4 text-[11px] font-bold uppercase tracking-wider ${isSolidMode ? 'text-neutral-400' : 'text-neutral-500'}`}>
|
||||||
|
{child.label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TransitionLink
|
<TransitionLink
|
||||||
key={child.url}
|
key={child.url}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Grabenlose Leitungsverlegung"
|
title: "Bohrtechnik"
|
||||||
date: "2024-03-20"
|
date: "2024-03-20"
|
||||||
excerpt: "Präzise Horizontalspülbohrungen und Erdraketen in allen Bodenklassen für eine absolut oberflächenschonende und effiziente Leitungsverlegung."
|
excerpt: "Präzise Horizontalspülbohrungen und Erdraketen in allen Bodenklassen für eine absolut oberflächenschonende und effiziente Leitungsverlegung."
|
||||||
layout: "fullBleed"
|
layout: "fullBleed"
|
||||||
@@ -7,8 +7,8 @@ layout: "fullBleed"
|
|||||||
|
|
||||||
<HeroSection
|
<HeroSection
|
||||||
badge="Kernkompetenz"
|
badge="Kernkompetenz"
|
||||||
title="Grabenlose Verlegung"
|
title="Bohrtechnik"
|
||||||
subtitle="Oberflächenschonende Horizontalspülbohrungen und Erdraketen"
|
subtitle="Grabenlose Leitungsverlegung, Horizontalspülbohrungen und Erdraketen"
|
||||||
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
|
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
|
||||||
alignment="center"
|
alignment="center"
|
||||||
ctaLabel="Projekt anfragen"
|
ctaLabel="Projekt anfragen"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ description: "Die E-TIB GmbH ist Ihr zuverlässiger Partner für komplexe Kabelt
|
|||||||
title: "E-TIB Bohrtechnik GmbH",
|
title: "E-TIB Bohrtechnik GmbH",
|
||||||
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
||||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||||
url: "/de/standorte/kirchheilingen",
|
url: "/de/bohrtechnik",
|
||||||
backgroundImage: "/assets/photos/DSC08653.JPG"
|
backgroundImage: "/assets/photos/DSC08653.JPG"
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ layout: "fullBleed"
|
|||||||
title: "E-TIB Bohrtechnik GmbH",
|
title: "E-TIB Bohrtechnik GmbH",
|
||||||
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
description: "Präzise Horizontalspülbohrungen in allen Bodenklassen für eine oberflächenschonende und grabenlose Leitungsverlegung.",
|
||||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||||
url: "/de/standorte/kirchheilingen",
|
url: "/de/bohrtechnik",
|
||||||
backgroundImage: "/assets/photos/DSC08653.JPG"
|
backgroundImage: "/assets/photos/DSC08653.JPG"
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "Trenchless Line Laying"
|
title: "Drilling Technology"
|
||||||
date: "2024-03-20"
|
date: "2024-03-20"
|
||||||
excerpt: "Precise horizontal directional drilling and earth rockets in all soil classes for surface-friendly and efficient line laying."
|
excerpt: "Precise horizontal directional drilling and earth rockets in all soil classes for surface-friendly and efficient line laying."
|
||||||
layout: "fullBleed"
|
layout: "fullBleed"
|
||||||
@@ -7,8 +7,8 @@ layout: "fullBleed"
|
|||||||
|
|
||||||
<HeroSection
|
<HeroSection
|
||||||
badge="Core Competency"
|
badge="Core Competency"
|
||||||
title="Trenchless Laying"
|
title="Drilling Technology"
|
||||||
subtitle="Surface-friendly horizontal directional drilling and earth rockets"
|
subtitle="Trenchless Laying, horizontal directional drilling and earth rockets"
|
||||||
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
|
backgroundImage={{ url: '/assets/photos/DSC08653.JPG' }}
|
||||||
alignment="center"
|
alignment="center"
|
||||||
ctaLabel="Request a project"
|
ctaLabel="Request a project"
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ description: "E-TIB GmbH is your reliable partner for complex cable routes, hori
|
|||||||
title: "E-TIB Bohrtechnik GmbH",
|
title: "E-TIB Bohrtechnik GmbH",
|
||||||
description: "Precise horizontal directional drilling in all soil classes for surface-friendly and trenchless pipe laying.",
|
description: "Precise horizontal directional drilling in all soil classes for surface-friendly and trenchless pipe laying.",
|
||||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||||
url: "/en/standorte/kirchheilingen",
|
url: "/en/drilling-technology",
|
||||||
backgroundImage: "/assets/photos/DSC08653.JPG"
|
backgroundImage: "/assets/photos/DSC08653.JPG"
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ layout: "fullBleed"
|
|||||||
title: "E-TIB Bohrtechnik GmbH",
|
title: "E-TIB Bohrtechnik GmbH",
|
||||||
description: "Precise horizontal directional drilling in all soil classes for surface-friendly and trenchless pipe laying.",
|
description: "Precise horizontal directional drilling in all soil classes for surface-friendly and trenchless pipe laying.",
|
||||||
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
icon: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z",
|
||||||
url: "/en/standorte/kirchheilingen",
|
url: "/en/drilling-technology",
|
||||||
backgroundImage: "/assets/photos/DSC08653.JPG"
|
backgroundImage: "/assets/photos/DSC08653.JPG"
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export function getStandortById(id: string): StandortData | undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert StandortData to the Location format required by the map
|
// Convert StandortData to the Location format required by the map
|
||||||
export const standorteLocations = standorteData.map((standort) => ({
|
export const standorteLocations = standorteData.map(standort => ({
|
||||||
id: standort.id,
|
id: standort.id,
|
||||||
name: standort.shortName,
|
name: standort.shortName,
|
||||||
type: standort.type,
|
type: standort.type,
|
||||||
|
|||||||
1
runs.json
Normal file
1
runs.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"message":"token is required","url":"https://git.infra.mintel.me/api/swagger"}
|
||||||
@@ -18,12 +18,12 @@ describe('Task 12 TDD - Bohrtechnik and Reference Links', () => {
|
|||||||
const urlDeIndex = bohrtechnikDeBlock.indexOf('url:');
|
const urlDeIndex = bohrtechnikDeBlock.indexOf('url:');
|
||||||
const nextItemDeIndex = bohrtechnikDeBlock.indexOf('title:', 10);
|
const nextItemDeIndex = bohrtechnikDeBlock.indexOf('title:', 10);
|
||||||
|
|
||||||
// Ensure "url:" exists within the E-TIB Bohrtechnik block and points to "/de/standorte/kirchheilingen"
|
// Ensure "url:" exists within the E-TIB Bohrtechnik block and points to "/de/bohrtechnik"
|
||||||
expect(deContent).toMatch(/title:\s*"E-TIB Bohrtechnik GmbH"[\s\S]*?url:\s*["']\/de\/standorte\/kirchheilingen["']/);
|
expect(deContent).toMatch(/title:\s*"E-TIB Bohrtechnik GmbH"[\s\S]*?url:\s*["']\/de\/bohrtechnik["']/);
|
||||||
|
|
||||||
// Assert that E-TIB Bohrtechnik GmbH has url: "/en/standorte/kirchheilingen" in English content
|
// Assert that E-TIB Bohrtechnik GmbH has url: "/en/drilling-technology" in English content
|
||||||
expect(enContent).toContain('title: "E-TIB Bohrtechnik GmbH"');
|
expect(enContent).toContain('title: "E-TIB Bohrtechnik GmbH"');
|
||||||
expect(enContent).toMatch(/title:\s*"E-TIB Bohrtechnik GmbH"[\s\S]*?url:\s*["']\/en\/standorte\/kirchheilingen["']/);
|
expect(enContent).toMatch(/title:\s*"E-TIB Bohrtechnik GmbH"[\s\S]*?url:\s*["']\/en\/drilling-technology["']/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should verify that all reference projects in map-data have no href links', () => {
|
it('should verify that all reference projects in map-data have no href links', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user