Compare commits
10 Commits
v2.2.13-rc
...
staging
| Author | SHA1 | Date | |
|---|---|---|---|
| 0191fdb770 | |||
| afaa5e038c | |||
| e0d6ea0d6c | |||
| 34839ad5a5 | |||
| a8d6a45aad | |||
| 6de8ad8516 | |||
| 023fef5343 | |||
| 7181dafca2 | |||
| 8b6d2da821 | |||
| 17736860d6 |
@@ -186,8 +186,6 @@ export default async function Layout(props: {
|
||||
data-scroll-behavior="smooth"
|
||||
>
|
||||
<head>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||
<link rel="preconnect" href="https://img.infra.mintel.me" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
<link rel="apple-touch-icon" href="/apple-icon.png" sizes="180x180" />
|
||||
|
||||
@@ -6,21 +6,22 @@ import { MDXRemote } from 'next-mdx-remote/rsc';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
// Import components used in MDX
|
||||
import { HeroVideo as HomeHero } from '@/components/blocks/HeroVideo';
|
||||
import { SubCompanyTiles as HomeSubCompanyTiles } from '@/components/blocks/SubCompanyTiles';
|
||||
import { CompetenceBentoGrid as HomeCompetenceBentoGrid } from '@/components/blocks/CompetenceBentoGrid';
|
||||
import { ReferencesSlider as HomeReferencesSlider } from '@/components/blocks/ReferencesSlider';
|
||||
import { FaqBlock } from '@/components/blocks/FaqBlock';
|
||||
import { CertificatesBlock } from '@/components/blocks/CertificatesBlock';
|
||||
import { HeroSection } from '@/components/blocks/HeroSection';
|
||||
import nextDynamic from 'next/dynamic';
|
||||
|
||||
const HomeHero = nextDynamic(() => import('@/components/blocks/HeroVideo').then(mod => mod.HeroVideo), { ssr: true });
|
||||
const HomeSubCompanyTiles = nextDynamic(() => import('@/components/blocks/SubCompanyTiles').then(mod => mod.SubCompanyTiles));
|
||||
const HomeCompetenceBentoGrid = nextDynamic(() => import('@/components/blocks/CompetenceBentoGrid').then(mod => mod.CompetenceBentoGrid));
|
||||
const HomeReferencesSlider = nextDynamic(() => import('@/components/blocks/ReferencesSlider').then(mod => mod.ReferencesSlider));
|
||||
const FaqBlock = nextDynamic(() => import('@/components/blocks/FaqBlock').then(mod => mod.FaqBlock));
|
||||
const CertificatesBlock = nextDynamic(() => import('@/components/blocks/CertificatesBlock').then(mod => mod.CertificatesBlock));
|
||||
const HeroSection = nextDynamic(() => import('@/components/blocks/HeroSection').then(mod => mod.HeroSection), { ssr: true });
|
||||
import JsonLd from '@/components/JsonLd';
|
||||
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Heading } from '@/components/ui/Heading';
|
||||
import { AnimatedCounter } from '@/components/ui';
|
||||
import { InteractiveGermanyMap } from '@/components/blocks/InteractiveGermanyMap';
|
||||
import { ScaleOfImpact } from '@/components/blocks/ScaleOfImpact';
|
||||
const AnimatedCounter = nextDynamic(() => import('@/components/ui').then(mod => mod.AnimatedCounter));
|
||||
const InteractiveGermanyMap = nextDynamic(() => import('@/components/blocks/InteractiveGermanyMap').then(mod => mod.InteractiveGermanyMap));
|
||||
const ScaleOfImpact = nextDynamic(() => import('@/components/blocks/ScaleOfImpact').then(mod => mod.ScaleOfImpact));
|
||||
import { getAllReferences } from '@/lib/references';
|
||||
|
||||
const mdxComponents = (references: any[]) => ({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { cn } from '@/components/ui';
|
||||
|
||||
interface RevealProps {
|
||||
@@ -10,40 +10,12 @@ interface RevealProps {
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
export default function Reveal({ children, className, threshold = 0.1, delay = 0 }: RevealProps) {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true);
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
},
|
||||
{ threshold }
|
||||
);
|
||||
|
||||
const currentRef = ref.current;
|
||||
if (currentRef) {
|
||||
observer.observe(currentRef);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (currentRef) {
|
||||
observer.unobserve(currentRef);
|
||||
}
|
||||
};
|
||||
}, [threshold]);
|
||||
|
||||
export default function Reveal({ children, className }: RevealProps) {
|
||||
// Reveal animation disabled due to flickering issues on mobile/hydration
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('reveal-on-scroll', isVisible && 'is-visible', className)}
|
||||
style={{ transitionDelay: `${delay}ms` }}
|
||||
>
|
||||
<div className={cn(className)}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,10 +86,6 @@ export function CompetenceBentoGrid(props: CompetenceBentoGridProps) {
|
||||
<h2 className="text-primary font-bold tracking-wider uppercase text-sm mb-3">{badge}</h2>
|
||||
<h3 className="font-heading text-3xl md:text-5xl font-extrabold text-neutral-dark mb-4">{title}</h3>
|
||||
</div>
|
||||
<Button href={ctaHref} variant="ghost" className="bg-primary/5 hover:bg-primary/10 mx-4 md:mx-0 whitespace-nowrap">
|
||||
{ctaLabel}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="w-5 h-5 ml-2 transform group-hover:translate-x-1 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 auto-rows-[220px] px-4 md:px-0">
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import Image from 'next/image';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
@@ -81,11 +80,9 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
<div className="absolute top-0 left-0 w-full h-48 bg-gradient-to-b from-black/70 to-transparent z-[3] pointer-events-none" />
|
||||
|
||||
<div className="container relative z-[4] text-center px-4">
|
||||
<motion.div
|
||||
<div
|
||||
key={`hero-content-${pathname}`}
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1.2, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="animate-in fade-in slide-in-from-bottom-10 duration-1000 ease-out fill-mode-both"
|
||||
>
|
||||
<h1
|
||||
className="font-heading font-bold text-3xl sm:text-4xl md:text-6xl lg:text-8xl text-white mb-6 uppercase tracking-tight drop-shadow-lg"
|
||||
@@ -114,7 +111,7 @@ export function HeroVideo(props: HeroVideoProps) {
|
||||
{secondaryCtaLabel}
|
||||
</Button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -138,8 +138,54 @@ export function Header({ navLinks }: HeaderProps) {
|
||||
<div className="flex items-center gap-2 md:gap-4 lg:gap-6">
|
||||
<div className={`hidden md:block h-5 w-px transition-colors duration-300 ${isSolidMode ? 'bg-neutral-200' : 'bg-white/20'}`} />
|
||||
|
||||
{/* Language Switcher visible on all devices */}
|
||||
<div className="z-50 relative flex items-center">
|
||||
{/* Quick Actions (Mobile Only) */}
|
||||
<div className="md:hidden flex items-center gap-2">
|
||||
<a
|
||||
href="tel:+492572946760"
|
||||
className={`relative flex items-center justify-center w-9 h-9 rounded-full transition-all duration-300 ${
|
||||
isSolidMode
|
||||
? 'bg-primary text-white shadow-md shadow-primary/20 hover:-translate-y-0.5'
|
||||
: 'bg-white text-primary shadow-md hover:-translate-y-0.5'
|
||||
}`}
|
||||
aria-label="Anrufen"
|
||||
>
|
||||
<svg className="w-[16px] h-[16px]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="mailto:info@e-tib.com"
|
||||
className={`relative flex items-center justify-center w-9 h-9 rounded-full transition-all duration-300 ${
|
||||
isSolidMode
|
||||
? 'bg-neutral-100 text-neutral-600 hover:text-primary hover:bg-neutral-200'
|
||||
: 'bg-white/10 text-white backdrop-blur-md border border-white/20 hover:bg-white/20'
|
||||
}`}
|
||||
aria-label="E-Mail"
|
||||
>
|
||||
<svg className="w-[16px] h-[16px]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
href="https://maps.google.com/?q=E-TIB+GmbH,+Greven"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={`relative flex items-center justify-center w-9 h-9 rounded-full transition-all duration-300 ${
|
||||
isSolidMode
|
||||
? 'bg-neutral-100 text-neutral-600 hover:text-primary hover:bg-neutral-200'
|
||||
: 'bg-white/10 text-white backdrop-blur-md border border-white/20 hover:bg-white/20'
|
||||
}`}
|
||||
aria-label="Route"
|
||||
>
|
||||
<svg className="w-[16px] h-[16px]" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Language Switcher visible on desktop only */}
|
||||
<div className="z-50 relative hidden md:flex items-center">
|
||||
<LanguageSwitcher isSolidMode={isSolidMode} />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -25,11 +25,14 @@ export function MobileBottomNav({ navLinks, currentLocale }: MobileBottomNavProp
|
||||
React.useEffect(() => {
|
||||
if (isFlyoutOpen) {
|
||||
document.body.style.overflow = 'hidden';
|
||||
document.documentElement.style.overflow = 'hidden';
|
||||
} else {
|
||||
document.body.style.overflow = '';
|
||||
document.documentElement.style.overflow = '';
|
||||
}
|
||||
return () => {
|
||||
document.body.style.overflow = '';
|
||||
document.documentElement.style.overflow = '';
|
||||
};
|
||||
}, [isFlyoutOpen]);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ featuredImage: "/assets/photos/DJI_0037.JPG"
|
||||
|
||||
- 500 m Kabelgraben ausheben und verfüllen
|
||||
- 4.500 m Einpflügen von 3 x PE-Schutzrohr d 160
|
||||
- 3.200 m Horizontalspülbohrung d 160
|
||||
- 12.000 m Horizontalspülbohrung d 160
|
||||
- 8.500 m Verlegung HS-Kabel 1.000 mm² 64/110 kV
|
||||
- 11 Satz Verbindungsmuffen 1.000 mm² 64/110 kV
|
||||
- 2 Satz Freiluftendverschlüsse 1.000 mm² 64/110 kV
|
||||
|
||||
@@ -42,7 +42,7 @@ layout: "fullBleed"
|
||||
{
|
||||
id: "martin-polan",
|
||||
name: "Martin Polan",
|
||||
position: "Bauleiter",
|
||||
position: "Bauleitung",
|
||||
email: "m.polan@e-tib.com",
|
||||
phone: "+49 171 3868167",
|
||||
image: "/assets/photos/team/martin.jpg"
|
||||
|
||||
@@ -9,7 +9,7 @@ featuredImage: "/assets/photos/DJI_0037.JPG"
|
||||
|
||||
- Excavation and backfilling of 500 m cable trench
|
||||
- 4,500 m plowing of 3 x PE protective pipe d 160
|
||||
- 3,200 m HDD directional drilling d 160
|
||||
- 12,000 m HDD directional drilling d 160
|
||||
- 8,500 m laying of HV cable 1,000 mm² 64/110 kV
|
||||
- 11 sets of connection joints 1,000 mm² 64/110 kV
|
||||
- 2 sets of outdoor terminations 1,000 mm² 64/110 kV
|
||||
|
||||
@@ -42,7 +42,7 @@ layout: "fullBleed"
|
||||
{
|
||||
id: "martin-polan",
|
||||
name: "Martin Polan",
|
||||
position: "Site Manager",
|
||||
position: "Site Management",
|
||||
email: "m.polan@e-tib.com",
|
||||
phone: "+49 171 3868167",
|
||||
image: "/assets/photos/team/martin.jpg"
|
||||
|
||||
@@ -189,62 +189,6 @@ export const minorLocations: Location[] = [
|
||||
y: 83.33,
|
||||
description: 'fiber',
|
||||
},
|
||||
{
|
||||
id: 'hdd-29436-meter-29436',
|
||||
name: 'HDD 29436 Meter',
|
||||
type: 'minor_node',
|
||||
x: 46.89,
|
||||
y: 41.34,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'hdd-28680-meter-28680',
|
||||
name: 'HDD 28680 Meter',
|
||||
type: 'minor_node',
|
||||
x: 44.84,
|
||||
y: 43.61,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'hdd-44655-meter-44655',
|
||||
name: 'HDD 44655 Meter',
|
||||
type: 'minor_node',
|
||||
x: 49.36,
|
||||
y: 48.57,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'kabelverlegung-76727-meter-76727',
|
||||
name: 'Kabelverlegung 76727 Meter',
|
||||
type: 'minor_node',
|
||||
x: 45.57,
|
||||
y: 49.95,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'offener-tiefbau-21288-meter-21288',
|
||||
name: 'Offener Tiefbau 21288 Meter',
|
||||
type: 'minor_node',
|
||||
x: 40.15,
|
||||
y: 49.41,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'offener-tiefbau-30773-meter-30773',
|
||||
name: 'Offener Tiefbau 30773 Meter',
|
||||
type: 'minor_node',
|
||||
x: 41.74,
|
||||
y: 43.78,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'offener-tiefbau-34815-meter-34815',
|
||||
name: 'Offener Tiefbau 34815 Meter',
|
||||
type: 'minor_node',
|
||||
x: 43.91,
|
||||
y: 42.14,
|
||||
description: 'power',
|
||||
},
|
||||
{
|
||||
id: 'pv-anlage-01909-grosshartau-01909',
|
||||
name: 'PV-Anlage, 01909 Großhartau',
|
||||
|
||||
@@ -35,7 +35,7 @@ export const standorteData: StandortData[] = [
|
||||
{
|
||||
id: 'guben',
|
||||
name: 'E-TIB GmbH',
|
||||
shortName: 'Guben (Hauptsitz)',
|
||||
shortName: 'Standort Brandenburg (Hauptsitz)',
|
||||
type: 'hq',
|
||||
description: {
|
||||
de: 'Unser Hauptsitz in Guben bildet das strategische und operative Zentrum der E-TIB Gruppe. Von hier aus steuern wir bundesweit Großprojekte im Kabelleitungsnetzbau und koordinieren unseren hochmodernen Maschinenpark.',
|
||||
@@ -67,7 +67,7 @@ export const standorteData: StandortData[] = [
|
||||
'Central project management'
|
||||
]
|
||||
},
|
||||
image: '/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-100.jpg',
|
||||
image: '/assets/photos/DSC02114.jpg',
|
||||
gallery: [
|
||||
'/assets/photos/DSC02114.jpg',
|
||||
'/assets/photos/Etib_E-tib_Tiefbau_Guben_Netzanbindung_Energie-45.jpg'
|
||||
@@ -117,7 +117,7 @@ export const standorteData: StandortData[] = [
|
||||
{
|
||||
id: 'buelstedt',
|
||||
name: 'E-TIB Ingenieurgesellschaft mbH',
|
||||
shortName: 'Bülstedt (Ingenieurgesellschaft)',
|
||||
shortName: 'Standort Niedersachsen',
|
||||
type: 'branch',
|
||||
description: {
|
||||
de: 'Unsere Ingenieurgesellschaft in Bülstedt ist spezialisiert auf die hochpräzise Planung, Vermessung und Projektierung von Energie- und Telekommunikationsnetzen. Hier verschmelzen technische Expertise und modernes Datenmanagement.',
|
||||
|
||||
@@ -15,6 +15,10 @@ const nextConfig = {
|
||||
pagesBufferLength: 2,
|
||||
},
|
||||
experimental: {
|
||||
staleTimes: {
|
||||
dynamic: 0,
|
||||
static: 30,
|
||||
},
|
||||
optimizePackageImports: [
|
||||
'lucide-react',
|
||||
'framer-motion',
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.2.13-rc.60",
|
||||
"version": "2.2.14",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
Reference in New Issue
Block a user