Fix - Mail vom 16.02.2025

This commit is contained in:
Damjan Savic 2025-03-11 15:12:04 +01:00
parent 664f5b1b77
commit b8d8c59bce
8 changed files with 322 additions and 176 deletions

124
scripts/print_project.py Normal file
View File

@ -0,0 +1,124 @@
import os
def list_directory_contents(root_dir, ignore_dirs, ignore_files, max_file_size_mb=5):
"""
Gibt rekursiv alle Verzeichnisse, Unterverzeichnisse und Dateien im angegebenen Stammverzeichnis aus
und zeigt den vollständigen Inhalt jeder Datei an.
Args:
root_dir (str): Das Stammverzeichnis, von dem aus begonnen werden soll
ignore_dirs (list): Liste der zu ignorierenden Verzeichnisnamen
ignore_files (list): Liste der zu ignorierenden Dateinamen
max_file_size_mb (int): Maximale Dateigröße zum Lesen in MB
"""
# Überprüfen, ob das Stammverzeichnis existiert
if not os.path.exists(root_dir):
print(f"Fehler: Verzeichnis '{root_dir}' existiert nicht.")
return
# Binäre Dateierweiterungen, deren Inhalt nicht angezeigt werden soll
binary_extensions = {
'.exe', '.dll', '.so', '.dylib', '.bin', '.dat', '.db', '.sqlite', '.sqlite3',
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tif', '.tiff', '.ico', '.webp',
'.mp3', '.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv', '.wav', '.ogg',
'.zip', '.tar', '.gz', '.bz2', '.7z', '.rar', '.pdf', '.doc', '.docx',
'.xls', '.xlsx', '.ppt', '.pptx'
}
# Kodierungen, die beim Lesen von Dateien versucht werden sollen
encodings = ['utf-8', 'latin-1', 'cp1252', 'iso-8859-1']
max_file_size = max_file_size_mb * 1024 * 1024 # MB in Bytes umrechnen
# Durch die Verzeichnisstruktur laufen
for dirpath, dirnames, filenames in os.walk(root_dir):
# Ignorierte Verzeichnisse aus dirnames entfernen, um zu verhindern, dass os.walk sie durchläuft
dirnames[:] = [d for d in dirnames if d not in ignore_dirs]
# Aktuellen Verzeichnispfad ausgeben
rel_path = os.path.relpath(dirpath, root_dir)
if rel_path == '.':
print(f"\n\n{'=' * 80}")
print(f"VERZEICHNIS: {root_dir}")
print(f"{'=' * 80}")
else:
print(f"\n\n{'=' * 80}")
print(f"VERZEICHNIS: {os.path.join(root_dir, rel_path)}")
print(f"{'=' * 80}")
# Unterverzeichnisse ausgeben
if dirnames:
print("\nUnterverzeichnisse:")
for dirname in dirnames:
print(f" - {dirname}")
# Dateien und ihre Inhalte ausgeben
if filenames:
# Zu ignorierende Dateien herausfiltern
filtered_filenames = [f for f in filenames if f not in ignore_files]
print("\nDateien:")
for filename in filtered_filenames:
file_path = os.path.join(dirpath, filename)
print(f"\n{'-' * 50}")
print(f"DATEI: {file_path}")
print(f"{'-' * 50}")
try:
# Dateigröße überprüfen
file_size = os.path.getsize(file_path)
if file_size > max_file_size:
print(f"Datei ist zu groß, um den Inhalt anzuzeigen ({file_size / 1024 / 1024:.2f} MB).")
continue
# Überprüfen, ob es sich um eine Binärdatei anhand der Erweiterung handelt
file_ext = os.path.splitext(filename)[1].lower()
if file_ext and file_ext in binary_extensions:
print(f"Binärdatei erkannt ({file_ext}). Inhalt wird nicht angezeigt.")
continue
# Mehrere Kodierungen ausprobieren
content = None
for encoding in encodings:
try:
with open(file_path, 'r', encoding=encoding) as f:
content = f.read()
break
except UnicodeDecodeError:
continue
if content is not None:
print(content)
else:
print("Datei konnte mit keiner der versuchten Kodierungen gelesen werden.")
except (PermissionError, IsADirectoryError) as e:
print(f"Dateiinhalt konnte nicht gelesen werden: {str(e)}")
except Exception as e:
print(f"Unerwarteter Fehler beim Lesen der Datei: {str(e)}")
def main():
root_dir = r"C:\Users\DamjanSavic\Documents\Techologie.Team"
# Zu ignorierende Verzeichnisse
ignore_dirs = [
"__pycache__",
".idea",
"node_modules",
".git",
"External Libraries",
"Scratches and Consoles"
]
# Zu ignorierende Dateien
ignore_files = [
"package-lock.json"
]
# Maximale Dateigröße für die Anzeige des Inhalts (in MB)
max_file_size_mb = 5
list_directory_contents(root_dir, ignore_dirs, ignore_files, max_file_size_mb)
if __name__ == "__main__":
main()

View File

@ -38,7 +38,7 @@ export default function ExtendedGroup() {
<div className={`transition-all duration-700 ${
isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'
}`}>
<h2 className="font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-[#C25B3F]
<h2 className="font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900
mb-4 sm:mb-6 section-enter section-enter-active">
Die erweiterte Unternehmensgruppe
</h2>
@ -94,6 +94,13 @@ export default function ExtendedGroup() {
Zentrale: Oberhausen
</p>
</div>
{/* Link for more information */}
<a href="#" className="absolute bottom-4 right-4 bg-[#C25B3F] hover:bg-[#A34832] text-white
px-4 py-2 rounded-full shadow-lg transform transition-all duration-300
group-hover:scale-105 font-medium">
Mehr Informationen zur Unternehmensgruppe
</a>
</div>
</div>
</div>

View File

@ -2,150 +2,151 @@ import { Link } from 'react-router-dom';
import { useState, useEffect } from 'react';
type FooterSection = {
title: string;
content: React.ReactNode;
title: string;
content: React.ReactNode;
};
const links = [
{ href: '#technologies', text: 'Unterstütze Technologien' },
{ href: '#group', text: 'Gruppenbeitritt' },
{ href: '#impressum', text: 'Impressum' },
{ href: '#technologies', text: 'Unterstützte Technologien' },
{ href: '#group', text: 'Gruppenbeitritt' },
{ href: 'mailto:kontakt@technologie.team?subject=Gruppenbeitritt%20anfragen', text: 'Gruppenbeitritt anfragen' },
{ href: '#impressum', text: 'Impressum' },
];
export default function Footer() {
const [isVisible, setIsVisible] = useState(false);
const [hoveredLink, setHoveredLink] = useState<string | null>(null);
const [isVisible, setIsVisible] = useState(false);
const [hoveredLink, setHoveredLink] = useState<string | null>(null);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
},
{ threshold: 0.1 }
);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
},
{ threshold: 0.1 }
);
const footer = document.querySelector('footer');
if (footer) {
observer.observe(footer);
}
const footer = document.querySelector('footer');
if (footer) {
observer.observe(footer);
}
return () => {
if (footer) {
observer.unobserve(footer);
}
};
}, []);
return () => {
if (footer) {
observer.unobserve(footer);
}
};
}, []);
const sections: FooterSection[] = [
{
title: 'Links',
content: (
<div className="space-y-3">
{links.map((link) => (
<a
key={link.href}
href={link.href}
className="block transform transition-all duration-300 hover:text-white
const sections: FooterSection[] = [
{
title: 'Links',
content: (
<div className="space-y-3">
{links.map((link) => (
<a
key={link.href}
href={link.href}
className="block transform transition-all duration-300 hover:text-white
hover:translate-x-1 focus:outline-none focus:text-white
group relative"
onMouseEnter={() => setHoveredLink(link.href)}
onMouseLeave={() => setHoveredLink(null)}
>
<span className="relative z-10 inline-block">{link.text}</span>
<span className={`absolute left-0 bottom-0 w-0 h-0.5 bg-[#C25B3F]
onMouseEnter={() => setHoveredLink(link.href)}
onMouseLeave={() => setHoveredLink(null)}
>
<span className="relative z-10 inline-block">{link.text}</span>
<span className={`absolute left-0 bottom-0 w-0 h-0.5 bg-[#C25B3F]
transition-all duration-300 group-hover:w-full
${hoveredLink === link.href ? 'w-full' : 'w-0'}`} />
</a>
))}
</div>
),
},
{
title: 'Ort',
content: (
<address className="not-italic space-y-2">
<p className="transition-colors duration-300 hover:text-white">
Essener Straße 2-24
</p>
<p className="transition-colors duration-300 hover:text-white">
46047 Oberhausen
</p>
</address>
),
},
{
title: 'Mailkontakt',
content: (
<div>
<a href="mailto:kontakt@technologie.team"
className="block mb-4 transition-all duration-300 hover:text-white
</a>
))}
</div>
),
},
{
title: 'Ort',
content: (
<address className="not-italic space-y-2">
<p className="transition-colors duration-300 hover:text-white">
Essener Straße 2-24
</p>
<p className="transition-colors duration-300 hover:text-white">
46047 Oberhausen
</p>
</address>
),
},
{
title: 'Mailkontakt',
content: (
<div>
<a href="mailto:kontakt@technologie.team"
className="block mb-4 transition-all duration-300 hover:text-white
hover:translate-x-1 relative group">
<span>kontakt@technologie.team</span>
<span className="absolute left-0 bottom-0 w-0 h-0.5 bg-[#C25B3F]
<span>kontakt@technologie.team</span>
<span className="absolute left-0 bottom-0 w-0 h-0.5 bg-[#C25B3F]
transition-all duration-300 group-hover:w-full" />
</a>
<a
href="https://linkedin.com"
target="_blank"
rel="noopener noreferrer"
className="inline-block transform transition-all duration-300
</a>
<a
href="https://www.linkedin.com/company/technologie-team"
target="_blank"
rel="noopener noreferrer"
className="inline-block transform transition-all duration-300
hover:scale-110 focus:outline-none focus:scale-110"
aria-label="Besuchen Sie uns auf LinkedIn"
>
<img
src="/images/linkedin.svg"
alt="LinkedIn"
className="h-8 w-8 sm:h-10 sm:w-10"
/>
</a>
</div>
),
},
];
aria-label="Besuchen Sie uns auf LinkedIn"
>
<img
src="/images/linkedin.svg"
alt="LinkedIn"
className="h-8 w-8 sm:h-10 sm:w-10"
/>
</a>
</div>
),
},
];
return (
<footer className="bg-gray-900 text-gray-400 py-12 sm:py-16">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className={`flex flex-col space-y-12 sm:space-y-16
return (
<footer className="bg-gray-900 text-gray-400 py-12 sm:py-16">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className={`flex flex-col space-y-12 sm:space-y-16
transition-all duration-700 transform
${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'}`}>
{/* Logo */}
<Link to="/"
className="block transition-transform duration-300 hover:scale-105
{/* Logo */}
<Link to="/"
className="block transition-transform duration-300 hover:scale-105
focus:outline-none focus:scale-105">
<img
src="/logos/tteamhell.png"
alt="Technologie Team Logo"
className="h-12 sm:h-15"
loading="lazy"
/>
</Link>
<img
src="/logos/tteamhell.png"
alt="Technologie Team Logo"
className="h-12 sm:h-15"
loading="lazy"
/>
</Link>
{/* Navigation Section */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 sm:gap-12">
{sections.map((section, index) => (
<div key={section.title}
className={`transition-all duration-500 delay-${index * 100}
{/* Navigation Section */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 sm:gap-12">
{sections.map((section, index) => (
<div key={section.title}
className={`transition-all duration-500 delay-${index * 100}
${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>
<h3 className="font-outfit text-white font-semibold mb-4 text-base sm:text-lg
<h3 className="font-outfit text-white font-semibold mb-4 text-base sm:text-lg
transform transition-all duration-300 hover:text-[#C25B3F]">
{section.title}
</h3>
{section.content}
</div>
))}
</div>
</div>
{section.title}
</h3>
{section.content}
</div>
))}
</div>
</div>
<div className="border-t border-gray-800 mt-12 sm:mt-16 pt-6 sm:pt-8
<div className="border-t border-gray-800 mt-12 sm:mt-16 pt-6 sm:pt-8
text-center text-sm text-gray-500">
<p className="transition-colors duration-300 hover:text-gray-400">
Copyright © {new Date().getFullYear()} TechnologieTeam
</p>
</div>
</div>
</footer>
);
<p className="transition-colors duration-300 hover:text-gray-400">
Copyright © {new Date().getFullYear()} TechnologieTeam
</p>
</div>
</div>
</footer>
);
}

View File

@ -4,37 +4,42 @@ const companies = [
{
name: 'b.o.c. IT-SECURITY',
logo: '/images/bocitsec.png',
link: '#'
},
{
name: 'GIS',
logo: '/images/gis.png',
link: '#'
link: 'https://www.boc.de'
},
{
name: 'RITTER TECHNOLOGIE',
logo: '/images/rittec.png',
link: '#'
link: 'https://www.rittec.de'
},
{
name: 'NETRIX',
logo: '/images/netrix.png',
link: '#'
name: 'GIS',
logo: '/images/gis.png',
link: 'https://www.gis-net.de'
},
{
name: '2G-KONZEPT',
logo: '/images/2gdigital.png',
link: 'https://www.2g-konzept.de'
},
{
name: 'RITTER digital',
logo: '/images/ritterdigital.png',
link: '#'
link: 'https://www.ritterdigital.de'
},
{
name: 'LINQ-IT',
logo: '/images/linqit.png',
link: '#'
link: 'https://www.linq-it.de'
},
{
name: '2G.digital',
logo: '/images/2gdigital.png',
link: '#'
name: 'NETRIX IT',
logo: '/images/netrix.png',
link: 'https://www.netrix-it.de'
},
{
name: 'DEMOS COMPUTER',
logo: '/images/2gdigital.png', // Placeholder, should be replaced with the actual image
link: 'https://www.demoscomputer.de'
}
];
@ -67,7 +72,7 @@ export default function GroupCompanies() {
return (
<section id="companies" className="py-12 sm:py-16 lg:py-24 bg-white overflow-hidden">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 className={`font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-[#C25B3F]
<h2 className={`font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900
mb-8 sm:mb-12 lg:mb-16 transition-all duration-700
${isVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'}`}>
Unsere IT-/Technologie Gruppenunternehmen
@ -79,6 +84,8 @@ export default function GroupCompanies() {
<a
key={index}
href={company.link}
target="_blank"
rel="noopener noreferrer"
className={`
relative bg-white rounded-xl p-4 sm:p-6 lg:p-8
transition-all duration-500 ease-out
@ -98,7 +105,7 @@ export default function GroupCompanies() {
<img
src={company.logo}
alt={company.name}
className="w-full max-w-[85%] max-h-[65%] object-contain
className="w-full max-w-[95%] max-h-[80%] object-contain
transition-transform duration-500
group-hover:scale-110 will-change-transform"
loading="lazy"

View File

@ -1,12 +1,38 @@
import { useState, useEffect } from 'react';
import { Users2, Eye, BarChart3, Settings2, DollarSign, Search, Link2, TrendingUp, GraduationCap, Monitor } from 'lucide-react';
// Geänderte Reihenfolge der Items
const valueItems = [
{
icon: TrendingUp,
title: 'Personal Perspektive',
description: 'Individuelle Fördermöglichkeiten in einem großen Ökosystem, mit agilen Entscheidungswegen.'
},
{
icon: DollarSign,
title: 'Finanzielle Hebel',
description: 'Finanzielle Stärken bündeln und zum Wohle der Gesamtlösung einsetzen.'
},
{
icon: Settings2,
title: 'Operative Hebel',
description: 'Gemeinsame Stärken nutzen und durchgängige Experten-Lösungen schaffen.'
},
{
icon: Users2,
title: 'Management Team',
description: 'Ein erfahrenes, kompetentes Managementteam sorgt für strategische Unterstützung.'
},
{
icon: Search,
title: 'Recruiting',
description: 'Unterstützung durch Personal-Experten'
},
{
icon: GraduationCap,
title: 'Ausbildung',
description: 'Kontinuierliche Schulung und Weiterentwicklung der Mitarbeiterkompetenzen.'
},
{
icon: Eye,
title: 'Fokus auf Transparenz',
@ -17,36 +43,11 @@ const valueItems = [
title: 'Schlankes Reporting',
description: 'Ein effektives Berichtssystem ermöglicht es sich auf seine Aufgaben zu konzentrieren und agil zu reagieren.'
},
{
icon: Settings2,
title: 'Operative Hebel',
description: 'Gemeinsame Stärken nutzen und durchgängige Experten-Lösungen schaffen.'
},
{
icon: DollarSign,
title: 'Finanzielle Hebel',
description: 'Finanzielle Stärken bündeln und zum Wohle der Gesamtlösung einsetzen.'
},
{
icon: Search,
title: 'Recruiting',
description: 'Unterstützung durch Personal-Experten'
},
{
icon: Link2,
title: 'Gruppenzugehörigkeit',
description: 'Mehr aus den einzelnen Möglichkeiten rausholen und gemeinsam bessere Lösungen und Entwicklungen schaffen.'
},
{
icon: TrendingUp,
title: 'Personal Perspektive',
description: 'Individuelle Fördermöglichkeiten in einem großen Ökosystem, mit agilen Entscheidungswegen.'
},
{
icon: GraduationCap,
title: 'Ausbildung',
description: 'Kontinuierliche Schulung und Weiterentwicklung der Mitarbeiterkompetenzen.'
},
{
icon: Monitor,
title: 'Digitalisierung',
@ -82,14 +83,14 @@ export default function GroupValue() {
return (
<section id="group-value" className="bg-[#C25B3F] py-12 sm:py-16 lg:py-24 overflow-hidden">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className={`mb-8 sm:mb-12 lg:mb-16 max-w-3xl mx-auto text-center
<div className={`mb-8 sm:mb-12 lg:mb-16 mx-auto text-center
${isVisible ? 'animate-fade-in' : 'opacity-0'}`}>
<h2 className="font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-white mb-4 sm:mb-8
section-enter section-enter-active">
Unser Gruppenmehrwert
</h2>
<p className="font-outfit text-base sm:text-lg text-white/90 leading-relaxed
section-enter section-enter-active delay-100">
section-enter section-enter-active delay-100 max-w-full">
IT-/Technologieunternehmen zeichnen sich durch ihre Kompetenz und die exzellente Umsetzung von
Kundenanforderungen aus. Unser Ziel ist es, diese Qualitäten zu erhalten, die Unternehmenskultur
zu wahren und Raum für weiteres Wachstum und Entwicklung zu schaffen.

View File

@ -1,4 +1,3 @@
import { Link } from 'react-router-dom';
import { useState, useEffect } from 'react';
export default function Hero() {
@ -38,14 +37,14 @@ export default function Hero() {
UNTERNEHMENSGRUPPE
</span>
</h1>
<p className="font-outfit text-lg xs:text-xl sm:text-2xl md:text-3xl text-gray-200
mb-6 sm:mb-8 md:mb-12 tracking-normal leading-relaxed
<p className="font-outfit text-xl xs:text-2xl sm:text-3xl md:text-4xl text-gray-200
mb-6 sm:mb-8 md:mb-12 tracking-normal leading-relaxed font-bold
section-enter section-enter-active delay-200">
Gemeinsam Stärker | Für Unsere Kunden | Durchgängig In Ihren Prozessen
</p>
<div className="section-enter section-enter-active delay-300">
<Link
to="/mehr"
<div className="section-enter section-enter-active delay-300 flex flex-col sm:flex-row sm:items-center gap-4">
<a
href="mailto:kontakt@technologie.team?subject=Gruppenbeitritt%20anfragen"
className="group relative font-outfit inline-flex items-center justify-center
overflow-hidden rounded bg-[#C25B3F] px-6 sm:px-8 py-3 sm:py-4
text-base sm:text-lg md:text-xl font-medium uppercase tracking-wide
@ -54,7 +53,7 @@ export default function Hero() {
hover:bg-[#A34832]"
>
<span className="flex items-center gap-2">
Mehr erfahren
Gruppenbeitritt anfragen
<svg
className="w-4 h-4"
fill="none"
@ -69,7 +68,14 @@ export default function Hero() {
/>
</svg>
</span>
</Link>
</a>
<a
href="mailto:kontakt@technologie.team"
className="font-outfit text-white text-base sm:text-lg md:text-xl
hover:text-[#C25B3F] transition-colors duration-300"
>
kontakt@technologie.team
</a>
</div>
</div>
</div>

View File

@ -59,9 +59,9 @@ export default function Mission() {
{/* Mission Text Content */}
<div className="lg:col-span-8">
<h2 className="font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-[#C25B3F]
<h2 className="font-outfit text-3xl sm:text-4xl lg:text-5xl font-bold text-gray-900
mb-8 sm:mb-12 section-enter section-enter-active">
Unser Leitbild
Unser Leitbild - Expertise in der Nachfolge
</h2>
<div className="space-y-6 sm:space-y-8">

View File

@ -70,7 +70,7 @@ export default function Technologies() {
{/* Header */}
<div className="flex items-center justify-between mb-6">
<h2 className="font-outfit text-2xl sm:text-3xl font-bold text-[#C25B3F]">
Unterstützte Technologien
Unterstützte Technologien in der gesamten Prozesskette
</h2>
{!isMobile && (
<div className="flex gap-3">